Interface Documentation
Version: invalid
bit_buffer.hh
Go to the documentation of this file.
1 /*
2  @@@@@@@@ @@ @@@@@@ @@@@@@@@ @@
3  /@@///// /@@ @@////@@ @@////// /@@
4  /@@ /@@ @@@@@ @@ // /@@ /@@
5  /@@@@@@@ /@@ @@///@@/@@ /@@@@@@@@@/@@
6  /@@//// /@@/@@@@@@@/@@ ////////@@/@@
7  /@@ /@@/@@//// //@@ @@ /@@/@@
8  /@@ @@@//@@@@@@ //@@@@@@ @@@@@@@@ /@@
9  // /// ////// ////// //////// //
10 
11  Copyright (c) 2016, Triad National Security, LLC
12  All rights reserved.
13  */
14 #pragma once
15 
18 #include <bitset>
19 #include <cassert>
20 #include <cstddef>
21 #include <cstdint>
22 #include <iostream>
23 
24 namespace flecsi {
25 namespace util {
26 
37 template<typename T, size_t BITS_PER_INDEX>
39 {
40 public:
41  static constexpr size_t word_bits = sizeof(T) * 8;
42 
43  static_assert(BITS_PER_INDEX <= word_bits, "invalid bit buffer params");
44 
46  {
47  public:
48  range_proxy(bit_buffer & b, size_t index, size_t bit_start, size_t bit_end)
49  : b_(b), index_(index), bit_start_(bit_start), bit_end_(bit_end) {}
50 
51  range_proxy & operator=(const T & value) {
52  b_.set_(index_, bit_start_, bit_end_, value);
53  return *this;
54  }
55 
56  operator T() {
57  return b_.get_(index_, bit_start_, bit_end_);
58  }
59 
60  private:
61  bit_buffer & b_;
62  size_t index_;
63  size_t bit_start_;
64  size_t bit_end_;
65  };
66 
67  class proxy
68  {
69  public:
70  proxy(bit_buffer & b, size_t index, size_t bit)
71  : b_(b), index_(index), bit_(bit) {}
72 
73  proxy & operator=(const T & value) {
74  b_.set_(index_, bit_, value);
75  return *this;
76  }
77 
78  operator T() {
79  return b_.get_(index_, bit_);
80  }
81 
82  private:
83  bit_buffer & b_;
84  size_t index_;
85  size_t bit_;
86  };
87 
88  bit_buffer(uint8_t * buffer) : buffer_(buffer) {}
89 
90  proxy operator()(size_t index, ) {
91  return proxy(*this, index, 0);
92  }
93 
94  proxy operator()(size_t index, size_t bit) {
95  return proxy(*this, index, bit);
96  }
97 
98  range_proxy operator()(size_t index, size_t bit_start, size_t bit_end) {
99  assert(
100  bit_start <= bit_end && bit_start < BITS_PER_INDEX && "invalid index");
101 
102  return range_proxy(*this, index, bit_start, bit_end);
103  }
104 
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;
109 
110  if(i1 == i2) {
111  size_t r = (s + bit_start) % word_bits;
112 
113  T * const v = buffer_ + i1;
114  *v &= ~(((1 << (bit_end - bit_start + 1)) - 1) << r);
115  *v |= (value << r);
116  }
117  else {
118  size_t r1 = (s + bit_start) % word_bits;
119  size_t r2 = word_bits - r1 - 1;
120 
121  T * const v1 = buffer_ + i1;
122  *v1 &= ~(((1 << word_bits - r1) - 1) << r1);
123  *v1 |= (value << r1);
124 
125  T * const v2 = buffer_ + i2;
126  *v2 &= ~((1 << r2) - 1);
127  *v2 |= (value >> (word_bits - r1));
128  }
129  }
130 
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;
135 
136  T * const v = buffer_ + i;
137  *v &= ~(((1 << (bit + 1)) - 1) << r);
138  *v |= (value << r);
139  }
140 
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;
145 
146  if(i1 == i2) {
147  size_t r = (s + bit_start) % word_bits;
148 
149  T * const v = buffer_ + i1;
150  return (*v >> r) & ((1 << (bit_end - bit_start + 1)) - 1);
151  }
152  else {
153  size_t r1 = (s + bit_start) % word_bits;
154  size_t r2 = bit_end - bit_start - (word_bits - r1) + 1;
155 
156  T * const v1 = buffer_ + i1;
157  T * const v2 = buffer_ + i2;
158 
159  return ((*v1 >> r1) & ((1 << word_bits - r1) - 1)) |
160  ((*v2 & ((1 << r2) - 1)) << (word_bits - r1));
161  }
162  }
163 
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;
168 
169  T * const v = buffer_ + i;
170  return (*v >> r) & ((1 << (bit + 1)) - 1);
171  }
172 
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;
176  }
177  }
178 
179 private:
180  T * buffer_;
181 };
182 
183 } // namespace util
184 } // namespace flecsi
Definition: bit_buffer.hh:38
Definition: bit_buffer.hh:67
Definition: bit_buffer.hh:45
Definition: control.hh:31