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

snif3

parent f1a578b1
Pipeline #2187 failed with stage
in 40 seconds
/* // Copyright (c) 2019 INRA Distributed under the Boost Software License,
* This file is part of VLE, a framework for multi-modeling, simulation // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* and analysis of complex dynamical systems. // http://www.boost.org/LICENSE_1_0.txt)
* https://www.vle-project.org
*
* Copyright (c) 2003-2018 Gauthier Quesnel <gauthier.quesnel@inra.fr>
* Copyright (c) 2003-2018 ULCO http://www.univ-littoral.fr
* Copyright (c) 2007-2018 INRA http://www.inra.fr
*
* See the AUTHORS or Authors.txt file for copyright owners and
* contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ORG_VLEPROJECT_BITS_DATAARRAY_HPP #ifndef ORG_VLEPROJECT_BITS_DATAARRAY_HPP
#define ORG_VLEPROJECT_BITS_DATAARRAY_HPP #define ORG_VLEPROJECT_BITS_DATAARRAY_HPP
...@@ -39,37 +17,49 @@ ...@@ -39,37 +17,49 @@
namespace bits { namespace bits {
using ID = std::uint_least64_t; using ID = std::uint64_t;
using IDs = std::uint_least32_t; using IDs = std::uint32_t;
constexpr ID constexpr int
get_index(ID id) noexcept get_index(ID id) noexcept
{ {
return static_cast<int>(id & 0x00000000ffffffff); return static_cast<int>(id & 0x00000000ffffffff);
} }
constexpr ID constexpr unsigned
get_key(ID id) noexcept get_key(ID id) noexcept
{ {
return id & 0xffffffff00000000; return static_cast<unsigned>((id & 0xffffffff00000000) >> 32);
}
constexpr int
get_index(IDs id) noexcept
{
return static_cast<int>(id & 0x0000ffff);
}
constexpr unsigned
get_key(IDs id) noexcept
{
return id & 0xffff0000;
} }
template<typename T> template<typename T>
constexpr T constexpr unsigned
get_max_key() noexcept; get_max_key() noexcept;
template<> template<>
constexpr ID constexpr unsigned
get_max_key<ID>() noexcept get_max_key<ID>() noexcept
{ {
return 0xffffffff00000000; return static_cast<unsigned>(0xffffffff00000000 >> 32);
} }
template<> template<>
constexpr IDs constexpr unsigned
get_max_key<IDs>() noexcept get_max_key<IDs>() noexcept
{ {
return 0xffff0000; return static_cast<unsigned>(0xffff0000 >> 16);
} }
template<typename T> template<typename T>
...@@ -87,31 +77,14 @@ template<> ...@@ -87,31 +77,14 @@ template<>
constexpr int constexpr int
size<IDs>() noexcept size<IDs>() noexcept
{ {
return INT16_MAX; return UINT16_MAX;
}
constexpr bool
is_valid(ID id) noexcept
{
return (id & 0xffffffff00000000) != 0;
}
constexpr int
get_index(IDs id) noexcept
{
return id & 0x0000ffff;
}
constexpr int
get_key(IDs id) noexcept
{
return id & 0xffff0000;
} }
template<typename Identifier>
constexpr bool constexpr bool
is_valid(IDs id) noexcept valid(Identifier id) noexcept
{ {
return (id & 0xffff0000) != 0; return get_key(id) != 0;
} }
/** /**
...@@ -136,19 +109,7 @@ struct data_array ...@@ -136,19 +109,7 @@ struct data_array
Identifier id; Identifier id;
}; };
using this_type = data_array<T, Identifier>;
using value_type = T;
using reference = value_type&;
using const_reference = const value_type&;
using iterator = item*;
using const_iterator = const item*;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using size_type = int;
using difference_type = ptrdiff_t;
data_array() = default; data_array() = default;
~data_array(); ~data_array();
/** Allocate a vector of items (max 65536 items). /** Allocate a vector of items (max 65536 items).
...@@ -160,21 +121,21 @@ struct data_array ...@@ -160,21 +121,21 @@ struct data_array
/** Resets data members, (runs destructors* on outstanding items, *optional /** Resets data members, (runs destructors* on outstanding items, *optional
*/ */
void clear(); void clear();
/* alloc (memclear* and/or construct*, *optional) an item from /* alloc (memclear* and/or construct*, *optional) an item from
freeList or items[max_used++], sets id to (next_key++ << 16) | index */ freeList or items[max_used++], sets id to (next_key++ << 16) | index */
T& alloc(); T& alloc();
template <typename... Args> template<typename... Args>
T& alloc(Args&&... args); T& alloc(Args&&... args);
// puts entry on free list (uses id to store next) // puts entry on free list (uses id to store next)
void free(T&); void free(T&);
void free(Identifier id); void free(Identifier id);
// accessor to the id part if Item // accessor to the id part if Item
int get_id(T&); Identifier get_id(T&);
T& get(Identifier id); // return item[id & 0xFFFF]; T& get(Identifier id); // return item[id & 0xFFFF];
...@@ -196,30 +157,14 @@ struct data_array ...@@ -196,30 +157,14 @@ struct data_array
*/ */
bool next(T*&); bool next(T*&);
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cend() const noexcept;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator crbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crend() const noexcept;
bool full() const noexcept; bool full() const noexcept;
item* items = nullptr; // items vector. item* items = nullptr; // items vector.
int max_size = 0; // total size int max_size = 0; // total size
int max_used = 0; // highest index ever alloced int max_used = 0; // highest index ever alloced
int capacity = 0; // num alloced items int capacity = 0; // num alloced items
int next_key = 1; // [1..2^16] (don't let == 0) unsigned int next_key = 1; // [1..2^16] (don't let == 0)
int free_head = -1; // index of first free entry int free_head = -1; // index of first free entry
}; };
template<typename T, typename Identifier> template<typename T, typename Identifier>
...@@ -266,7 +211,7 @@ Do_clear(typename data_array<T, Identifier>::item* items, ...@@ -266,7 +211,7 @@ Do_clear(typename data_array<T, Identifier>::item* items,
std::false_type) std::false_type)
{ {
for (int i = 0; i != size; ++i) { for (int i = 0; i != size; ++i) {
if (is_valid(items[i].id)) { if (valid(items[i].id)) {
items[i].item.~T(); items[i].item.~T();
items[i].id = 0; items[i].id = 0;
} }
...@@ -308,7 +253,7 @@ data_array<T, Identifier>::alloc() ...@@ -308,7 +253,7 @@ data_array<T, Identifier>::alloc()
if (free_head >= 0) { if (free_head >= 0) {
new_index = free_head; new_index = free_head;
if (is_valid(items[free_head].id)) if (valid(items[free_head].id))
free_head = -1; free_head = -1;
else else
free_head = get_index(items[free_head].id); free_head = get_index(items[free_head].id);
...@@ -316,7 +261,7 @@ data_array<T, Identifier>::alloc() ...@@ -316,7 +261,7 @@ data_array<T, Identifier>::alloc()
new_index = max_used++; new_index = max_used++;
} }
new (&items[new_index].item) T(std::formard<Args>(args)...); Do_alloc<T, Identifier>(items[new_index].item, std::is_trivial<T>());
if (next_key == get_max_key<Identifier>()) if (next_key == get_max_key<Identifier>())
next_key = 1; next_key = 1;
...@@ -328,15 +273,15 @@ data_array<T, Identifier>::alloc() ...@@ -328,15 +273,15 @@ data_array<T, Identifier>::alloc()
} }
template<typename T, typename Identifier> template<typename T, typename Identifier>
template <typename... Args> template<typename... Args>
T& T&
data_array<T, Identifier>::alloc(Args&&... args) data_array<T, Identifier>::alloc(Args&&... args)
{ {
int new_index; int new_index;
if (free_head >= 0) { if (free_head >= 0) {
new_index = free_head; new_index = free_head;
if (is_valid(items[free_head].id)) if (valid(items[free_head].id))
free_head = -1; free_head = -1;
else else
free_head = get_index(items[free_head].id); free_head = get_index(items[free_head].id);
...@@ -344,7 +289,7 @@ data_array<T, Identifier>::alloc(Args&&... args) ...@@ -344,7 +289,7 @@ data_array<T, Identifier>::alloc(Args&&... args)
new_index = max_used++; new_index = max_used++;
} }
Do_alloc<T, Identifier>(items[new_index].item, std::is_trivial<T>()); new (&items[new_index].item) T(std::forward<Args>(args)...);
if (next_key == get_max_key<Identifier>()) if (next_key == get_max_key<Identifier>())
next_key = 1; next_key = 1;
...@@ -352,7 +297,7 @@ data_array<T, Identifier>::alloc(Args&&... args) ...@@ -352,7 +297,7 @@ data_array<T, Identifier>::alloc(Args&&... args)
++max_size; ++max_size;
return items[new_index].item; return items[new_index].item;
} }
template<typename T, typename Identifier> template<typename T, typename Identifier>
...@@ -381,7 +326,7 @@ data_array<T, Identifier>::free(T& t) ...@@ -381,7 +326,7 @@ data_array<T, Identifier>::free(T& t)
assert(&items[index] == static_cast<void*>(&t)); assert(&items[index] == static_cast<void*>(&t));
assert(items[index].id == id); assert(items[index].id == id);
assert(is_valid(id)); assert(valid(id));
Do_free<T, Identifier>(items[index].item, std::is_trivial<T>()); Do_free<T, Identifier>(items[index].item, std::is_trivial<T>());
...@@ -398,7 +343,7 @@ data_array<T, Identifier>::free(Identifier id) ...@@ -398,7 +343,7 @@ data_array<T, Identifier>::free(Identifier id)
auto index = get_index(id); auto index = get_index(id);
assert(items[index].id == id); assert(items[index].id == id);
assert(is_valid(id)); assert(valid(id));
Do_free<T, Identifier>(items[index].item, std::is_trivial<T>()); Do_free<T, Identifier>(items[index].item, std::is_trivial<T>());
...@@ -416,7 +361,7 @@ data_array<T, Identifier>::get(Identifier id) ...@@ -416,7 +361,7 @@ data_array<T, Identifier>::get(Identifier id)
} }
template<typename T, typename Identifier> template<typename T, typename Identifier>
int Identifier
data_array<T, Identifier>::get_id(T& t) data_array<T, Identifier>::get_id(T& t)
{ {
using type = data_array<T, Identifier>::item; using type = data_array<T, Identifier>::item;
...@@ -443,12 +388,12 @@ bool ...@@ -443,12 +388,12 @@ bool
data_array<T, Identifier>::next(T*& t) data_array<T, Identifier>::next(T*& t)
{ {
if (t) { if (t) {
int id = get_id(*t); auto id = get_id(*t);
int index = get_index(id); int index = get_index(id);
++index; ++index;
for (; index < max_used; ++index) { for (; index < max_used; ++index) {
if (is_valid(items[index].id)) { if (valid(items[index].id)) {
t = &items[index].item; t = &items[index].item;
return true; return true;
} }
...@@ -458,90 +403,6 @@ data_array<T, Identifier>::next(T*& t) ...@@ -458,90 +403,6 @@ data_array<T, Identifier>::next(T*& t)
return false; return false;
} }
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::iterator
data_array<T, Identifier>::begin() noexcept
{
return items;
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::const_iterator
data_array<T, Identifier>::begin() const noexcept
{
return items;
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::const_iterator
data_array<T, Identifier>::cbegin() const noexcept
{
return items;
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::iterator
data_array<T, Identifier>::end() noexcept
{
return items + max_used;
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::const_iterator
data_array<T, Identifier>::end() const noexcept
{
return items + max_used;
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::const_iterator
data_array<T, Identifier>::cend() const noexcept
{
return items + max_used;
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::reverse_iterator
data_array<T, Identifier>::rbegin() noexcept
{
return reverse_iterator(items + max_used);
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::const_reverse_iterator
data_array<T, Identifier>::rbegin() const noexcept
{
return const_reverse_iterator(items + max_used);
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::const_reverse_iterator
data_array<T, Identifier>::crbegin() const noexcept
{
return const_reverse_iterator(items + max_used);
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::reverse_iterator
data_array<T, Identifier>::rend() noexcept
{
return reverse_iterator(items);
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::const_reverse_iterator
data_array<T, Identifier>::rend() const noexcept
{
return const_reverse_iterator(items);
}
template<typename T, typename Identifier>
inline typename data_array<T, Identifier>::const_reverse_iterator
data_array<T, Identifier>::crend() const noexcept
{
return const_reverse_iterator(items);
}
template<typename T, typename Identifier> template<typename T, typename Identifier>
bool bool
data_array<T, Identifier>::full() const noexcept data_array<T, Identifier>::full() const noexcept
......
// 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))