Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Gauthier Quesnel
bits
Commits
3910cd13
Commit
3910cd13
authored
Mar 30, 2019
by
Gauthier Quesnel
Browse files
next5
parent
a9ce09ba
Pipeline
#2218
failed with stage
in 1 minute and 10 seconds
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
include/bits/allocator.hpp
0 → 100644
View file @
3910cd13
// 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_ALLOCATOR_HPP
#define ORG_VLEPROJECT_BITS_ALLOCATOR_HPP
#include <memory>
#include <cstdint>
namespace
bits
{
template
<
class
T
,
std
::
size_t
capacity
=
1024
>
class
fixed_memory_allocator
{
union
block
{
block
*
next
;
typename
std
::
aligned_storage
<
sizeof
(
T
),
alignof
(
T
)
>::
type
storage
;
};
class
buffer
{
static
constexpr
std
::
size_t
block_size
=
sizeof
(
T
)
>
sizeof
(
block
)
?
sizeof
(
T
)
:
sizeof
(
block
);
std
::
uint8_t
data
[
block_size
*
capacity
];
};
buffer
data
;
int
free_head
=
-
1
;
int
size
=
0
;
public:
fixed_memory_allocator
()
=
default
;
fixed_memory_allocator
(
fixed_memory_allocator
&&
)
=
delete
;
fixed_memory_allocator
(
const
fixed_memory_allocator
&
)
=
delete
;
fixed_memory_allocator
operator
=
(
fixed_memory_allocator
&&
)
=
delete
;
fixed_memory_allocator
operator
=
(
const
fixed_memory_allocator
&
)
=
delete
;
~
fixed_memory_allocator
()
=
default
;
T
*
allocate
()
{
if
(
size
>=
capacity
)
throw
std
::
bad_alloc
();
block
*
new_alloc
;
if
(
free_head
>=
0
)
{
new_alloc
=
free_head
;
free_head
=
data
[
free_head
]
->
next
;
}
else
new_alloc
=
reinterpret_cast
<
block
*>
(
&
data
[
size
++
]);
return
reinterpret_cast
<
T
*>
(
new_alloc
);
}
void
deallocate
(
T
*
pointer
)
noexcept
{
block
*
blk
=
reinterpret_cast
<
block
*>
(
pointer
);
blk
->
next
=
free_head
;
free_head
=
blk
;
}
};
template
<
class
T
,
std
::
size_t
capacity
=
1024
>
class
block_memory_allocator
{
union
block
{
block
*
next
;
typename
std
::
aligned_storage
<
sizeof
(
T
),
alignof
(
T
)
>::
type
storage
;
};
class
buffer
{
static
constexpr
std
::
size_t
block_size
=
sizeof
(
T
)
>
sizeof
(
block
)
?
sizeof
(
T
)
:
sizeof
(
block
);
std
::
uint8_t
data
[
block_size
*
capacity
];
public:
const
buffer
*
next
;
buffer
(
buffer
*
next_
)
noexcept
:
next
(
next_
)
{}
T
*
get_block
(
int
index
)
noexcept
{
return
reinterpret_cast
<
T
*>
(
&
data
[
block_size
*
index
]);
}
};
block
*
free_head
=
nullptr
;
buffer
*
first_buffer
=
nullptr
;
std
::
size_t
size
=
capacity
;
public:
block_memory_allocator
()
noexcept
=
default
;
block_memory_allocator
(
const
block_memory_allocator
&
)
noexcept
=
default
;
block_memory_allocator
&
operator
=
(
const
block_memory_allocator
&
)
noexcept
=
default
;
block_memory_allocator
(
block_memory_allocator
&&
other
)
noexcept
:
free_head
(
other
.
free_head
)
,
first_buffer
(
other
.
first_buffer
)
,
size
(
other
.
size
)
{
other
.
free_head
=
nullptr
;
other
.
first_buffer
=
nullptr
;
other
.
size
=
{
0
};
}
block_memory_allocator
&
operator
=
(
block_memory_allocator
&&
other
)
noexcept
{
if
(
this
!=
&
other
)
{
while
(
first_buffer
)
{
auto
*
buffer
=
first_buffer
;
first_buffer
=
buffer
->
next
;
delete
buffer
;
}
free_head
=
other
.
free_head
;
first_buffer
=
other
.
first_buffer
;
size
=
other
.
size
;
other
.
free_head
=
nullptr
;
other
.
first_buffer
=
nullptr
;
other
.
size
=
{
0
};
}
return
*
this
;
}
~
block_memory_allocator
()
noexcept
{
while
(
first_buffer
)
{
auto
*
buffer
=
first_buffer
;
first_buffer
=
buffer
->
next
;
delete
buffer
;
}
}
T
*
allocate
()
{
if
(
free_head
)
{
block
*
block
=
free_head
;
free_head
=
block
->
next
;
return
reinterpret_cast
<
T
*>
(
block
);
}
if
(
size
>=
capacity
)
{
first_buffer
=
new
buffer
(
first_buffer
);
size
=
0
;
}
return
first_buffer
->
getBlock
(
size
++
);
}
void
deallocate
(
T
*
pointer
)
noexcept
{
block
*
blk
=
reinterpret_cast
<
block
*>
(
pointer
);
blk
->
next
=
free_head
;
free_head
=
blk
;
}
};
template
<
class
T
,
std
::
size_t
capacity
=
1024
>
class
fixed_node_allocator
:
private
fixed_memory_allocator
<
T
,
capacity
>
{
public:
using
value_type
=
T
;
using
size_type
=
std
::
size_t
;
using
propagate_on_container_move_assignment
=
std
::
true_type
;
using
difference_type
=
std
::
ptrdiff_t
;
T
*
allocate
(
size_type
n
,
const
void
*
hint
=
0
)
{
if
(
n
!=
1
||
hint
)
throw
std
::
bad_alloc
();
return
fixed_node_allocator
<
T
,
capacity
>::
allocate
();
}
void
deallocate
(
T
*
p
,
size_type
n
)
{
fixed_node_allocator
<
T
,
capacity
>::
deallocate
(
p
);
}
void
construct
(
T
*
p
,
const
T
&
val
)
{
new
(
p
)
T
(
val
);
}
void
destroy
(
T
*
p
)
{
p
->~
T
();
}
};
template
<
class
T
,
std
::
size_t
capacity
=
1024
>
class
block_node_allocator
:
private
block_memory_allocator
<
T
,
capacity
>
{
public:
using
value_type
=
T
;
using
size_type
=
std
::
size_t
;
using
propagate_on_container_move_assignment
=
std
::
true_type
;
using
difference_type
=
std
::
ptrdiff_t
;
T
*
allocate
(
size_type
n
,
const
void
*
hint
=
0
)
{
if
(
n
!=
1
||
hint
)
throw
std
::
bad_alloc
();
return
block_node_allocator
<
T
,
capacity
>::
allocate
();
}
void
deallocate
(
T
*
p
,
size_type
n
)
{
block_node_allocator
<
T
,
capacity
>::
deallocate
(
p
);
}
void
construct
(
T
*
p
,
const
T
&
val
)
{
new
(
p
)
T
(
val
);
}
void
destroy
(
T
*
p
)
{
p
->~
T
();
}
};
}
// bits
#endif // ORG_VLEPROJECT_BITS_ALLOCATOR_HPP
include/bits/list.hpp
View file @
3910cd13
...
...
@@ -5,19 +5,26 @@
#ifndef ORG_VLEPROJECT_BITS_TRIVIAL_LIST_HPP
#define ORG_VLEPROJECT_BITS_TRIVIAL_LIST_HPP
#include <bits/data-array.hpp>
#include <bits/allocator.hpp>
#include <cassert>
#include <forward_list>
#include <list>
namespace
bits
{
/* Maybe we can call it trivial_flat_forward_list ? */
template
<
typename
T
>
struct
flat_forward_list
{
using
accessor_type
=
int
;
struct
accessor_type
{
int
head
=
-
1
;
};
static_assert
(
std
::
is_trivial
<
T
>::
value
,
"flat_forward_list needs trivial type"
);
static_assert
(
std
::
is_trivial
<
T
>::
value
&&
std
::
is_standard_layout
<
T
>::
value
,
"flat_forward_list needs std::is_pod type"
);
struct
item
{
...
...
@@ -25,6 +32,78 @@ struct flat_forward_list
int
next
;
};
// class iterator
// {
// using iterator_category = std::forward_iterator_tag;
// using value_type = T;
// using difference_type = std::ptrdiff_t;
// using pointer = T*;
// using reference = T&;
// iterator(item* items_, int id_)
// : items(items_)
// , id(id_)
// {}
// iterator(const iterator&) = default;
// iterator(iterator&&) = default;
// iterator operator=(const iterator&) = default;
// iterator operator=(iterator&&) = default;
// iterator operator++(int)
// {
// if (id == -1)
// return iterator(items, -1);
// iterator copy(*this);
// id = items[id].next;
// return copy;
// }
// iterator& operator++()
// {
// if (id == -1)
// return iterator(items, -1);
// id = items[id].next;
// return *this;
// }
// const pointer operator->() const
// {
// return &items[id];
// }
// reference operator*() const
// {
// return items[id];
// }
// friend void swap(iterator& lhs, iterator& rhs)
// {
// 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)
// {
// return lhs.id == rhs.id;
// }
// friend bool operator!=(const iterator& lhs, const iterator& rhs)
// {
// return !(lhs.id == rhs.id);
// }
// item* items;
// int id;
// };
item
*
items
=
nullptr
;
int
size
=
0
;
int
free_head
=
-
1
;
...
...
@@ -51,6 +130,13 @@ struct flat_forward_list
items
=
new
item
[
capacity_
];
}
// iterator begin(int head) noexcept
// {
// return iterator(items, head);
// }
// iterator end()
[[
nodiscard
]]
int
alloc
()
noexcept
{
int
new_head
;
...
...
@@ -65,27 +151,28 @@ struct flat_forward_list
return
new_head
;
}
[[
nodiscard
]]
accessor_type
push_front
(
int
head
,
T
id
)
noexcept
[[
nodiscard
]]
accessor_type
push_front
(
accessor_type
list
,
T
id
)
noexcept
{
int
new_head
=
alloc
();
items
[
new_head
].
id
=
id
;
items
[
new_head
].
next
=
head
;
items
[
new_head
].
next
=
list
.
head
;
list
.
head
=
new_head
;
return
new_head
;
return
list
;
}
[[
nodiscard
]]
int
pop_front
(
int
head
)
noexcept
[[
nodiscard
]]
int
pop_front
(
accessor_type
list
)
noexcept
{
if
(
head
>=
0
)
{
int
old_head
=
head
;
head
=
items
[
head
].
next
;
if
(
list
.
head
>=
0
)
{
int
old_head
=
list
.
head
;
list
.
head
=
items
[
list
.
head
].
next
;
items
[
old_head
].
id
=
0u
;
items
[
old_head
].
next
=
free_head
;
free_head
=
old_head
;
}
return
head
;
return
list
;
}
void
erase_after
(
int
elem
)
noexcept
...
...
@@ -101,17 +188,18 @@ struct flat_forward_list
}
template
<
typename
Predicate
>
[[
nodiscard
]]
int
remove_if
(
int
head
,
Predicate
predicate
)
noexcept
[[
nodiscard
]]
int
remove_if
(
accessor_type
list
,
Predicate
predicate
)
noexcept
{
while
(
head
>=
0
&&
predicate
(
items
[
head
].
id
))
head
=
pop_front
(
head
);
while
(
list
.
head
>=
0
&&
predicate
(
items
[
list
.
head
].
id
))
list
.
head
=
pop_front
(
list
.
head
);
if
(
head
<
0
)
return
head
;
if
(
list
.
head
<
0
)
return
list
.
head
;
int
current
=
head
;
int
next
=
items
[
head
].
next
;
int
current
=
list
.
head
;
int
next
=
items
[
list
.
head
].
next
;
while
(
current
>=
0
&&
next
>=
0
)
{
if
(
predicate
(
items
[
next
].
id
))
{
...
...
@@ -122,29 +210,31 @@ struct flat_forward_list
};
}
return
head
;
return
list
;
}
[[
nodiscard
]]
int
clear
(
int
head
)
noexcept
[[
nodiscard
]]
int
clear
(
accessor_type
list
)
noexcept
{
while
(
head
>=
0
)
head
=
pop_front
(
head
);
while
(
list
.
head
>=
0
)
list
.
head
=
pop_front
(
list
.
head
);
return
-
1
;
return
list
;
}
};
template
<
typename
T
>
struct
flat_list
{
static_assert
(
std
::
is_trivial
<
T
>::
value
&&
std
::
is_standard_layout
<
T
>::
value
,
"flat_list needs trivial type"
);
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
;
...
...
@@ -152,6 +242,110 @@ struct flat_list
int
next
;
};
struct
iterator
{
using
iterator_category
=
std
::
forward_iterator_tag
;
using
value_type
=
T
;
using
difference_type
=
std
::
ptrdiff_t
;
using
pointer
=
T
*
;
using
reference
=
T
&
;
item
*
items
=
nullptr
;
accessor_type
list
;
iterator
(
flat_list
<
T
>&
self
,
int
pos
)
:
items
(
self
.
items_
)
,
list
(
list_
)
{}
iterator
()
=
default
;
iterator
(
const
iterator
&
)
=
default
;
iterator
(
iterator
&&
)
=
default
;
iterator
operator
=
(
const
iterator
&
)
=
default
;
iterator
operator
=
(
iterator
&&
)
=
default
;
void
forward
()
{
if
(
pos
>=
0
)
pos
=
items
[
pos
].
next
;
}
void
backward
()
{
if
(
pos
>=
0
)
pos
=
items
[
pos
].
previous
;
}
iterator
operator
++
(
int
)
{
if
(
pos
<
0
)
return
iterator
(
items
,
-
1
);
iterator
copy
(
*
this
);
forward
();
return
copy
;
}
iterator
&
operator
++
()
{
forward
();
return
*
this
;
}
iterator
operator
--
(
int
)
{
if
(
pos
<
0
)
return
iterator
(
items
,
-
1
);
iterator
copy
(
*
this
);
backward
();
return
copy
;
}
iterator
&
operator
--
()
{
backward
();
return
*
this
;
}
const
pointer
operator
->
()
const
{
return
&
items
[
pos
].
id
;
}
reference
operator
*
()
const
{
return
items
[
pos
].
id
;
}
friend
void
swap
(
iterator
&
lhs
,
iterator
&
rhs
)
{
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
)
{
return
lhs
.
id
==
rhs
.
id
;
}
friend
bool
operator
!=
(
const
iterator
&
lhs
,
const
iterator
&
rhs
)
{
return
!
(
lhs
.
id
==
rhs
.
id
);
}
};
item
*
items
=
nullptr
;
int
size
=
0
;
int
free_head
=
-
1
;
...
...
@@ -308,10 +502,10 @@ struct flat_list
return
list
;
while
(
list
.
head
>=
0
&&
predicate
(
items
[
list
.
head
].
id
))
list
=
pop_front
();
list
=
pop_front
(
list
);
while
(
list
.
tail
>=
0
&&
predicate
(
items
[
list
.
tail
].
id
))
list
=
pop_back
();
list
=
pop_back
(
list
);
for
(
int
current
=
list
.
head
;
current
!=
list
.
tail
;
current
=
items
[
current
].
next
)
{
...
...
include/bits/vector.hpp
deleted
100644 → 0
View file @
a9ce09ba
/*
* 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/>.
*/
#ifndef ORG_VLEPROJECT_BITS_VECTOR_HPP
#define ORG_VLEPROJECT_BITS_VECTOR_HPP
#include <memory>
#include <type_traits>
namespace
bits
{
template
<
typename
T
>
struct
vector
{
static_assert
(
std
::
is_trivial
<
T
>
()
==
true
);
// using this_type = vector<T>;
// using value_type = T;