1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#ifndef IuE4Lmq81ZDeAq0u7S79e56kZZQ
#define IuE4Lmq81ZDeAq0u7S79e56kZZQ
#include <inttypes.h>
#include <assert.h>
#include <boost/static_assert.hpp>
#include "bit_access.hpp"
#include "template_helpers.hpp"
// size - number of elements
// width - size of each elements (in bit!)
template<typename T, uint32_t size, size_t width = 8 * sizeof(T)>
class Array {
public:
typedef uint32_t ptr_t;
// reader and writer
inline T get(ptr_t id);
inline void set(ptr_t id, T value);
// allow accessing raw memory (this also encodes the correct size of the object)
uint8_t mem[ size * ((width + 7) / 8) ];
// garantuee that all sizes = 2^n
STATIC_ASSERT_IS_POWER_OF_TWO(width);
STATIC_ASSERT_IS_POWER_OF_TWO(size);
// garantue that we do not need bit-level access of the underlying container
BOOST_STATIC_ASSERT((uint64_t) width * size >= 8);
};
template<typename T, uint32_t size, size_t width>
inline T Array<T, size, width>::get(ptr_t id) {
assert(id < size);
if (width < 8) {
uint8_t res = bit_extract(mem, (uint8_t) width, id);
return FORCE_CONV(T, res);
}else{
return *((T*) (((char*) mem) + (width / 8) * id)); // TO CHECK: improve cast?
}
}
template<typename T, uint32_t size, size_t width>
inline void Array<T, size, width>::set(ptr_t id, T value) {
assert(id < size);
if (width < 8) {
bit_insert(mem, (uint8_t) width, id, value);
}else{
*((T*) (((char*) mem) + (width / 8) * id)) = value;
}
}
#endif // IuE4Lmq81ZDeAq0u7S79e56kZZQ
|