summaryrefslogtreecommitdiff
path: root/core/array.hpp
blob: e882f92ef5e2f137a1583bf5cf25697c5bd521c9 (plain)
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
contact: Jan Huwald // Impressum