CMS 3D CMS Logo

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