Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef BIT_ARRAY_H_
00015 #define BIT_ARRAY_H_
00016
00017
00018
00019
00020
00021
00022 #include <cassert>
00023 #include <iostream>
00024
00025
00026
00027
00028
00029 template<int N>
00030 class BitArray {
00031
00032 public:
00033 class refToBit;
00034 friend class refToBit;
00035
00036
00037 class refToBit{
00038 friend class BitArray;
00039
00040
00041
00042 public:
00043 refToBit() {}
00044 refToBit(BitArray& b, int pos) {
00045 _word = &b.getWord(pos);
00046 _pos = getPosInWord(pos);
00047 }
00048 ~refToBit() {}
00049
00050 refToBit& operator=(const int val) {
00051 if(val) {
00052 *_word |= getPosMask(_pos);
00053 } else {
00054 *_word &= ~(getPosMask(_pos));
00055 }
00056 return *this;
00057 }
00058
00059 refToBit& operator=(const refToBit& rtb) {
00060 if( (*(rtb._word) & getPosMask(rtb._pos)) ) {
00061 *_word |= getPosMask(_pos);
00062 } else {
00063 *_word &= ~getPosMask(_pos);
00064 }
00065 return *this;
00066 }
00067
00068 int operator~() const { return ((*_word)&getPosMask(_pos))==0; }
00069
00070 operator int() const { return ((*_word)&getPosMask(_pos))!=0; }
00071
00072 refToBit& flip() {
00073 *_word^=getPosMask(_pos);
00074 return *this;
00075 }
00076
00077 private:
00078 unsigned* _word;
00079 int _pos;
00080
00081 };
00082
00083 BitArray() {this->zero();}
00084
00085 BitArray(const BitArray<N>& br) {
00086 for (int i=0;i<this->nWords();i++) {
00087 _data[i] = br._data[i];
00088 }
00089 this->cleanUnused();
00090 }
00091 BitArray(const char* str) {
00092 this->zero();
00093 this->assign(0,this->nBits(),str);
00094 this->cleanUnused();
00095 }
00096 BitArray(const char* str, const int p, const int n) {
00097 this->zero();
00098 this->assign(p, n, str);
00099 }
00100 BitArray(const unsigned i) {
00101 this->zero();
00102 _data[0] = i;
00103 this->cleanUnused();
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 inline int nBits() const { return N; }
00122 inline int size() const { return this->nBits(); }
00123
00124
00125 inline int nWords() const { return N/32+1; }
00126
00127
00128 unsigned dataWord(const int i) const {
00129 assert(i>=0 && i<this->nWords());
00130 return _data[i];
00131 }
00132 unsigned & dataWord(const int i) {
00133 assert(i>=0 && i<this->nWords());
00134 return _data[i];
00135 }
00136
00137
00138 unsigned & getWord(const int pos) {
00139 assert(pos>=0&& pos<this->nBits());
00140 return _data[pos/32];
00141 }
00142 unsigned getWord(const int pos) const {
00143 assert(pos>=0&& pos<this->nBits());
00144 return _data[pos/32];
00145 }
00146
00147
00148 static int getPosInWord(const int pos) {
00149
00150 return pos%32;
00151 }
00152
00153
00154 static unsigned getPosMask(const int pos) {
00155 return static_cast<unsigned>(1)<<getPosInWord(pos);
00156 }
00157
00158
00159 int unusedBits() const {
00160 if(this->nBits()==0)return 32;
00161 return 31-((this->nBits()-1)%32);
00162 }
00163
00164
00165 unsigned lastWordMask() const {
00166 return static_cast<unsigned>(0xffffffff)>>(this->unusedBits());
00167 }
00168
00169
00170 void cleanUnused() {
00171 _data[this->nWords()-1] &= (this->lastWordMask());
00172 }
00173
00174
00175 int count() const {
00176 int n=0;
00177 for(int i=0;i<this->nBits();i++) {
00178 if(this->element(i))n++;
00179 }
00180 return n;
00181 }
00182
00183
00184 int any() {
00185 int nw = this->nWords();
00186 int ub = unusedBits();
00187 if(this->dataWord(nw-1)<<ub!=0)return 1;
00188 if(nw>1){
00189 for (int iw=0;iw<nw-1;iw++){
00190 if(this->dataWord(iw)!=0) return 1;
00191 }
00192 }
00193 return 0;
00194 }
00195
00196
00197 int none() {
00198 int nw = this->nWords();
00199 int ub = unusedBits();
00200 if(this->dataWord(nw-1)<<ub!=0xffffffff)return 1;
00201 if(nw>1){
00202 for (int iw=0;iw<nw-1;iw++){
00203 if(this->dataWord(iw)!=0xffffffff) return 1;
00204 }
00205 }
00206 return 0;
00207 }
00208
00209
00210 int element(const int pos) const {
00211 return (getWord(pos)&getPosMask(pos))!=static_cast<unsigned>(0);
00212 }
00213 inline int test(const int i) const { return element(i); }
00214
00215
00216 void zero() {
00217 for (int i=0;i<this->nWords();i++) {
00218 _data[i] = 0x0;
00219 }
00220 }
00221 inline void reset() { zero(); }
00222
00223 void one() {
00224 for (int i=0;i<this->nWords();i++) {
00225 _data[i] = 0xffffffff;
00226 }
00227 }
00228
00229
00230 void set(const int i) { getWord(i) |= getPosMask(i); }
00231 void unset(const int i) { getWord(i) &= ~getPosMask(i); }
00232 inline void reset(const int i) { this->unset(i); }
00233
00234
00235 inline void set(const int i, const int val) { this->assign(i,1,val); }
00236 inline void set(const int i, const char* str) { this->assign(i,1,str); }
00237
00238
00239 void assign(const int p, const int n, const int val) {
00240 assert(p>=0 && p+n<=this->nBits());
00241
00242 for(int i=0; i<n;i++){
00243 if(val>>i&1) {
00244 this->set(p+i);
00245 } else {
00246 this->unset(p+i);
00247 }
00248 }
00249 }
00250 void assign(const int p, const int n, const BitArray<N>& val) {
00251 assert(p>=0 && p+n<=this->nBits());
00252
00253 for(int i=0; i<n;i++){
00254 if(val.element(i)) {
00255 this->set(p+i);
00256 } else {
00257 this->unset(p+i);
00258 }
00259 }
00260 }
00261 void assign(const int p, const int n, const char* str) {
00262 assert(p>=0 && p+n<=this->nBits());
00263
00264 for(int i=0; i<n;i++){
00265 assert(str[i]=='1'||str[i]=='0');
00266 if(str[i]=='1') {
00267 this->set(p+n-i-1);
00268 } else {
00269 this->unset(p+n-i-1);
00270 }
00271 }
00272 }
00273
00274
00275 unsigned read(const int p, const int n) const {
00276 assert(p>=0 && p+n<=this->nBits());
00277 assert(n<=32);
00278
00279 unsigned out=0x0;
00280 for(int i=0; i<n;i++){
00281 if(this->test(p+i)) out |= 1<<i;
00282 }
00283 return out;
00284 }
00285
00286
00287 BitArray<8> byte(const int i) const {
00288 BitArray<8> out;
00289 if(i>=0&&i<4*this->nWords()){
00290 unsigned k=(_data[i/4]>>8*(i%4))&0xff;
00291 out=k;
00292 }
00293 return out;
00294 }
00295
00296 BitArray<N>& operator=(const BitArray<N>& a) {
00297 if(this != &a) {
00298 for (int i=0;i<this->nWords();i++) {
00299 _data[i] = a._data[i];
00300 }
00301 }
00302 this->cleanUnused();
00303 return *this;
00304 }
00305
00306
00307 BitArray<N>& operator=(const unsigned i) {
00308 this->zero();
00309 _data[0] = i;
00310 this->cleanUnused();
00311 return *this;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 BitArray<N>& operator=(const char* str) {
00329 this->zero();
00330 for(int i=0; i<this->nBits();i++){
00331 assert(str[i]=='1'||str[i]=='0');
00332 if(str[i]=='1') {
00333 this->set(this->nBits()-i-1);
00334 } else if(str[i]=='0') {
00335 this->unset(this->nBits()-i-1);
00336 } else {
00337 break;
00338 }
00339 }
00340 this->cleanUnused();
00341 return *this;
00342 }
00343
00344
00345 std::ostream & print(std::ostream& o=std::cout) const {
00346 for(int i = this->nBits()-1; i>=0; i--){
00347 o << this->element(i);
00348 }
00349 return o;
00350 }
00351
00352
00353 refToBit operator[](const int pos) { return refToBit(*this,pos); }
00354 int operator[](const int pos) const { return element(pos); }
00355
00356
00357 bool operator==(const BitArray<N>& a) const {
00358 int nw = this->nWords();
00359 int ub = this->unusedBits();
00360 if(this->dataWord(nw-1)<<ub!=
00361 a.dataWord(nw-1)<<ub)return 0;
00362 if(nw>1){
00363 for (int iw=0;iw<nw-1;iw++){
00364 if(this->dataWord(iw)!=a.dataWord(iw)) return 0;
00365 }
00366 }
00367 return 1;
00368 }
00369
00370
00371 bool operator<(const BitArray<N>& a) const {
00372 int nw = this->nWords();
00373 int ub = this->unusedBits();
00374 unsigned aaa = this->dataWord(nw-1)<<ub;
00375 unsigned bbb = a.dataWord(nw-1)<<ub;
00376 if (aaa<bbb) {
00377 return 1;
00378 } else if (aaa>bbb) {
00379 return 0;
00380 }
00381 if(nw>1){
00382 for (int iw=nw-2;iw>=0;iw--){
00383 if (this->dataWord(iw)<a.dataWord(iw)) {
00384 return 1;
00385 } else if (this->dataWord(iw)>a.dataWord(iw)) {
00386 return 0;
00387 }
00388 }
00389 }
00390 return 0;
00391 }
00392
00393
00394 bool operator!=(const BitArray<N>& a) const { return !(a==*this); }
00395
00396
00397 bool operator>=(const BitArray<N>& a) const{ return !(*this<a); }
00398
00399
00400 bool operator>(const BitArray<N>& a) const { return !(*this<a||*this==a); }
00401
00402
00403 bool operator<=(const BitArray<N>& a) const { return !(*this>a); }
00404
00405
00406 BitArray<N>& flip () {
00407 for(int i=0;i<this->nWords();i++) {
00408 _data[i] = ~_data[i];
00409 }
00410 return *this;
00411 }
00412
00413
00414 BitArray<N> operator~ () const { return BitArray<N> (*this).flip(); }
00415
00416
00417 BitArray<N>& operator&= (const BitArray<N>& a) {
00418 for(int i = 0;i<this->nWords();i++) {
00419 this->dataWord(i) &= a.dataWord(i);
00420 }
00421 return *this;
00422 }
00423
00424
00425 BitArray<N> operator&(const BitArray<N>& a) {return BitArray<N> (*this)&=a; }
00426
00427
00428 BitArray<N>& operator|=(const BitArray<N>& a) {
00429 for(int i = 0;i<this->nWords();i++) {
00430 this->dataWord(i) |= a.dataWord(i);
00431 }
00432 return *this;
00433 }
00434
00435
00436 BitArray<N> operator|(const BitArray<N>& a) {return BitArray<N> (*this)|=a;}
00437
00438
00439 BitArray<N>& operator^=(const BitArray<N>& a) {
00440 for(int i = 0;i<this->nWords();i++) {
00441 this->dataWord(i) ^= a.dataWord(i);
00442 }
00443 return *this;
00444 }
00445
00446
00447 BitArray<N> operator^(const BitArray<N>& a) {return BitArray<N> (*this)^=a; }
00448
00449
00450 BitArray<N>& operator<<=(const int n) {
00451 assert(n>=0&&n<this->nBits());
00452 if(n==0)return *this;
00453 int i=0;
00454 for(i=this->nBits()-1;i>=n;i--) this->set(i,this->element(i-n));
00455 for(i=n-1;i>=0;i--) this->unset(i);
00456 return *this;
00457 }
00458
00459
00460 BitArray<N> operator<<(const int n) { return BitArray<N> (*this)<<=n; }
00461
00462
00463 BitArray<N>& operator>>=(const int n) {
00464 assert(n>=0&&n<this->nBits());
00465 if(n==0)return *this;
00466 int i=0;
00467 for(i=0;i<this->nBits()-n;i++) this->set(i,this->element(i+n));
00468 for(i=this->nBits()-n;i<this->nBits();i++) this->unset(i);
00469 return *this;
00470 }
00471
00472
00473 BitArray<N> operator>>(const int n) { return BitArray<N> (*this)>>=n; }
00474
00475
00476 BitArray<N>& operator+=(const BitArray<N>& a) {
00477 int rep=0;
00478 int sum=0;
00479 for(int i=0;i<this->nBits();i++) {
00480 sum=this->element(i)^rep;
00481 rep=this->element(i)&rep;
00482 this->set(i,sum^a.element(i));
00483 rep|=(sum&a.element(i));
00484 }
00485 return *this;
00486 }
00487
00488
00489 BitArray<N> operator+(const BitArray<N>& a) {return BitArray<N> (*this)+=a; }
00490
00491
00492 BitArray<N>& operator++(int) {
00493 int i = 0;
00494 while(i<this->nBits()&&this->element(i)==1) { this->unset(i); i++; }
00495 if(i<this->nBits())this->set(i);
00496 return *this;
00497 }
00498
00499
00500 BitArray<N> twoComplement() const { return BitArray<N> (~*this)++; }
00501
00502
00503 BitArray<N>& twoComplement() {
00504 (*this).flip();
00505 (*this)++;
00506 return *this;
00507 }
00508
00509
00510 BitArray<N>& operator-=(const BitArray<N>& a) {
00511 return *this+=a.twoComplement();
00512 }
00513
00514
00515 BitArray<N> operator-(const BitArray<N>& a) {return BitArray<N> (*this)-=a; }
00516
00517 private:
00518
00519 unsigned _data[N/32+1];
00520 };
00521
00522
00523
00524
00525
00526
00527
00528
00529 #endif