CMS 3D CMS Logo

BitArray.h
Go to the documentation of this file.
1 //-------------------------------------------------
2 //
3 // Class: BitArray
4 //
5 // Description: Manipulates arrays of bits
6 //
7 //
8 // Author List:
9 // C. Grandi
10 // Modifications:
11 //
12 //
13 //--------------------------------------------------
14 #ifndef BIT_ARRAY_H_
15 #define BIT_ARRAY_H_
16 
17 //---------------
18 // C++ Headers --
19 //---------------
20 #include <cassert>
21 #include <iostream>
22 
23 // ---------------------
24 // -- Class Interface --
25 // ---------------------
26 
27 template <int N>
28 class BitArray {
29 public:
30  class refToBit;
31  friend class refToBit;
32 
33  // reference to bit class
34  class refToBit {
35  friend class BitArray;
36 
37  //refToBit();
38 
39  public:
40  refToBit() {}
42  _word = &b.getWord(pos);
44  }
45  ~refToBit() {}
46 
47  refToBit& operator=(const int val) {
48  if (val) {
49  *_word |= getPosMask(_pos);
50  } else {
51  *_word &= ~(getPosMask(_pos));
52  }
53  return *this;
54  }
55 
56  refToBit& operator=(const refToBit& rtb) {
57  if ((*(rtb._word) & getPosMask(rtb._pos))) {
58  *_word |= getPosMask(_pos);
59  } else {
60  *_word &= ~getPosMask(_pos);
61  }
62  return *this;
63  }
64 
65  int operator~() const { return ((*_word) & getPosMask(_pos)) == 0; }
66 
67  operator int() const { return ((*_word) & getPosMask(_pos)) != 0; }
68 
70  *_word ^= getPosMask(_pos);
71  return *this;
72  }
73 
74  private:
75  unsigned* _word;
76  int _pos;
77  };
78 
79  BitArray() { this->zero(); }
80 
82  for (int i = 0; i < this->nWords(); i++) {
83  _data[i] = br._data[i];
84  }
85  this->cleanUnused();
86  }
87  BitArray(const char* str) {
88  this->zero();
89  this->assign(0, this->nBits(), str);
90  this->cleanUnused();
91  }
92  BitArray(const char* str, const int p, const int n) {
93  this->zero();
94  this->assign(p, n, str);
95  }
96  BitArray(const unsigned i) {
97  this->zero();
98  _data[0] = i; // the nBit least sign. bits are considered
99  this->cleanUnused();
100  }
101  /*
102  BitArray(const unsigned long i) {
103  this->zero();
104  unsigned j = i&static_cast<unsigned long>(0xffffffff);
105  _data[0] = j; // the nBit least sign. bits are considered
106  if(this->nBits()>32) {
107  j=i>>32;
108  _data[1] = j;
109  }
110  this->cleanUnused();
111  }
112 */
113  // Destructor
114  // ~BitArray() {}
115 
116  // Return number of bits
117  inline int nBits() const { return N; }
118  inline int size() const { return this->nBits(); }
119 
120  // Return number of words
121  inline int nWords() const { return N / 32 + 1; }
122 
123  // Return a data word
124  unsigned dataWord(const int i) const {
125  assert(i >= 0 && i < this->nWords());
126  return _data[i];
127  }
128  unsigned& dataWord(const int i) {
129  assert(i >= 0 && i < this->nWords());
130  return _data[i];
131  }
132 
133  // Return the dataword which contains bit in position
134  unsigned& getWord(const int pos) {
135  assert(pos >= 0 && pos < this->nBits());
136  return _data[pos / 32];
137  }
138  unsigned getWord(const int pos) const {
139  assert(pos >= 0 && pos < this->nBits());
140  return _data[pos / 32];
141  }
142 
143  // Return the position inside a word given the position in bitArray
144  static int getPosInWord(const int pos) {
145  // assert(pos>=0&& pos<this->nBits());
146  return pos % 32;
147  }
148 
149  // Return the word mask for a given bit
150  static unsigned getPosMask(const int pos) { return static_cast<unsigned>(1) << getPosInWord(pos); }
151 
152  // how many bits are not used (most significative bits of last word)
153  int unusedBits() const {
154  if (this->nBits() == 0)
155  return 32;
156  return 31 - ((this->nBits() - 1) % 32);
157  }
158 
159  // mask to get rid of last word unused bits
160  unsigned lastWordMask() const { return static_cast<unsigned>(0xffffffff) >> (this->unusedBits()); }
161 
162  // set unused bits to 0
163  void cleanUnused() { _data[this->nWords() - 1] &= (this->lastWordMask()); }
164 
165  // count non 0 bits
166  int count() const {
167  int n = 0;
168  for (int i = 0; i < this->nBits(); i++) {
169  if (this->element(i))
170  n++;
171  }
172  return n;
173  }
174 
175  // true if any bit == 1
176  int any() {
177  int nw = this->nWords();
178  int ub = unusedBits();
179  if (this->dataWord(nw - 1) << ub != 0)
180  return 1;
181  if (nw > 1) {
182  for (int iw = 0; iw < nw - 1; iw++) {
183  if (this->dataWord(iw) != 0)
184  return 1;
185  }
186  }
187  return 0;
188  }
189 
190  // true if any bit == 0
191  int none() {
192  int nw = this->nWords();
193  int ub = unusedBits();
194  if (this->dataWord(nw - 1) << ub != 0xffffffff)
195  return 1;
196  if (nw > 1) {
197  for (int iw = 0; iw < nw - 1; iw++) {
198  if (this->dataWord(iw) != 0xffffffff)
199  return 1;
200  }
201  }
202  return 0;
203  }
204 
205  // Return i^th elemnet
206  int element(const int pos) const { return (getWord(pos) & getPosMask(pos)) != static_cast<unsigned>(0); }
207  inline int test(const int i) const { return element(i); }
208 
209  // Set/unset all elements
210  void zero() {
211  for (int i = 0; i < this->nWords(); i++) {
212  _data[i] = 0x0; // set to 0
213  }
214  }
215  inline void reset() { zero(); }
216 
217  void one() {
218  for (int i = 0; i < this->nWords(); i++) {
219  _data[i] = 0xffffffff; // set to 1
220  }
221  }
222 
223  // Set/unset i^th element
224  void set(const int i) { getWord(i) |= getPosMask(i); }
225  void unset(const int i) { getWord(i) &= ~getPosMask(i); }
226  inline void reset(const int i) { this->unset(i); }
227 
228  // Set the i^th element to a given value
229  inline void set(const int i, const int val) { this->assign(i, 1, val); }
230  inline void set(const int i, const char* str) { this->assign(i, 1, str); }
231 
232  // Set/unset many bits to a given integer/bitArray/string
233  void assign(const int p, const int n, const int val) {
234  assert(p >= 0 && p + n <= this->nBits());
235  // only the n least significant bits of val are considered
236  for (int i = 0; i < n; i++) {
237  if (val >> i & 1) {
238  this->set(p + i);
239  } else {
240  this->unset(p + i);
241  }
242  }
243  }
244  void assign(const int p, const int n, const BitArray<N>& val) {
245  assert(p >= 0 && p + n <= this->nBits());
246  // only the n least significant bits of val are considered
247  for (int i = 0; i < n; i++) {
248  if (val.element(i)) {
249  this->set(p + i);
250  } else {
251  this->unset(p + i);
252  }
253  }
254  }
255  void assign(const int p, const int n, const char* str) {
256  assert(p >= 0 && p + n <= this->nBits());
257  // only the n least significant bits of val are considered
258  for (int i = 0; i < n; i++) {
259  assert(str[i] == '1' || str[i] == '0');
260  if (str[i] == '1') {
261  this->set(p + n - i - 1); // reading a string from left to right
262  } else { // --> most significative bit is the one
263  this->unset(p + n - i - 1); // with lower string index
264  }
265  }
266  }
267 
268  // Read a given range in an unsigned integer
269  unsigned read(const int p, const int n) const {
270  assert(p >= 0 && p + n <= this->nBits());
271  assert(n <= 32); // the output must fit in a 32 bit word
272  // only the n least significant bits of val are considered
273  unsigned out = 0x0;
274  for (int i = 0; i < n; i++) {
275  if (this->test(p + i))
276  out |= 1 << i;
277  }
278  return out;
279  }
280 
281  // Read BitArray in bytes. Returns a BitArray<8>
282  BitArray<8> byte(const int i) const {
284  if (i >= 0 && i < 4 * this->nWords()) {
285  unsigned k = (_data[i / 4] >> 8 * (i % 4)) & 0xff;
286  out = k;
287  }
288  return out;
289  }
290  // Assignment
292  if (this != &a) {
293  for (int i = 0; i < this->nWords(); i++) {
294  _data[i] = a._data[i];
295  }
296  }
297  this->cleanUnused();
298  return *this;
299  }
300 
301  // Conversion from unsigned
302  BitArray<N>& operator=(const unsigned i) {
303  this->zero();
304  _data[0] = i; // the nBit least sign. bits are considered
305  this->cleanUnused();
306  return *this;
307  }
308  /*
309  // Conversion from unsigned long
310  BitArray<N>& operator=(const unsigned long i) {
311  this->zero();
312  unsigned j = i&0xffffffff;
313  _data[0] = j; // the nBit least sign. bits are considered
314  if(this->nBits()>32) {
315  j=i>>32;
316  _data[1] = j;
317  }
318  this->cleanUnused();
319  return *this;
320  }
321 */
322  // Conversion from char
323  BitArray<N>& operator=(const char* str) {
324  this->zero();
325  for (int i = 0; i < this->nBits(); i++) {
326  assert(str[i] == '1' || str[i] == '0');
327  if (str[i] == '1') {
328  this->set(this->nBits() - i - 1); // reading a string from left to right
329  } else if (str[i] == '0') { // --> most significative bit is the one
330  this->unset(this->nBits() - i - 1); // with lower string index
331  } else {
332  break; // exit when find a char which is not 0 or 1
333  }
334  }
335  this->cleanUnused();
336  return *this;
337  }
338 
339  // Print
340  std::ostream& print(std::ostream& o = std::cout) const {
341  for (int i = this->nBits() - 1; i >= 0; i--) {
342  o << this->element(i);
343  }
344  return o;
345  }
346 
347  // direct access to set/read elements
348  refToBit operator[](const int pos) { return refToBit(*this, pos); }
349  int operator[](const int pos) const { return element(pos); }
350 
351  // logical operators ==
352  bool operator==(const BitArray<N>& a) const {
353  int nw = this->nWords();
354  int ub = this->unusedBits();
355  if (this->dataWord(nw - 1) << ub != // check last word
356  a.dataWord(nw - 1) << ub)
357  return false;
358  if (nw > 1) {
359  for (int iw = 0; iw < nw - 1; iw++) {
360  if (this->dataWord(iw) != a.dataWord(iw))
361  return false;
362  }
363  }
364  return true;
365  }
366 
367  // logical operators <
368  bool operator<(const BitArray<N>& a) const {
369  int nw = this->nWords();
370  int ub = this->unusedBits();
371  unsigned aaa = this->dataWord(nw - 1) << ub; // ignore unused bits
372  unsigned bbb = a.dataWord(nw - 1) << ub; // in both operands
373  if (aaa < bbb) {
374  return true;
375  } else if (aaa > bbb) {
376  return false;
377  }
378  if (nw > 1) {
379  for (int iw = nw - 2; iw >= 0; iw--) {
380  if (this->dataWord(iw) < a.dataWord(iw)) {
381  return true;
382  } else if (this->dataWord(iw) > a.dataWord(iw)) {
383  return false;
384  }
385  }
386  }
387  return false;
388  }
389 
390  // logical operators !=
391  bool operator!=(const BitArray<N>& a) const { return !(a == *this); }
392 
393  // logical operators >=
394  bool operator>=(const BitArray<N>& a) const { return !(*this < a); }
395 
396  // logical operators >
397  bool operator>(const BitArray<N>& a) const { return !(*this < a || *this == a); }
398 
399  // logical operators <=
400  bool operator<=(const BitArray<N>& a) const { return !(*this > a); }
401 
402  // non-const bit by bit negation
404  for (int i = 0; i < this->nWords(); i++) {
405  _data[i] = ~_data[i];
406  }
407  return *this;
408  }
409 
410  // const bit by bit negation
411  BitArray<N> operator~() const { return BitArray<N>(*this).flip(); }
412 
413  // bit by bit AND and assignment
415  for (int i = 0; i < this->nWords(); i++) {
416  this->dataWord(i) &= a.dataWord(i);
417  }
418  return *this;
419  }
420 
421  // bit by bit AND
422  BitArray<N> operator&(const BitArray<N>& a) { return BitArray<N>(*this) &= a; }
423 
424  // bit by bit OR and assignment
426  for (int i = 0; i < this->nWords(); i++) {
427  this->dataWord(i) |= a.dataWord(i);
428  }
429  return *this;
430  }
431 
432  // bit by bit AND
433  BitArray<N> operator|(const BitArray<N>& a) { return BitArray<N>(*this) |= a; }
434 
435  // bit by bit XOR and assignment
437  for (int i = 0; i < this->nWords(); i++) {
438  this->dataWord(i) ^= a.dataWord(i);
439  }
440  return *this;
441  }
442 
443  // bit by bit XOR
444  BitArray<N> operator^(const BitArray<N>& a) { return BitArray<N>(*this) ^= a; }
445 
446  // left shift and assignment
447  BitArray<N>& operator<<=(const int n) {
448  assert(n >= 0 && n < this->nBits());
449  if (n == 0)
450  return *this;
451  int i = 0;
452  for (i = this->nBits() - 1; i >= n; i--)
453  this->set(i, this->element(i - n));
454  for (i = n - 1; i >= 0; i--)
455  this->unset(i);
456  return *this;
457  }
458 
459  // left shift
460  BitArray<N> operator<<(const int n) { return BitArray<N>(*this) <<= n; }
461 
462  // right shift and assignment
463  BitArray<N>& operator>>=(const int n) {
464  assert(n >= 0 && n < this->nBits());
465  if (n == 0)
466  return *this;
467  int i = 0;
468  for (i = 0; i < this->nBits() - n; i++)
469  this->set(i, this->element(i + n));
470  for (i = this->nBits() - n; i < this->nBits(); i++)
471  this->unset(i);
472  return *this;
473  }
474 
475  // right shift
476  BitArray<N> operator>>(const int n) { return BitArray<N>(*this) >>= n; }
477 
478  // sum and assignment
480  int rep = 0;
481  int sum = 0;
482  for (int i = 0; i < this->nBits(); i++) {
483  sum = this->element(i) ^ rep;
484  rep = this->element(i) & rep;
485  this->set(i, sum ^ a.element(i));
486  rep |= (sum & a.element(i));
487  }
488  return *this;
489  }
490 
491  // sum
492  BitArray<N> operator+(const BitArray<N>& a) { return BitArray<N>(*this) += a; }
493 
494  // postfix increment
496  int i = 0;
497  while (i < this->nBits() && this->element(i) == 1) {
498  this->unset(i);
499  i++;
500  }
501  if (i < this->nBits())
502  this->set(i);
503  return *this;
504  }
505 
506  // const 2 complement
507  BitArray<N> twoComplement() const { return BitArray<N>(~*this)++; }
508 
509  // non-const 2 complement
511  (*this).flip();
512  (*this)++;
513  return *this;
514  }
515 
516  // subtract and assignment
517  BitArray<N>& operator-=(const BitArray<N>& a) { return *this += a.twoComplement(); }
518 
519  // subtract
520  BitArray<N> operator-(const BitArray<N>& a) { return BitArray<N>(*this) -= a; }
521 
522 private:
523  unsigned _data[N / 32 + 1];
524 };
525 
526 /*
527 template<int N>
528 ostream & operator <<(ostream & o, const BitArray<N> &b) {
529  b.print(o); return o;
530 }
531 */
532 
533 #endif
BitArray(const BitArray< N > &br)
Definition: BitArray.h:81
void assign(const int p, const int n, const BitArray< N > &val)
Definition: BitArray.h:244
BitArray< N > operator^(const BitArray< N > &a)
Definition: BitArray.h:444
BitArray< N > operator>>(const int n)
Definition: BitArray.h:476
void assign(const int p, const int n, const char *str)
Definition: BitArray.h:255
refToBit & operator=(const int val)
Definition: BitArray.h:47
int any()
Definition: BitArray.h:176
void zero()
Definition: BitArray.h:210
BitArray< N > & operator>>=(const int n)
Definition: BitArray.h:463
unsigned * _word
Definition: BitArray.h:75
std::ostream & print(std::ostream &o=std::cout) const
Definition: BitArray.h:340
unsigned lastWordMask() const
Definition: BitArray.h:160
friend class refToBit
Definition: BitArray.h:30
BitArray< N > & operator<<=(const int n)
Definition: BitArray.h:447
BitArray(const char *str, const int p, const int n)
Definition: BitArray.h:92
BitArray< N > & operator+=(const BitArray< N > &a)
Definition: BitArray.h:479
BitArray< N > & twoComplement()
Definition: BitArray.h:510
assert(be >=bs)
BitArray< N > & operator++(int)
Definition: BitArray.h:495
int operator~() const
Definition: BitArray.h:65
BitArray(const unsigned i)
Definition: BitArray.h:96
refToBit(BitArray &b, int pos)
Definition: BitArray.h:41
unsigned _data[N/32+1]
Definition: BitArray.h:523
BitArray< N > & operator=(const unsigned i)
Definition: BitArray.h:302
BitArray< N > & operator^=(const BitArray< N > &a)
Definition: BitArray.h:436
void one()
Definition: BitArray.h:217
void reset()
Definition: BitArray.h:215
int none()
Definition: BitArray.h:191
BitArray< N > operator|(const BitArray< N > &a)
Definition: BitArray.h:433
int count() const
Definition: BitArray.h:166
BitArray< N > & operator &=(const BitArray< N > &a)
Definition: BitArray.h:414
bool operator>=(const BitArray< N > &a) const
Definition: BitArray.h:394
refToBit & operator=(const refToBit &rtb)
Definition: BitArray.h:56
BitArray< N > operator~() const
Definition: BitArray.h:411
BitArray< N > operator<<(const int n)
Definition: BitArray.h:460
int nBits() const
Definition: BitArray.h:117
unsigned & dataWord(const int i)
Definition: BitArray.h:128
BitArray< N > twoComplement() const
Definition: BitArray.h:507
void cleanUnused()
Definition: BitArray.h:163
refToBit & flip()
Definition: BitArray.h:69
BitArray(const char *str)
Definition: BitArray.h:87
rep
Definition: cuy.py:1189
int unusedBits() const
Definition: BitArray.h:153
bool operator!=(const BitArray< N > &a) const
Definition: BitArray.h:391
void unset(const int i)
Definition: BitArray.h:225
int nWords() const
Definition: BitArray.h:121
unsigned & getWord(const int pos)
Definition: BitArray.h:134
BitArray< N > & operator=(const char *str)
Definition: BitArray.h:323
#define N
Definition: blowfish.cc:9
BitArray()
Definition: BitArray.h:79
double b
Definition: hdecay.h:120
BitArray< N > & flip()
Definition: BitArray.h:403
int test(const int i) const
Definition: BitArray.h:207
BitArray< N > & operator|=(const BitArray< N > &a)
Definition: BitArray.h:425
BitArray< N > operator+(const BitArray< N > &a)
Definition: BitArray.h:492
void assign(const int p, const int n, const int val)
Definition: BitArray.h:233
static unsigned getPosMask(const int pos)
Definition: BitArray.h:150
double a
Definition: hdecay.h:121
unsigned getWord(const int pos) const
Definition: BitArray.h:138
bool operator==(const BitArray< N > &a) const
Definition: BitArray.h:352
bool operator>(const BitArray< N > &a) const
Definition: BitArray.h:397
BitArray< N > operator-(const BitArray< N > &a)
Definition: BitArray.h:520
BitArray< 8 > byte(const int i) const
Definition: BitArray.h:282
unsigned read(const int p, const int n) const
Definition: BitArray.h:269
BitArray< N > & operator-=(const BitArray< N > &a)
Definition: BitArray.h:517
BitArray< N > operator &(const BitArray< N > &a)
Definition: BitArray.h:422
#define str(s)
int size() const
Definition: BitArray.h:118
BitArray< N > & operator=(const BitArray< N > &a)
Definition: BitArray.h:291
static int getPosInWord(const int pos)
Definition: BitArray.h:144
int element(const int pos) const
Definition: BitArray.h:206
unsigned dataWord(const int i) const
Definition: BitArray.h:124
refToBit operator[](const int pos)
Definition: BitArray.h:348
void reset(const int i)
Definition: BitArray.h:226
int operator[](const int pos) const
Definition: BitArray.h:349