00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #ifndef __VBITSET_HH__
00071 #define __VBITSET_HH__
00072
00073 #include <memory>
00074 using namespace std;
00075
00076 #include "debug.h"
00077
00078 extern unsigned char vBitset_bit_count[];
00079
00080 #ifdef DEBUG
00081 extern unsigned long vBitset_usecnt;
00082 #endif
00083
00099 template<class W, class A = allocator<W> > class vBitset_base
00100 {
00101
00102
00103
00104
00105
00106
00107
00108
00109 public:
00110
00116 typedef W WordType;
00117
00118 typedef A AllocatorType;
00119
00123 typedef WordType *Mptr;
00124
00128 typedef WordType &Mref;
00129
00133 typedef size_t SizeType;
00134
00138 static const SizeType WORDBITS = sizeof(WordType) * 8;
00139
00140 static const SizeType WORDBYTES = sizeof(WordType);
00141
00142 static SizeType whichWord (SizeType bits)
00143 {
00144 return bits / WORDBITS;
00145 }
00146
00147 static SizeType whichBit (SizeType bits)
00148 {
00149 return bits % WORDBITS;
00150 }
00151
00152 static WordType maskBit (SizeType bits)
00153 {
00154 return static_cast<WordType>(1) << whichBit(bits);
00155 }
00156
00161 class reference
00162 {
00163 friend class vBitset_base;
00164
00165 public:
00166
00167 reference (const vBitset_base &set_, SizeType bit_) :
00168 wp(set_.getWord(bit_)), mask(maskBit(bit_))
00169 {}
00170
00171 reference (const reference &o) :
00172 wp(o.wp), mask(o.mask)
00173 {}
00174
00175 reference () : wp(0), mask(0)
00176 {}
00177
00178 ~reference ()
00179 {}
00180
00181 reference& operator = (const reference &o)
00182 {
00183 wp = o.wp;
00184 mask = o.mask;
00185 return *this;
00186 }
00187
00192 bool set (bool b = 1) const
00193 {
00194 check();
00195 if (b) *wp |= mask; else *wp &= ~mask;
00196 return b;
00197 }
00198
00202 bool get () const
00203 {
00204 return *wp & mask;
00205 }
00206
00212 bool eq (const reference &o)
00213 {
00214 return (wp == o.wp) && (mask == o.mask);
00215 }
00216
00217 bool neq (const reference &o)
00218 {
00219 return !eq(o);
00220 }
00221
00222 bool lt (const reference &o)
00223 {
00224 return (wp < o.wp) || ((wp == o.wp) && (mask < o.mask));
00225 }
00226
00227 bool le (const reference &o)
00228 {
00229 return lt(o) || eq(o);
00230 }
00231
00232 bool gt (const reference &o)
00233 {
00234 return !le(o);
00235 }
00236
00237 bool ge (const reference &o)
00238 {
00239 return !lt(o);
00240 }
00241
00242
00243
00247 reference& next ()
00248 {
00249 if (mask == (static_cast<WordType>(1) << (WORDBITS - 1))) {
00250 mask = (WordType) 1;
00251 ++wp;
00252 } else {
00253 mask <<= 1;
00254 }
00255 return *this;
00256 }
00257
00261 reference& prev ()
00262 {
00263 if (mask == static_cast<WordType>(1)) {
00264 mask = static_cast<WordType>(1) << (WORDBITS - 1);
00265 --wp;
00266 } else {
00267 mask >>= 1;
00268 }
00269 return this;
00270 }
00271
00276 void check() const
00277 {
00278
00279 }
00280
00281 protected:
00282
00287 void move (const vBitset_base &set_, SizeType bit_)
00288 {
00289 wp = set_.getWord(bit_);
00290 mask = maskBit(bit_);
00291 }
00292
00293
00294 private:
00295 Mptr wp;
00296 WordType mask;
00297 };
00298
00304 vBitset_base (SizeType len_ = 1) :
00305 len(len_ ? len_ : 1)
00306 {
00307 SizeType cap = whichWord(len) + 1;
00308 data = M_alloc.allocate(cap);
00309 endOfData = data + cap;
00310 for (Mptr q = data; q < endOfData; *q++ = 0);
00311 updateLimits();
00312 #ifdef DEBUG
00313 vBitset_usecnt++;
00314 #endif
00315 }
00316
00317 vBitset_base (const vBitset_base &o)
00318 {
00319 len = o.len;
00320 data = M_alloc.allocate(o.capacity());
00321 endOfData = data + o.capacity();
00322 for(Mptr p = data, q = o.data; p < endOfData; *p++ = *q++);
00323 updateLimits();
00324 #ifdef DEBUG
00325 vBitset_usecnt++;
00326 #endif
00327 }
00328
00329
00330 vBitset_base& operator = (const vBitset_base &o)
00331 {
00332 if (this == &o) return *this;
00333 M_alloc.deallocate(data, capacity());
00334 len = o.len;
00335 data = M_alloc.allocate(o.capacity());
00336 endOfData = data + o.capacity();
00337 for(Mptr p = data, q = o.data; p < endOfData; *p++ = *q++);
00338 updateLimits();
00339 }
00340
00341 ~vBitset_base ()
00342 {
00343 M_alloc.deallocate(data, capacity());
00344 }
00345
00346
00351 reference operator [] (SizeType n)
00352 {
00353 return reference(*this, n);
00354 }
00355
00356 reference begin ()
00357 {
00358 return _begin;
00359 }
00360
00361 reference end ()
00362 {
00363 return _end;
00364 }
00365
00370 void resize (SizeType n)
00371 {
00372 grow(n);
00373 }
00374
00378 SizeType size () const
00379 {
00380 return len;
00381 }
00382
00386 SizeType length () const
00387 {
00388 return size();
00389 }
00390
00395 SizeType capacity () const
00396 {
00397 return endOfData - data;
00398 }
00399
00403 bool all0 () const
00404 {
00405 return count1() == 0;
00406 }
00407
00411 bool all1 () const
00412 {
00413 return !all0();
00414 }
00415
00419 SizeType count1 () const
00420 {
00421 SizeType res = 0;
00422
00423 for (unsigned char* p = (unsigned char *) data;
00424 p < (unsigned char *)endOfData; p++)
00425 {
00426 res += vBitset_bit_count[*p];
00427 }
00428
00429 return res;
00430 }
00431
00435 SizeType count0 () const
00436 {
00437 return length() - count1();
00438 }
00439
00443 void flip ()
00444 {
00445 for (Mptr q = data; q < endOfData; q++) *q = ~*q;
00446 }
00447
00448 void doOr (const vBitset_base &o)
00449 {
00450 Mptr p = data, q = o.data;
00451 if (capacity() < o.capacity()) {
00452 while (p < endOfData) *p++ |= *q++;
00453 grow_fill(o.length(), q);
00454 } else {
00455 while (q < o.endOfData) *p++ |= *q++;
00456 if (o.len > len) {
00457 len = o.len;
00458 updateLimits();
00459 }
00460 }
00461 }
00462
00463 vBitset_base& operator |= (const vBitset_base &o)
00464 {
00465 doOr(o);
00466 return *this;
00467 }
00468
00469 void doAnd (const vBitset_base &o)
00470 {
00471 Mptr p = data, q = o.data;
00472 if (capacity() < o.capacity()) {
00473 while (p < endOfData) *p++ &= *q++;
00474 grow(o.length());
00475 } else {
00476 while (q < o.endOfData) *p++ &= *q++;
00477 while (p < endOfData) *p++ = 0;
00478 if (o.len > len) {
00479 len = o.len;
00480 updateLimits();
00481 }
00482 }
00483 }
00484
00485 vBitset_base& operator &= (const vBitset_base &o)
00486 {
00487 doAnd(o);
00488 return *this;
00489 }
00490
00497 bool operator == (const vBitset_base &o) const
00498 {
00499 if (this == &o) return true;
00500
00501 if (o.capacity() > capacity()) return o == *this;
00502
00503
00504 Mptr p = data, q = o.data;
00505 while (q < o.endOfData) if (*p++ != *q++) return false;
00506 while (p < endOfData) if (*p++ != static_cast<WordType>(0)) return false;
00507 return true;
00508 }
00509
00510 bool operator != (const vBitset_base &o) const
00511 {
00512 return ! (*this== o);
00513 }
00514
00515 void clear ()
00516 {
00517 for (Mptr p = data; p < endOfData; *p++ = static_cast<WordType>(0));
00518 len = 1;
00519 updateLimits();
00520 }
00521
00522 protected:
00523
00527 Mptr getWord (SizeType n) const
00528 {
00529 return data + whichWord(n);
00530 }
00531
00536 void grow (SizeType n)
00537 {
00538 SizeType newCap = whichWord(n) + 1;
00539 if (capacity() < newCap)
00540 {
00541 Mptr q = data, pS = M_alloc.allocate(newCap), pE = pS;
00542
00543 while (q < endOfData) *pE++ = *q++;
00544 while (pE < pS + newCap) *pE++ = static_cast<WordType>(0);
00545
00546 M_alloc.deallocate(data, capacity());
00547
00548 data = pS;
00549 endOfData = pE;
00550 }
00551 len = n;
00552 updateLimits();
00553 }
00554
00559 void grow_fill (SizeType n, Mptr d)
00560 {
00561 SizeType newCap = whichWord(n) + 1;
00562 if (capacity() < newCap)
00563 {
00564 Mptr q = data, pS = M_alloc.allocate(newCap), pE = pS;
00565
00566 while (q < endOfData) *pE++ = *q++;
00567 while (pE < pS + newCap) *pE++ = *d++;
00568
00569 M_alloc.deallocate(data, capacity());
00570
00571 data = pS;
00572 endOfData = pE;
00573 }
00574 len = n;
00575 updateLimits();
00576 }
00577
00581 void updateLimits ()
00582 {
00583 _begin.move(*this, 0);
00584 _end.move(*this, len);
00585 }
00586
00587 private:
00588
00592 Mptr data;
00593
00597 Mptr endOfData;
00598
00602 SizeType len;
00603
00607 reference _begin;
00608
00612 reference _end;
00613
00614 static AllocatorType M_alloc;
00615 };
00616
00617
00618 typedef vBitset_base<unsigned long> vBitset;
00619
00620 template<class W, class A>
00621 vBitset_base<W, A> operator | (const vBitset_base<W, A> &a,
00622 const vBitset_base<W, A> &b)
00623 {
00624 vBitset_base<W, A> res(a);
00625 res |= b;
00626 return res;
00627 }
00628
00629 template<class W, class A>
00630 vBitset_base<W, A> operator & (const vBitset_base<W, A> &a,
00631 const vBitset_base<W, A> &b)
00632 {
00633 vBitset_base<W, A> res(a);
00634 res &= b;
00635 return res;
00636 }
00637
00638 template<class W, class A>
00639 vBitset_base<W, A> operator ^ (const vBitset_base<W, A> &a,
00640 const vBitset_base<W, A> &b)
00641 {
00642 vBitset_base<W, A> res(a);
00643 res ^= b;
00644 return res;
00645 }
00646
00647 template<class W, class A>
00648 vBitset_base<W, A> operator << (const vBitset_base<W, A> &a,
00649 typename vBitset_base<W, A>::SizeType n)
00650 {
00651 vBitset_base<W, A> res(a);
00652 res <<= n;
00653 return res;
00654 }
00655
00656 template<class W, class A>
00657 vBitset_base<W, A> operator >> (const vBitset_base<W, A> &a,
00658 typename vBitset_base<W, A>::SizeType n)
00659 {
00660 vBitset_base<W, A> res(a);
00661 res >>= n;
00662 return res;
00663 }
00664
00665 #endif