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
b605f021
Commit
b605f021
authored
Apr 04, 2019
by
Gauthier Quesnel
Browse files
next11
parent
b71a75ac
Pipeline
#2304
failed with stage
in 1 minute
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
include/bits/data-array.hpp
View file @
b605f021
...
...
@@ -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
>
...
...
include/bits/linker.hpp
View file @
b605f021
...
...
@@ -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
(
&
l
is
t
,
array
,
index
);
auto
index
=
bits
::
get_index
(
head
);
return
iterator
(
th
is
,
array
,
index
);
}
template
<
typename
DataArray
>
auto
end
(
DataArray
*
array
)
noexcept
{
return
multi_linker_
iterator
(
&
l
is
t
,
array
,
-
1
);
return
iterator
(
th
is
,
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
];
...
...
test/array.cpp
View file @
b605f021
...
...
@@ -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
...
...
test/vpz.cpp
View file @
b605f021
...
...
@@ -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;