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

snif3

parent f1a578b1
Pipeline #2187 failed with stage
in 40 seconds
/*
* This file is part of VLE, a framework for multi-modeling, simulation
* and analysis of complex dynamical systems.
* 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/>.
*/
// 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_DATAARRAY_HPP
#define ORG_VLEPROJECT_BITS_DATAARRAY_HPP
......@@ -39,37 +17,49 @@
namespace bits {
using ID = std::uint_least64_t;
using IDs = std::uint_least32_t;
using ID = std::uint64_t;
using IDs = std::uint32_t;
constexpr ID
constexpr int
get_index(ID id) noexcept
{
return static_cast<int>(id & 0x00000000ffffffff);
}
constexpr ID
constexpr unsigned
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>
constexpr T
constexpr unsigned
get_max_key() noexcept;
template<>
constexpr ID
constexpr unsigned
get_max_key<ID>() noexcept
{
return 0xffffffff00000000;
return static_cast<unsigned>(0xffffffff00000000 >> 32);
}
template<>
constexpr IDs
constexpr unsigned
get_max_key<IDs>() noexcept
{
return 0xffff0000;
return static_cast<unsigned>(0xffff0000 >> 16);
}
template<typename T>
......@@ -87,31 +77,14 @@ template<>
constexpr int
size<IDs>() noexcept
{
return INT16_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;
return UINT16_MAX;
}
template<typename Identifier>
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
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();
/** Allocate a vector of items (max 65536 items).
......@@ -160,21 +121,21 @@ struct data_array
/** Resets data members, (runs destructors* on outstanding items, *optional
*/
void clear();
/* alloc (memclear* and/or construct*, *optional) an item from
freeList or items[max_used++], sets id to (next_key++ << 16) | index */
T& alloc();
template <typename... Args>
template<typename... Args>
T& alloc(Args&&... args);
// puts entry on free list (uses id to store next)
void free(T&);
void free(Identifier id);
// accessor to the id part if Item
int get_id(T&);
Identifier get_id(T&);
T& get(Identifier id); // return item[id & 0xFFFF];
......@@ -196,30 +157,14 @@ struct data_array
*/
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;
item* items = nullptr; // items vector.
int max_size = 0; // total size
int max_used = 0; // highest index ever alloced
int capacity = 0; // num alloced items
int next_key = 1; // [1..2^16] (don't let == 0)
int free_head = -1; // index of first free entry
item* items = nullptr; // items vector.
int max_size = 0; // total size
int max_used = 0; // highest index ever alloced
int capacity = 0; // num alloced items
unsigned int next_key = 1; // [1..2^16] (don't let == 0)
int free_head = -1; // index of first free entry
};
template<typename T, typename Identifier>
......@@ -266,7 +211,7 @@ Do_clear(typename data_array<T, Identifier>::item* items,
std::false_type)
{
for (int i = 0; i != size; ++i) {
if (is_valid(items[i].id)) {
if (valid(items[i].id)) {
items[i].item.~T();
items[i].id = 0;
}
......@@ -308,7 +253,7 @@ data_array<T, Identifier>::alloc()
if (free_head >= 0) {
new_index = free_head;
if (is_valid(items[free_head].id))
if (valid(items[free_head].id))
free_head = -1;
else
free_head = get_index(items[free_head].id);
......@@ -316,7 +261,7 @@ data_array<T, Identifier>::alloc()
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>())
next_key = 1;
......@@ -328,15 +273,15 @@ data_array<T, Identifier>::alloc()
}
template<typename T, typename Identifier>
template <typename... Args>
template<typename... Args>
T&
data_array<T, Identifier>::alloc(Args&&... args)
{
int new_index;
if (free_head >= 0) {
new_index = free_head;
if (is_valid(items[free_head].id))
if (valid(items[free_head].id))
free_head = -1;
else
free_head = get_index(items[free_head].id);
......@@ -344,7 +289,7 @@ data_array<T, Identifier>::alloc(Args&&... args)
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>())
next_key = 1;
......@@ -352,7 +297,7 @@ data_array<T, Identifier>::alloc(Args&&... args)
++max_size;
return items[new_index].item;
return items[new_index].item;
}
template<typename T, typename Identifier>
......@@ -381,7 +326,7 @@ data_array<T, Identifier>::free(T& t)
assert(&items[index] == static_cast<void*>(&t));
assert(items[index].id == id);
assert(is_valid(id));
assert(valid(id));
Do_free<T, Identifier>(items[index].item, std::is_trivial<T>());
......@@ -398,7 +343,7 @@ data_array<T, Identifier>::free(Identifier id)
auto index = get_index(id);
assert(items[index].id == id);
assert(is_valid(id));
assert(valid(id));
Do_free<T, Identifier>(items[index].item, std::is_trivial<T>());
......@@ -416,7 +361,7 @@ data_array<T, Identifier>::get(Identifier id)
}
template<typename T, typename Identifier>
int
Identifier
data_array<T, Identifier>::get_id(T& t)
{
using type = data_array<T, Identifier>::item;
......@@ -443,12 +388,12 @@ bool
data_array<T, Identifier>::next(T*& t)
{
if (t) {
int id = get_id(*t);
auto id = get_id(*t);
int index = get_index(id);
++index;
for (; index < max_used; ++index) {
if (is_valid(items[index].id)) {
if (valid(items[index].id)) {
t = &items[index].item;
return true;
}
......@@ -458,90 +403,6 @@ data_array<T, Identifier>::next(T*& t)
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>
bool
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))
head = pop_front(head);
return 0u;
}
};
} // bits
#endif
template<typename T, typename Identifier>
class flat_list_iterator
{
flat_list<T, Identifier>& list;
Identifier current = 0;
public:
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
flat_list_iterator(flat_list<T, Identifier>& list_ )
: list(list_)
, current(0)
{}
flat_list_iterator(flat_list<T, Identifier>& list_, Identifier current_)
: list(list_)
, current(current_)
{}
flat_list_iterator operator++(int)
{
flat_list_iterator copy(*this);
auto& t = list.get(current);
copy.current = t.next;
return copy;
}
flat_list_iterator& operator++()
{
auto& t = list.get(current);
current = t.next;
returh *this;
}
T operator*() const
{
return list.get(current);
}
friend bool operator==(const flat_list_iterator& lhs, const flat_list_iterator& rhs)
{
return &lhs.list == &rhs.list && lhs.current == rhs.current;
}
friend bool operator!=(const flat_list_iterator& lhs, const flat_list_iterator& rhs)
{
return !(lhs == rhs.m_entry);
}
// friend bool operator<(const flat_list_iterator& lhs, const flat_list_iterator& rhs)
// {
// return lhs.m_entry < rhs.m_entry;
// }
};
template<typename T, typename Identifier>
struct flat_list
{
struct item
{
T id;
Identifier next;
};
Identifier head = 0;
flat_list() = default;
~flat_list() = default;
Identifier append(data_array<item, Identifier>& items, T id)
{
auto& t = item.alloc();
t.id = id;
t.next = head ? head : 0;
return get_id(t);
}
void clear(data_array<item, Identifier>& items)
{
while (head) {
auto to_delete = head;
auto& t = items.get(head);
head = t.next;
items.free(to_delete);
}
}
};
......@@ -20,9 +20,11 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <bits/array.hpp>