91template <
typename T,
int BaseOffset,
int BitsPerItem,
int NumItems>
class BitFieldArray {
95 static_assert(BaseOffset + BitsPerItem * NumItems <= (int)
sizeof(T) * 8,
"Array exceeds bitfield boundaries");
96 static_assert(BitsPerItem < (int)
sizeof(T) * 8,
"Can't fill entire bitfield with one array element");
98 static const T Maximum = (T(1) << BitsPerItem) - 1;
99 T maximum()
const {
return Maximum; }
100 int numItems()
const {
return NumItems; }
108 Element(T& value,
int offset)
111 T mask()
const {
return Maximum << offset; }
113 operator T()
const {
return (value >> offset) & Maximum; }
115 Element& operator=(T v) {
116 assert(v <= Maximum);
117 value = (value & ~mask()) | (v << offset);
121 Element& operator+=(T v) {
122 assert(T(*
this) + v <= Maximum);
123 value += v << offset;
127 Element& operator-=(T v) {
128 assert(T(*
this) >= v);
129 value -= v << offset;
133 Element& operator++() {
return *
this += 1; }
134 Element operator++(
int) {
139 Element& operator--() {
return *
this -= 1; }
140 Element operator--(
int) {
148 assert(i >= 0 && i < NumItems);
149 return Element(value, BaseOffset + BitsPerItem * i);
152 const Element operator[](
int i)
const {
153 assert(i >= 0 && i < NumItems);
154 return Element(value, BaseOffset + BitsPerItem * i);