diff options
author | Jan Huwald <jh@sotun.de> | 2013-06-04 09:40:43 (GMT) |
---|---|---|
committer | Jan Huwald <jh@sotun.de> | 2013-06-04 09:40:43 (GMT) |
commit | f6e02882fb9899eca36d389ee55fdaf0ec5cc5b3 (patch) | |
tree | 95d6d0e83083194e72e141f3fe3cbcd441cc74e7 /packed_array.hpp | |
parent | f06c74f26a3e3b9b6225c70fda283a97b0494919 (diff) |
go to 64-bit State, use bit-packed array
Diffstat (limited to 'packed_array.hpp')
-rw-r--r-- | packed_array.hpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/packed_array.hpp b/packed_array.hpp new file mode 100644 index 0000000..9fb2c59 --- /dev/null +++ b/packed_array.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include <inttypes.h> +#include <sys/types.h> + +template<typename T> struct bit_size; + +template<typename T, size_t count, size_t bit_sz = bit_size<T>::size> +struct packed_array { + typedef packed_array<T, count, bit_sz> packed_array_t; + typedef uint64_t word_t; + const size_t word_sz = 8 * sizeof(word_t); + uint8_t data[(count * bit_sz + 7) / 8]; + + /// element access + + struct element { + element(word_t *base, uint shift) : base(base), shift(shift) {} + + T operator= (T val) { + word_t mask = ~(((((word_t) 1) << bit_sz) - 1) << shift); + *base &= mask; + *base ^= val << shift; + return val; + } + + operator T() { + word_t mask = (((((word_t) 1) << bit_sz) - 1) << shift); + return static_cast<T>((*base & mask) >> shift); + } + + T operator() () { + return (T) (*this); + } + + word_t *base; + uint shift; + }; + + element operator[] (size_t i) { + size_t bit_addr = i * bit_sz; + return element((word_t*) (data + (bit_addr / 8)), + bit_addr % 8); + } + + /// simple iteration (for for-all loops) + + struct iterator { + packed_array_t &a; + size_t i; + + iterator(packed_array_t &a, size_t i) : a(a), i(i) {} + iterator& operator++() { ++i; return *this; } + element operator*() { return a[i]; } + bool operator != (iterator &o) { return (i != o.i) && (&a != &(o.a)); } + }; + + iterator begin() { return iterator(*this, 0); } + iterator end() { return iterator(*this, count); } +}; |