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 ...@@ -44,6 +44,24 @@ get_key(IDs id) noexcept
return id & 0xffff0000; 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> template<typename T>
constexpr unsigned constexpr unsigned
get_max_key() noexcept; get_max_key() noexcept;
...@@ -84,7 +102,7 @@ template<typename Identifier> ...@@ -84,7 +102,7 @@ template<typename Identifier>
constexpr bool constexpr bool
valid(Identifier id) noexcept 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) ...@@ -376,7 +394,8 @@ data_array<T, Identifier>::try_to_get(Identifier id)
{ {
if (get_key(id)) { if (get_key(id)) {
auto index = get_index(id); auto index = get_index(id);
return &items[index].item; if (items[index].id == id)
return &items[index].item;
} }
return nullptr; 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 <bits/assert.hpp>
#include <vector> #include <vector>
namespace bits { 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: private:
std::vector<value_type, Allocator> items; std::vector<value_type, Allocator> items;
...@@ -16,36 +42,36 @@ public: ...@@ -16,36 +42,36 @@ public:
using reference = container_type::reference; using reference = container_type::reference;
public: public:
links(const size_t size, const Allocator& allocator) linker(const size_t size, const Allocator& allocator)
: items(size, -1, allocator) : items(size, get_invalid_id<Referenced>(), allocator)
{ {
bits_expects(size > 0); 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> template<typename Linker, typename DataArray, typename Identifier>
class multi_links_iterator class multi_linker_iterator
{ {
public: public:
using iterator_category = std::forward_iterator_tag; using iterator_category = std::forward_iterator_tag;
...@@ -55,25 +81,25 @@ public: ...@@ -55,25 +81,25 @@ public:
using reference = Identifier&; using reference = Identifier&;
private: private:
List* list = nullptr; Linker* list = nullptr;
DataArray* dataarray = nullptr; DataArray* dataarray = nullptr;
Identifier elem = { -1 }; Identifier elem = { -1 };
public: public:
multi_links_iterator() noexcept = default; multi_linker_iterator() noexcept = default;
multi_links_iterator(const multi_links_iterator&) noexcept = default; multi_linker_iterator(const multi_linker_iterator&) noexcept = default;
multi_links_iterator& operator=(const multi_links_iterator&) noexcept = multi_linker_iterator& operator=(const multi_linker_iterator&) noexcept =
default; default;
multi_links_iterator(List* list_, multi_linker_iterator(Linker* list_,
DataArray* dataarray_, DataArray* dataarray_,
Identifier elem_) noexcept Identifier elem_) noexcept
: list(list_) : list(list_)
, dataarray(dataarray_) , dataarray(dataarray_)
, elem(elem_) , elem(elem_)
{} {}
multi_links_iterator(multi_links_iterator&& other) noexcept multi_linker_iterator(multi_linker_iterator&& other) noexcept
: list(other.list) : list(other.list)
, dataarray_(other.dataarray) , dataarray_(other.dataarray)
, elem(other.elem) , elem(other.elem)
...@@ -83,7 +109,7 @@ public: ...@@ -83,7 +109,7 @@ public:
other.elem = -1; other.elem = -1;
} }
multi_links_iterator& operator=(multi_links_iterator&& other) noexcept multi_linker_iterator& operator=(multi_linker_iterator&& other) noexcept
{ {
if (this != &other) { if (this != &other) {
list = other.list; list = other.list;
...@@ -164,29 +190,44 @@ public: ...@@ -164,29 +190,44 @@ public:
} }
}; };
template <typename Identifier> template<typename Identifier>
struct multi_links_node struct multi_linker_node
{ {
Identifier id = { -1 }; Identifier id = { -1 };
int next = { -1 }; int next = { -1 };
}; };
template<typename Identifier, template<typename Identifier,
typename IdentifierAllocator = std::allocator<Identifier>, typename Referenced,
typename NodeAllocator = std::allocator<mult_links_node>> typename IdentifierAllocator = std::allocator<Identifier>,
class multi_links typename NodeAllocator = std::allocator<mult_linker_node>>
class multi_linker
{ {
public:
using identifier_type = Identifier;
using referenced_type = Referenced;
private: private:
std::vector<int, IdentifierAllocator> map; // Map ID to head in the linked list. /// Map ID to head in the linked list.
std::vector<mult_links_node, NodeAllocator> list; // 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; int free_head = -1;
public: public:
multi_links(int size, const Allocator& allocator) noexcept multi_linker(const size_t size, const Allocator& allocator) noexcept
: map(size, -1, allocator) : map(size, get_invalid<referenced_type>(), allocator)
, list(size, allocator) , list(size, allocator)
, free_head(-1) , 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(); list.clear();
} }
...@@ -242,3 +283,5 @@ public: ...@@ -242,3 +283,5 @@ public:
}; };
} // namespace bits } // namespace bits
#endif // ORG_VLEPROJECT_BITS_LINKS_HPP
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <bits/allocator.hpp> #include <bits/allocator.hpp>
#include <bits/data-array.hpp> #include <bits/data-array.hpp>
#include <bits/list.hpp> #include <bits/linker.hpp>
#include <bits/unit-test.hpp> #include <bits/unit-test.hpp>
...@@ -34,8 +34,7 @@ ...@@ -34,8 +34,7 @@
namespace vle { namespace vle {
using ID = bits::ID; using ID = bits::ID;
// using ForwardListID = bits::flat_forward_list<ID>::accessor_type; using ID4 = bits::ID[4];
using ListID = std::list<ID, bits::block_memory_allocator<ID, 32768>>;
struct Dynamics struct Dynamics
{ {
...@@ -79,21 +78,23 @@ enum class value_type ...@@ -79,21 +78,23 @@ enum class value_type
struct Value struct Value
{ {
ID id = -1;
value_type type = value_type::none; value_type type = value_type::none;
}; };
struct NamedValue struct NamedValue
{ {
std::string name; std::string name;
ID id = -1;
value_type type = value_type::none; value_type type = value_type::none;
}; };
struct Condition struct Condition
{ {
std::string name; std::string name;
ListID named_values_list; };
struct Port
{
std::string name;
}; };
struct Connection struct Connection
...@@ -131,65 +132,6 @@ struct Class ...@@ -131,65 +132,6 @@ struct Class
std::string name; 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 struct Vpz
{ {
std::string name; std::string name;
...@@ -212,13 +154,15 @@ struct Vpz ...@@ -212,13 +154,15 @@ struct Vpz
bits::data_array<double, ID> real64; bits::data_array<double, ID> real64;
bits::data_array<std::string, ID> string; 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_dynamics;
bits::links<ID> model_parent; bits::links<ID> model_parent;
bits::multi_links<ID> model_input_ports;
bits::multi_links<ID> model_connections; bits::multi_links<ID> model_output_ports;
bits::multi_links<ID4> model_connections;
bits::multi_links<ID> model_conditions; bits::multi_links<ID> model_conditions;
bits::multi_links<ID> model_children; bits::multi_links<ID> model_children;
bits::multi_links<ID> condition_port;
void init(int object_capacity, int list_capacity) void init(int object_capacity, int list_capacity)
{ {
...@@ -434,7 +378,7 @@ struct Vpz ...@@ -434,7 +378,7 @@ struct Vpz
} // vle } // vle
int int
main(int /* argc */, char* /* argv */ []) main(int /* argc */, char* /* argv */[])
{ {
vle::Vpz vpz; vle::Vpz vpz;
......
Supports Markdown
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