Commit 25305363 authored by Gauthier Quesnel's avatar Gauthier Quesnel
Browse files

next6

parent d58bd7ff
Pipeline #2285 failed with stage
in 38 seconds
......@@ -44,6 +44,24 @@ get_key(IDs id) noexcept
return id & 0xffff0000;
}
template<typename T>
constexpr unsigned
get_invalid_id() noexcept;
template<>
constexpr unsigned
get_invalid_id<ID>() noexcept
{
return 0u;
}
template<>
constexpr unsigned
get_invalid_id<IDs>() noexcept
{
return 0u;
}
template<typename T>
constexpr unsigned
get_max_key() noexcept;
......@@ -84,7 +102,7 @@ template<typename Identifier>
constexpr bool
valid(Identifier id) noexcept
{
return get_key(id) != 0;
return get_key(id) > 0;
}
/**
......@@ -376,7 +394,8 @@ data_array<T, Identifier>::try_to_get(Identifier id)
{
if (get_key(id)) {
auto index = get_index(id);
return &items[index].item;
if (items[index].id == id)
return &items[index].item;
}
return nullptr;
......
// Copyright (c) 2019 INRA Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ORG_VLEPROJECT_BITS_LINKS_HPP
#define ORG_VLEPROJECT_BITS_LINKS_HPP
#include <bits/assert.hpp>
#include <vector>
namespace bits {
template<typename Identifier, typename Allocator = std::allocator<Identifier>>
class links
/**
* @code
* // ID reference an another ID data.
* bits::linker <ID, ID> map_simple(size_t{200});
* map_simple[0u] = 123u;
* map_simple[1u] = 123u;
* map_simple.destroy(0u);
*
* // ID reference an ID4 data.
* bits::linker <ID, ID4> map(size_t{1024});
* map[123u] = { 1u, 2u, 3u, 4u };
* @endcode
*/
template<typename Identifier,
typename Referenced,
typename Allocator = std::allocator<Identifier>>
class linker
{
public:
using identifier_type = Identifier;
using referenced_type = Referenced;
private:
std::vector<value_type, Allocator> items;
......@@ -16,36 +42,36 @@ public:
using reference = container_type::reference;
public:
links(const size_t size, const Allocator& allocator)
: items(size, -1, allocator)
linker(const size_t size, const Allocator& allocator)
: items(size, get_invalid_id<Referenced>(), allocator)
{
bits_expects(size > 0);
}
Identifier operator[](const Identifier ID) const noexcept
referenced_type operator[](const identifier_type id) const noexcept
{
bits_expects(bits::valid(ID));
bits_expects(bits::valid(id));
return items[bits::get_index(ID)];
return items[bits::get_index(id)];
}
Identifier& operator[](const Identifier ID) noexcept
referenced_type& operator[](const identifier_type id) noexcept
{
bits_assert(bits::valid(ID));
bits_expects(bits::valid(id));
return items[bits::get_index(ID)];
return items[bits::get_index(id)];
}
void destroy(const Identifier ID) noexcept
void destroy(const identifier_type id) noexcept
{
bits_assert(bits::valid(ID));
bits_expects(bits::valid(id));
items[bits::get_index(ID)] = { -1 };
items[bits::get_index(id)] = get_invalid_id<referenced_type>();
}
};
template<typename List, typename DataArray, typename Identifier>
class multi_links_iterator
template<typename Linker, typename DataArray, typename Identifier>
class multi_linker_iterator
{
public:
using iterator_category = std::forward_iterator_tag;
......@@ -55,25 +81,25 @@ public:
using reference = Identifier&;
private:
List* list = nullptr;
Linker* list = nullptr;
DataArray* dataarray = nullptr;
Identifier elem = { -1 };
public:
multi_links_iterator() noexcept = default;
multi_links_iterator(const multi_links_iterator&) noexcept = default;
multi_links_iterator& operator=(const multi_links_iterator&) noexcept =
multi_linker_iterator() noexcept = default;
multi_linker_iterator(const multi_linker_iterator&) noexcept = default;
multi_linker_iterator& operator=(const multi_linker_iterator&) noexcept =
default;
multi_links_iterator(List* list_,
DataArray* dataarray_,
Identifier elem_) noexcept
multi_linker_iterator(Linker* list_,
DataArray* dataarray_,
Identifier elem_) noexcept
: list(list_)
, dataarray(dataarray_)
, elem(elem_)
{}
multi_links_iterator(multi_links_iterator&& other) noexcept
multi_linker_iterator(multi_linker_iterator&& other) noexcept
: list(other.list)
, dataarray_(other.dataarray)
, elem(other.elem)
......@@ -83,7 +109,7 @@ public:
other.elem = -1;
}
multi_links_iterator& operator=(multi_links_iterator&& other) noexcept
multi_linker_iterator& operator=(multi_linker_iterator&& other) noexcept
{
if (this != &other) {
list = other.list;
......@@ -164,29 +190,44 @@ public:
}
};
template <typename Identifier>
struct multi_links_node
template<typename Identifier>
struct multi_linker_node
{
Identifier id = { -1 };
int next = { -1 };
};
template<typename Identifier,
typename IdentifierAllocator = std::allocator<Identifier>,
typename NodeAllocator = std::allocator<mult_links_node>>
class multi_links
typename Referenced,
typename IdentifierAllocator = std::allocator<Identifier>,
typename NodeAllocator = std::allocator<mult_linker_node>>
class multi_linker
{
public:
using identifier_type = Identifier;
using referenced_type = Referenced;
private:
std::vector<int, IdentifierAllocator> map; // Map ID to head in the linked list.
std::vector<mult_links_node, NodeAllocator> list; // The linked list.
/// Map ID to head in the linked list.
std::vector<int, IdentifierAllocator> map;
/// The (flat) linked list in contiguous container.
std::vector<mult_linker_node, NodeAllocator> list;
/// The free linked list.
int free_head = -1;
public:
multi_links(int size, const Allocator& allocator) noexcept
: map(size, -1, allocator)
multi_linker(const size_t size, const Allocator& allocator) noexcept
: map(size, get_invalid<referenced_type>(), allocator)
, list(size, allocator)
, free_head(-1)
{
bits_expects(size > 0);
// The linked list starts at an empty state and grow automatically
// except if at least one element is deleted before.
list.clear();
}
......@@ -242,3 +283,5 @@ public:
};
} // namespace bits
#endif // ORG_VLEPROJECT_BITS_LINKS_HPP
......@@ -22,7 +22,7 @@
#include <bits/allocator.hpp>
#include <bits/data-array.hpp>
#include <bits/list.hpp>
#include <bits/linker.hpp>
#include <bits/unit-test.hpp>
......@@ -34,8 +34,7 @@
namespace vle {
using ID = bits::ID;
// using ForwardListID = bits::flat_forward_list<ID>::accessor_type;
using ListID = std::list<ID, bits::block_memory_allocator<ID, 32768>>;
using ID4 = bits::ID[4];
struct Dynamics
{
......@@ -79,21 +78,23 @@ enum class value_type
struct Value
{
ID id = -1;
value_type type = value_type::none;
};
struct NamedValue
{
std::string name;
ID id = -1;
value_type type = value_type::none;
};
struct Condition
{
std::string name;
ListID named_values_list;
};
struct Port
{
std::string name;
};
struct Connection
......@@ -131,65 +132,6 @@ struct Class
std::string name;
};
template<typename Identifier, typename Allocator>
struct links
{
using value_type = Identifier;
std::vector<value_type> data;
links() = default;
const value_type operator[](value_type id) const noexcept
{
assert(bits::is_valid(id));
return data[bits::get_index(id)];
}
value_type& operator[](value_type id) noexcept
{
assert(bits::is_valid(id));
return data[bits::get_index(id)];
}
void destroy(value_type id) noexcept
{
assert(bits::is_valid(id));
data[bits::get_index(id)] = { 0 };
}
};
template<typename Identifier, typename Allocator>
struct multi_links
{
using value_type = Identifier;
std::vector<std::size_t> linker;
flat_list<value_type> data;
void emplace(value_type id, value_type link) noexcept
{
auto index = bits::get_index(id);
if (linker[index] < 0) {
linker[index] = data.alloc();
}
data[linker[index]].emplace(link);
}
void destroy(value_type id) noexcept
{
auto index = bits::get_index(id);
if (index[index] > 0) {
data[linker].clear();
index[index] = -1;
}
}
};
struct Vpz
{
std::string name;
......@@ -212,13 +154,15 @@ struct Vpz
bits::data_array<double, ID> real64;
bits::data_array<std::string, ID> string;
bits::links<ID> value_type;
bits::links<ID> namedvalue_type;
bits::links<ID> model_dynamics;
bits::links<ID> model_parent;
bits::multi_links<ID> model_connections;
bits::multi_links<ID> model_input_ports;
bits::multi_links<ID> model_output_ports;
bits::multi_links<ID4> model_connections;
bits::multi_links<ID> model_conditions;
bits::multi_links<ID> model_children;
bits::multi_links<ID> condition_port;
void init(int object_capacity, int list_capacity)
{
......@@ -434,7 +378,7 @@ struct Vpz
} // vle
int
main(int /* argc */, char* /* argv */ [])
main(int /* argc */, char* /* argv */[])
{
vle::Vpz vpz;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment