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

next11

parent b71a75ac
Pipeline #2304 failed with stage
in 1 minute
......@@ -9,12 +9,11 @@
#include <type_traits>
#include <vector>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <bits/assert.hpp>
namespace bits {
using ID = std::uint64_t;
......@@ -87,6 +86,44 @@ valid(Identifier id) noexcept
return get_key(id) > 0;
}
template<typename T>
constexpr T
make_id(unsigned key, int index) noexcept;
template<>
constexpr ID
make_id<ID>(unsigned key, int index) noexcept
{
ID id = key;
id <<= 32;
return id | index;
}
template<>
constexpr IDs
make_id<IDs>(unsigned key, int index) noexcept
{
return (key << 16 | index);
}
template<typename T>
constexpr unsigned
make_next_key(unsigned key) noexcept;
template<>
constexpr unsigned
make_next_key<ID>(unsigned key) noexcept
{
return key == get_max_key<ID>() ? 1u : key + 1;
}
template<>
constexpr unsigned
make_next_key<IDs>(unsigned key) noexcept
{
return key == get_max_key<IDs>() ? 1u : key + 1;
}
/**
* @brief An optimized fixed size array for dynamics objects.
* @details Handles everything from any trivial, pod or object.
......@@ -262,37 +299,14 @@ data_array<T, Identifier>::alloc()
Do_alloc<T, Identifier>(items[new_index].item, std::is_trivial<T>());
if (next_key == get_max_key<Identifier>())
next_key = 1;
items[new_index].id = (next_key++ << 16) | new_index;
std::printf("new index: %d next key: %u and ID: %lu\n",
new_index,
next_key,
static_cast<long unsigned int>(
make_id<Identifier>(next_key, new_index)));
++max_size;
return items[new_index].item;
}
template<typename T, typename Identifier>
template<typename... Args>
T&
data_array<T, Identifier>::alloc(Args&&... args)
{
int new_index;
if (free_head >= 0) {
new_index = free_head;
if (valid(items[free_head].id))
free_head = -1;
else
free_head = get_index(items[free_head].id);
} else {
new_index = max_used++;
}
new (&items[new_index].item) T(std::forward<Args>(args)...);
if (next_key == get_max_key<Identifier>())
next_key = 1;
items[new_index].id = (next_key++ << 16) | new_index;
items[new_index].id = make_id<Identifier>(next_key, new_index);
next_key = make_next_key<Identifier>(next_key);
++max_size;
......@@ -323,9 +337,9 @@ data_array<T, Identifier>::free(T& t)
auto id = get_id(t);
auto index = get_index(id);
assert(&items[index] == static_cast<void*>(&t));
assert(items[index].id == id);
assert(valid(id));
bits_assert(&items[index] == static_cast<void*>(&t));
bits_assert(items[index].id == id);
bits_assert(valid(id));
Do_free<T, Identifier>(items[index].item, std::is_trivial<T>());
......@@ -341,8 +355,8 @@ data_array<T, Identifier>::free(Identifier id)
{
auto index = get_index(id);
assert(items[index].id == id);
assert(valid(id));
bits_assert(items[index].id == id);
bits_assert(valid(id));
Do_free<T, Identifier>(items[index].item, std::is_trivial<T>());
......@@ -364,10 +378,14 @@ Identifier
data_array<T, Identifier>::get_id(const T& t)
{
using type = data_array<T, Identifier>::item;
auto offset = offsetof(type, id);
auto* ptr = reinterpret_cast<const char*>(&t);
ptr += offset;
return static_cast<int>(*reinterpret_cast<int*>(ptr));
// auto offset = offsetof(type, id);
// auto* ptr = reinterpret_cast<const char*>(&t);
// ptr += offset;
// return static_cast<int>(*reinterpret_cast<const int*>(ptr));
auto* ptr = reinterpret_cast<const item*>(&t);
return ptr->id;
}
template<typename T, typename Identifier>
......
......@@ -53,6 +53,14 @@ public:
bits_expects(size > 0);
}
void emplace(const identifier_type id,
const referenced_type value) noexcept
{
bits_expects(bits::valid(id));
items[bits::get_index(id)] = value;
}
referenced_type operator[](const identifier_type id) const noexcept
{
bits_expects(bits::valid(id));
......@@ -78,143 +86,30 @@ public:
template<typename T, typename Identifier>
struct data_array;
template<typename Linker, typename DataArray, typename Identifier>
class multi_linker_iterator
template<typename Referenced>
struct multi_linker_node
{
public:
using iterator_category = std::forward_iterator_tag;
using value_type = Identifier;
using difference_type = std::ptrdiff_t;
using pointer = Identifier*;
using reference = Identifier&;
multi_linker_node() = default;
private:
Linker* list = nullptr;
DataArray* dataarray = nullptr;
Identifier elem = { -1 };
public:
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_linker_iterator(Linker* list_,
DataArray* dataarray_,
Identifier elem_) noexcept
: list(list_)
, dataarray(dataarray_)
, elem(elem_)
multi_linker_node(const Referenced id_, const int next_)
: id(id_)
, next(next_)
{}
multi_linker_iterator(multi_linker_iterator&& other) noexcept
: list(other.list)
, dataarray_(other.dataarray)
, elem(other.elem)
{
other.list = nullptr;
other.dataarray = nullptr;
other.elem = -1;
}
multi_linker_iterator& operator=(multi_linker_iterator&& other) noexcept
{
if (this != &other) {
list = other.list;
dataarray = other.dataarray;
elem = other.elem;
other.list = nullptr;
other.dataarray = nullptr;
other.elem = { -1 };
}
return *this;
}
/**
* @brief Advance the ID to the next valid ID in the linked list.
*
* @details If a element is invalid, this element is removed from the list.
*/
void advance() noexcept
{
if (list && elem >= 0) {
int next = list[elem].next;
while (next >= 0) {
if (dataarray->try_to_get(list[next].id)) {
elem = next;
return;
} else {
list[elem].next = list[next].next;
list[next].next = free_head;
free_head = next;
next = list[elem].next;
}
}
}
}
multi_linker_iterator operator++(int)
{
multi_linker_iterator copy(*this);
advance();
return copy;
}
multi_linker_iterator operator++()
{
advance();
return *this;
}
pointer operator->() const noexcept
{
return &list[elem].id;
}
reference operator*() const noexcept
{
return list[elem].id;
}
friend void swap(multi_linker_iterator& lhs,
multi_linker_iterator& rhs) noexcept
{
auto items_ = lhs.items;
auto id_ = lhs.id;
lhs.items = rhs.items;
lhs.id = rhs.id;
rhs.items = items_;
rhs.id = id_;
}
friend bool operator==(const multi_linker_iterator& lhs,
const multi_linker_iterator& rhs) noexcept
{
return lhs.id == rhs.id;
}
friend bool operator!=(const multi_linker_iterator& lhs,
const multi_linker_iterator& rhs) noexcept
{
return !(lhs.id == rhs.id);
}
};
template<typename Referenced>
struct multi_linker_node
{
Referenced id = { 0 };
int next = { -1 }; // Next element is the (flat) linked list.
int next = { -1 }; // Next element is the (flat) linked list.
};
template<typename Identifier,
typename Referenced,
typename IdentifierAllocator = std::allocator<int>,
typename NodeAllocator = std::allocator<multi_linker_node<Referenced>>>
typename NodeAllocator =
std::allocator<multi_linker_node<Referenced>>>
class multi_linker
{
public:
using this_type =
multi_linker<Identifier, Referenced, IdentifierAllocator, NodeAllocator>;
using identifier_type = Identifier;
using referenced_type = Referenced;
......@@ -228,6 +123,129 @@ private:
/// The free linked list.
int free_head = -1;
template<typename DataArray>
class iterator
{
public:
using iterator_category = std::forward_iterator_tag;
using value_type = Identifier;
using difference_type = std::ptrdiff_t;
using pointer = Identifier*;
using reference = Identifier&;
private:
this_type* list = nullptr;
DataArray* dataarray = nullptr;
int elem = -1;
public:
iterator() noexcept = default;
iterator(const iterator&) noexcept = default;
iterator& operator=(const iterator&) noexcept = default;
iterator(this_type* list_,
DataArray* dataarray_,
Identifier elem_) noexcept
: list(list_)
, dataarray(dataarray_)
, elem(elem_)
{}
iterator(iterator&& other) noexcept
: list(other.list)
, dataarray(other.dataarray)
, elem(other.elem)
{
other.list = nullptr;
other.dataarray = nullptr;
other.elem = -1;
}
iterator& operator=(iterator&& other) noexcept
{
if (this != &other) {
list = other.list;
dataarray = other.dataarray;
elem = other.elem;
other.list = nullptr;
other.dataarray = nullptr;
other.elem = { -1 };
}
return *this;
}
/**
* @brief Advance the ID to the next valid ID in the linked list.
*
* @details If a element is invalid, this element is removed from the
* list.
*/
void advance() noexcept
{
if (list && elem >= 0) {
int next = list->list[elem].next;
while (next >= 0) {
if (dataarray->try_to_get(list->list[next].id)) {
elem = next;
return;
} else {
list->list[elem].next = list->list[next].next;
list->list[next].next = list->free_head;
list->free_head = next;
next = list->list[elem].next;
}
}
}
}
iterator operator++(int)
{
iterator copy(*this);
advance();
return copy;
}
iterator operator++()
{
advance();
return *this;
}
pointer operator->() const noexcept
{
return &list[elem].id;
}
reference operator*() const noexcept
{
return list->list[elem].id;
}
friend void swap(iterator& lhs, iterator& rhs) noexcept
{
auto items_ = lhs.items;
auto id_ = lhs.id;
lhs.items = rhs.items;
lhs.id = rhs.id;
rhs.items = items_;
rhs.id = id_;
}
friend bool operator==(const iterator& lhs,
const iterator& rhs) noexcept
{
return lhs.list == rhs.list && lhs.dataarray == rhs.dataarray &&
lhs.elem == rhs.elem;
}
friend bool operator!=(const iterator& lhs,
const iterator& rhs) noexcept
{
return !(lhs == rhs);
}
};
public:
multi_linker(const size_t size) noexcept
: map(size, 0, IdentifierAllocator())
......@@ -259,8 +277,7 @@ public:
void emplace(Identifier ID, Referenced value) noexcept
{
assert(bits::valid(ID));
assert(bits::valid(value));
bits_expects(bits::valid(ID));
auto index = bits::get_index(ID);
......@@ -281,19 +298,19 @@ public:
template<typename DataArray>
auto begin(DataArray* array, Identifier head) noexcept
{
auto index = bits::get_index(ID);
return multi_linker_iterator(&list, array, index);
auto index = bits::get_index(head);
return iterator(this, array, index);
}
template<typename DataArray>
auto end(DataArray* array) noexcept
{
return multi_linker_iterator(&list, array, -1);
return iterator(this, array, -1);
}
void destroy(Identifier ID)
{
assert(bits::valid(ID));
bits_expects(bits::valid(ID));
auto index = bits::get_index(ID);
auto id = map[index];
......
......@@ -20,10 +20,12 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <cstdio>
#include <bits/data-array.hpp>
#include <bits/fixed-2darray.hpp>
#include <bits/fixed-array.hpp>
#include <bits/list.hpp>
// #include <bits/list.hpp>
#include <bits/unit-test.hpp>
......@@ -33,45 +35,45 @@
static void
check_list()
{
bits::flat_list<float> list;
bits::flat_list<float>::accessor_type access;
// bits::flat_list<float> list;
// bits::flat_list<float>::accessor_type access;
list.init(32);
// list.init(32);
access.head = -1;
access.tail = -1;
// access.head = -1;
// access.tail = -1;
access = list.push_back(access, 2.f);
access = list.push_back(access, 3.f);
access = list.push_front(access, 1.f);
// access = list.push_back(access, 2.f);
// access = list.push_back(access, 3.f);
// access = list.push_front(access, 1.f);
{
int size = 0;
for (int i = access.head; i != -1; i = list.items[i].next)
size++;
Ensures(size == 3);
Ensures(list.items[access.head].id == 1.f);
Ensures(list.items[access.tail].id == 3.f);
Ensures(list.items[list.items[access.head].next].id == 2.f);
}
// {
// int size = 0;
// for (int i = access.head; i != -1; i = list.items[i].next)
// size++;
access = list.remove_if(access, [](float f) { return (f == 2.f); });
// Ensures(size == 3);
// Ensures(list.items[access.head].id == 1.f);
// Ensures(list.items[access.tail].id == 3.f);
// Ensures(list.items[list.items[access.head].next].id == 2.f);
// }
{
int size = 0;
for (int i = access.head; i != -1; i = list.items[i].next)
size++;
// access = list.remove_if(access, [](float f) { return (f == 2.f); });
Ensures(size == 2);
Ensures(list.items[access.head].id == 1.f);
Ensures(list.items[access.tail].id == 3.f);
}
// {
// int size = 0;
// for (int i = access.head; i != -1; i = list.items[i].next)
// size++;
// Ensures(size == 2);
// Ensures(list.items[access.head].id == 1.f);
// Ensures(list.items[access.tail].id == 3.f);
// }
access = list.clear(access);
// access = list.clear(access);
Ensures(access.head == access.tail);
Ensures(access.head == -1);
// Ensures(access.head == access.tail);
// Ensures(access.head == -1);
}
static void
......
......@@ -20,6 +20,9 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <cstdio>
#include <iostream>
#include <bits/allocator.hpp>
#include <bits/data-array.hpp>
#include <bits/linker.hpp>
......@@ -29,13 +32,27 @@
#include <forward_list>
#include <string>
#include <cstdio>
namespace vle {
using ID = bits::ID;
using ID2 = bits::ID[2];
using ID4 = bits::ID[4];
struct ID2
{
ID2() = default;
ID2(ID id)
: id1(id)
, id2(id)
{}
ID2(ID id1_, ID id2_)
: id1(id1_)
, id2(id2_)
{}
ID id1{ 0 };
ID id2{ 0 };
};
struct Dynamics
{
......@@ -110,6 +127,8 @@ struct Model
coupled
};
std::int16_t input_slot_number = 0;
std::int16_t output_slot_number = 0;
model_type type = model_type::atomic;
};
......@@ -117,8 +136,13 @@ struct Model
// {
// ImVec2 pos = { 0, 0 };
// ImVec2 size = { 0, 0 };
// unsigned input_slot_number;