37 template<
typename T,
size_t BITS_PER_INDEX>
41 static constexpr
size_t word_bits =
sizeof(T) * 8;
43 static_assert(BITS_PER_INDEX <= word_bits,
"invalid bit buffer params");
49 : b_(b), index_(index), bit_start_(bit_start), bit_end_(bit_end) {}
52 b_.set_(index_, bit_start_, bit_end_, value);
57 return b_.get_(index_, bit_start_, bit_end_);
71 : b_(b), index_(index), bit_(bit) {}
73 proxy & operator=(
const T & value) {
74 b_.set_(index_, bit_, value);
79 return b_.get_(index_, bit_);
88 bit_buffer(uint8_t * buffer) : buffer_(buffer) {}
90 proxy operator()(
size_t index, ) {
91 return proxy(*
this, index, 0);
94 proxy operator()(
size_t index,
size_t bit) {
95 return proxy(*
this, index, bit);
98 range_proxy operator()(
size_t index,
size_t bit_start,
size_t bit_end) {
100 bit_start <= bit_end && bit_start < BITS_PER_INDEX &&
"invalid index");
102 return range_proxy(*
this, index, bit_start, bit_end);
105 void set_(
size_t index,
size_t bit_start,
size_t bit_end, T value) {
106 size_t s = index * BITS_PER_INDEX;
107 size_t i1 = (s + bit_start) / word_bits;
108 size_t i2 = (s + bit_end) / word_bits;
111 size_t r = (s + bit_start) % word_bits;
113 T *
const v = buffer_ + i1;
114 *v &= ~(((1 << (bit_end - bit_start + 1)) - 1) << r);
118 size_t r1 = (s + bit_start) % word_bits;
119 size_t r2 = word_bits - r1 - 1;
121 T *
const v1 = buffer_ + i1;
122 *v1 &= ~(((1 << word_bits - r1) - 1) << r1);
123 *v1 |= (value << r1);
125 T *
const v2 = buffer_ + i2;
126 *v2 &= ~((1 << r2) - 1);
127 *v2 |= (value >> (word_bits - r1));
131 void set_(
size_t index,
size_t bit, T value) {
132 size_t s = index * BITS_PER_INDEX + bit;
133 size_t i = s / word_bits;
134 size_t r = s % word_bits;
136 T *
const v = buffer_ + i;
137 *v &= ~(((1 << (bit + 1)) - 1) << r);
141 T get_(
size_t index,
size_t bit_start,
size_t bit_end) {
142 size_t s = index * BITS_PER_INDEX;
143 size_t i1 = (s + bit_start) / word_bits;
144 size_t i2 = (s + bit_end) / word_bits;
147 size_t r = (s + bit_start) % word_bits;
149 T *
const v = buffer_ + i1;
150 return (*v >> r) & ((1 << (bit_end - bit_start + 1)) - 1);
153 size_t r1 = (s + bit_start) % word_bits;
154 size_t r2 = bit_end - bit_start - (word_bits - r1) + 1;
156 T *
const v1 = buffer_ + i1;
157 T *
const v2 = buffer_ + i2;
159 return ((*v1 >> r1) & ((1 << word_bits - r1) - 1)) |
160 ((*v2 & ((1 << r2) - 1)) << (word_bits - r1));
164 T get_(
size_t index,
size_t bit) {
165 size_t s = index * BITS_PER_INDEX + bit;
166 size_t i = s / word_bits;
167 size_t r = s % word_bits;
169 T *
const v = buffer_ + i;
170 return (*v >> r) & ((1 << (bit + 1)) - 1);
173 void dump(
size_t size) {
174 for(
size_t i = 0; i < size; ++i) {
175 std::cout << i <<
": " << std::bitset<word_bits>(buffer_[i]) << std::endl;
Definition: bit_buffer.hh:38
Definition: bit_buffer.hh:67
Definition: bit_buffer.hh:45
Definition: control.hh:31