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

next4

parent b6308dfa
Pipeline #2205 passed with stage
in 43 seconds
......@@ -171,7 +171,7 @@ template<typename T, typename Identifier>
data_array<T, Identifier>::~data_array()
{
if (items)
::free(items);
delete[] items;
}
template<typename T, typename Identifier>
......@@ -183,8 +183,7 @@ data_array<T, Identifier>::init(int capacity_)
if (capacity_ < 0 || capacity_ > size<ID>())
return false;
items = (data_array<T, Identifier>::item*)::malloc(
static_cast<size_t>(capacity) * sizeof(item));
items = new item[capacity_ * sizeof(item)];
max_size = 0;
max_used = 0;
capacity = capacity_;
......
// 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_FLAT_LIST_HPP
#define ORG_VLEPROJECT_BITS_FLAT_LIST_HPP
#include <bits/data-array.hpp>
namespace bits {
template<typename T, typename Identifier>
struct flat_list
{
struct item
{
T id;
Identifier previous;
Identifier next;
};
data_array<item, Identifier> items;
flat_list() = default;
~flat_list() = default;
bool init(int capacity_)
{
return items.init(capacity_);
}
[[nodiscard]] Identifier push_front(Identifier head, T id) noexcept
{
auto& t = items.alloc();
t.id = id;
t.next = head;
return items.get_id(t);
}
[[nodiscard]] Identifier pop_front(Identifier head) noexcept
{
auto* t = items.try_to_get(head);
if (!t)
return 0u;
head = t->next;
items.free(*t);
return head;
}
void insert_after(Identifier elem, T id) noexcept
{
auto* t = items.try_to_get(elem);
assert(t);
auto& new_node = items.alloc();
new_node.id = id;
new_node.next = t->next;
t->next = items.get_id(new_node);
return elem;
}
void erase_after(Identifier elem) noexcept
{
auto* t = items.try_to_get(elem);
assert(t);
auto* next = items.try_to_get(t->next);
if (next) {
t->next = next->next;
free(*next);
}
}
template<typename Predicate>
[[nodiscard]] Identifier remove_if(Identifier head,
Predicate predicate) noexcept
{
Identifier current = head;
Identifier next = 0u;
while (valid(head)) {
auto& t = items.get(head);
if (predicate(t.id)) {
head = pop_front(head);
} else {
current = head;
next = t.next;
break;
}
}
while (valid(current) && valid(next)) {
if (predicate(items.get(next).id)) {
erase_after(current);
} else {
current = next;
next = get(next).next;
};
}
return head;
}
[[nodiscard]] Identifier clear(Identifier head) noexcept
{
while (valid(head))
head = pop_front(head);
return 0u;
}
};
} // bits
#endif
// 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_TRIVIAL_LIST_HPP
#define ORG_VLEPROJECT_BITS_TRIVIAL_LIST_HPP
#include <bits/data-array.hpp>
namespace bits {
/* Maybe we can call it trivial_flat_forward_list ? */
template<typename T>
struct flat_forward_list
{
using accessor_type = int;
static_assert(std::is_trivial<T>::value,
"flat_forward_list needs trivial type");
struct item
{
T id;
int next;
};
item* items = nullptr;
int size = 0;
int free_head = -1;
int capacity = 0;
flat_forward_list() = default;
~flat_forward_list()
{
if (items)
delete[] items;
}
bool init(int capacity_)
{
assert(capacity_ > 0);
if (items)
delete[] items;
capacity = capacity_;
size = 0;
free_head = -1;
items = new item[capacity_];
}
[[nodiscard]] int alloc() noexcept
{
int new_head;
if (free_head >= 0) {
new_head = free_head;
free_head = items[new_head].next;
} else {
new_head = size++;
}
return new_head;
}
[[nodiscard]] accessor_type push_front(int head, T id) noexcept
{
int new_head = alloc();
items[new_head].id = id;
items[new_head].next = head;
return new_head;
}
[[nodiscard]] int pop_front(int head) noexcept
{
if (head >= 0) {
int old_head = head;
head = items[head].next;
items[old_head].id = 0u;
items[old_head].next = free_head;
free_head = old_head;
}
return head;
}
void erase_after(int elem) noexcept
{
assert(elem >= 0 && elem < capacity);
if (items[elem].next >= 0) {
int to_delete = items[elem].next;
items[elem].next = items[to_delete].next;
items[to_delete].next = free_head;
free_head = to_delete;
}
}
template<typename Predicate>
[[nodiscard]] int remove_if(int head, Predicate predicate) noexcept
{
while (head >= 0 && predicate(items[head].id))
head = pop_front(head);
if (head < 0)
return head;
int current = head;
int next = items[head].next;
while (current >= 0 && next >= 0) {
if (predicate(items[next].id)) {
erase_after(current);
} else {
current = next;
next = items[next].next;
};
}
return head;
}
[[nodiscard]] int clear(int head) noexcept
{
while (head >= 0)
head = pop_front(head);
return -1;
}
};
template<typename T>
struct flat_list
{
struct accessor_type
{
int head = -1;
int tail = -1;
};
static_assert(std::is_trivial<T>::value, "flat_list needs trivial type");
struct item
{
T id;
int previous;
int next;
};
item* items = nullptr;
int size = 0;
int free_head = -1;
int capacity = 0;
flat_list() = default;
~flat_list()
{
if (items)
delete[] items;
}
bool init(int capacity_)
{
assert(capacity_ > 0);
if (items)
delete[] items;
capacity = capacity_;
size = 0;
free_head = -1;
items = new item[capacity_];
return true;
}
[[nodiscard]] int alloc(T id) noexcept
{
int new_head;
if (free_head >= 0) {
new_head = free_head;
free_head = items[new_head].next;
} else {
new_head = size++;
}
items[new_head].id = id;
return new_head;
}
void erase(int element) noexcept
{
items[element].id = 0;
items[element].next = free_head;
if (free_head >= 0)
items[free_head].previous = element;
free_head = element;
}
[[nodiscard]] accessor_type push_front(accessor_type list, T id) noexcept
{
int new_head = alloc(id);
items[new_head].previous = -1;
items[new_head].next = list.head;
if (list.head >= 0)
items[list.head].previous = new_head;
list.head = new_head;
if (list.tail < 0)
list.tail = new_head;
return list;
}
[[nodiscard]] accessor_type pop_front(accessor_type list) noexcept
{
if (list.head == -1)
return list;
if (list.head == list.tail) {
erase(list.head);
list.head = -1;
list.tail = -1;
return list;
}
int new_head = items[list.head].next;
items[new_head].previous = -1;
erase(list.head);
list.head = new_head;
return list;
}
[[nodiscard]] accessor_type push_back(accessor_type list, T id) noexcept
{
int new_tail = alloc(id);
items[new_tail].next = -1;
items[new_tail].previous = list.tail;
if (list.tail >= 0)
items[list.tail].next = new_tail;
list.tail = new_tail;
if (list.head < 0)
list.head = new_tail;
return list;
}
[[nodiscard]] accessor_type pop_back(accessor_type list) noexcept
{
if (list.head == -1)
return list;
if (list.head == list.tail) {
erase(list.tail);
list.head = -1;
list.tail = -1;
return list;
}
int new_tail = items[list.tail].previous;
items[new_tail].next = -1;
erase(list.tail);
list.tail = new_tail;
return list;
}
[[nodiscard]] accessor_type erase(accessor_type list, int elem) noexcept
{
assert(elem >= 0 && elem < capacity);
assert(list.head != -1 && list.tail != -1);
if (list.head == elem)
return pop_front(list);
if (list.tail == elem)
return pop_back(list);
int previous = items[elem].previous;
int next = items[elem].next;
items[previous].next = next;
items[next].previous = previous;
erase(elem);
return list;
}
template<typename Predicate>
[[nodiscard]] accessor_type remove_if(accessor_type list,
Predicate predicate) noexcept
{
if (list.head < 0)
return list;
while (list.head >= 0 && predicate(items[list.head].id))
list = pop_front();
while (list.tail >= 0 && predicate(items[list.tail].id))
list = pop_back();
for (int current = list.head; current != list.tail;
current = items[current].next) {
if (predicate(items[current].id)) {
int previous = items[current].previous;
int next = items[current].next;
items[previous].next = next;
items[next].previous = previous;
erase(current);
current = previous;
}
}
return list;
}
[[nodiscard]] int find(accessor_type list, T id) const noexcept
{
if (list.head < 0)
return -1;
if (list.head == list.tail)
return items[list.head].id == id ? list.head : -1;
for (int current = list.head; current != list.tail;
current = items[current].next)
if (items[current].id == id)
return current;
if (items[list.tail].id == id)
return list.tail;
}
template<typename Predicate>
[[nodiscard]] int find_if(accessor_type list, Predicate predicate) const
noexcept
{
if (list.head < 0)
return -1;
if (list.head == list.tail)
return predicate(items[list.head].id) ? list.head : -1;
for (int current = list.head; current != list.tail;
current = items[current].next)
if (predicate(items[current].id))
return current;
if (predicate(items[list.tail].id))
return list.tail;
}
[[nodiscard]] accessor_type clear(accessor_type list) noexcept
{
while (list.head != -1)
list = pop_front(list);
return list;
}
};
} // bits
#endif
......@@ -23,7 +23,7 @@
#include <bits/data-array.hpp>
#include <bits/fixed-2darray.hpp>
#include <bits/fixed-array.hpp>
#include <bits/flat-list.hpp>
#include <bits/list.hpp>
#include <bits/unit-test.hpp>
......
......@@ -21,7 +21,7 @@
*/
#include <bits/data-array.hpp>
#include <bits/flat-list.hpp>
#include <bits/list.hpp>
#include <bits/unit-test.hpp>
......@@ -30,6 +30,8 @@
namespace vle {
using ID = bits::ID;
using ForwardListID = bits::flat_forward_list<ID>::accessor_type;
using ListID = bits::flat_list<ID>::accessor_type;
struct Dynamics
{
......@@ -47,7 +49,7 @@ struct View
std::string package;
std::string library;
std::string location;
double timestep;
double timestep = 1.0;
enum class view_type
{
......@@ -60,7 +62,7 @@ struct View
finish = 1 << 6,
};
view_type type;
view_type type = view_type::timed;
};
struct Value
......@@ -76,37 +78,33 @@ struct Value
string,
};
Value()
: id(0)
, type(Value::value_type::none)
{}
ID id; // ID in one of the data_array of the Values structure.
value_type type; // The type of the identifier ID.
ID id = -1; // ID in one of the data_array of the Values structure.
value_type type = value_type::none; // The type of the identifier ID.
};
struct Condition
{
std::string name;
ID value_list;
ListID value_list{ -1, -1 };
};
struct Connection
{
ID model_src;
ID model_slot_src;
ID model_dst;
ID model_slot_dst;
ID model_src = -1;
ID model_slot_src = -1;
ID model_dst = -1;
ID model_slot_dst = -1;
};
struct Model
{
std::string name;
ID dynamics;
ID conditions_list;
ID observables_list;
ID connections_list;
ID parent;
ID parent = -1;
ID dynamics = -1;
ListID conditions_list = { -1, -1 };
ListID observables_list = { -1, -1 };
ListID connections_list = { -1, -1 };
ListID child_list = { -1, -1 };
enum class model_type
{
......@@ -114,7 +112,7 @@ struct Model
coupled
};
model_type type;
model_type type = model_type::atomic;
};
// struct GuiModel
......@@ -122,19 +120,15 @@ struct Model
// ID model = { 0u };
// ImVec2 pos = { 0, 0 };
// ImVec2 size = { 0, 0 };
// unsigned input_slot_number;