00001 #ifndef DUNE_BLOCK_BITFIELD_HH
00002 #define DUNE_BLOCK_BITFIELD_HH
00003
00008 #include <vector>
00009 #include <bitset>
00010 #include <iostream>
00011
00012 #include <dune/common/deprecated.hh>
00013 #include <dune/common/genericiterator.hh>
00014 #include <dune/common/exceptions.hh>
00015
00016 namespace Dune {
00017
00018 template <int block_size, class Alloc> class BitSetVector;
00019 template <int block_size, class Alloc> class BitSetVectorReference;
00020
00031 template <int block_size, class Alloc>
00032 class BitSetVectorConstReference
00033 {
00034 protected:
00035
00036 typedef Dune::BitSetVector<block_size, Alloc> BitSetVector;
00037 friend class Dune::BitSetVector<block_size, Alloc>;
00038
00039 BitSetVectorConstReference(const BitSetVector& blockBitField, int block_number) :
00040 blockBitField(blockBitField),
00041 block_number(block_number)
00042 {};
00043
00045 BitSetVectorConstReference& operator=(const BitSetVectorConstReference & b);
00046
00047 public:
00048
00049 typedef std::bitset<block_size> bitset;
00050
00051
00052 typedef typename std::vector<bool, Alloc>::const_reference reference;
00053 typedef typename std::vector<bool, Alloc>::const_reference const_reference;
00054 typedef size_t size_type;
00055
00057 bitset operator<<(size_type n) const
00058 {
00059 bitset b = *this;
00060 b <<= n;
00061 return b;
00062 }
00063
00065 bitset operator>>(size_type n) const
00066 {
00067 bitset b = *this;
00068 b >>= n;
00069 return b;
00070 }
00071
00073 bitset operator~() const
00074 {
00075 bitset b = *this;
00076 b.flip();
00077 return b;
00078 }
00079
00081 size_type size() const
00082 {
00083 return block_size;
00084 }
00085
00087 size_type count() const
00088 {
00089 size_type n = 0;
00090 for(size_type i=0; i<block_size; ++i)
00091 n += getBit(i);
00092 return n;
00093 }
00094
00096 bool any() const
00097 {
00098 return count();
00099 }
00100
00102 bool none() const
00103 {
00104 return ! any();
00105 }
00106
00108 bool test(size_type n) const
00109 {
00110 return getBit(n);
00111 }
00112
00113 const_reference operator[](size_type i) const
00114 {
00115 return getBit(i);
00116 }
00117
00119 operator bitset() const
00120 {
00121 return blockBitField.getRepr(block_number);
00122 }
00123
00125 bool operator== (const bitset& bs) const
00126 {
00127 return equals(bs);
00128 }
00129
00131 bool operator== (const BitSetVectorConstReference& bs) const
00132 {
00133 return equals(bs);
00134 }
00135
00137 bool operator!= (const bitset& bs) const
00138 {
00139 return ! equals(bs);
00140 }
00141
00143 bool operator!= (const BitSetVectorConstReference& bs) const
00144 {
00145 return ! equals(bs);
00146 }
00147
00154 friend std::ostream& operator<< (std::ostream& s, const BitSetVectorConstReference& v)
00155 {
00156 s << "(";
00157 for(int i=0; i<block_size; ++i)
00158 s << v[i];
00159 s << ")";
00160 return s;
00161 }
00162
00163 protected:
00164 const BitSetVector& blockBitField;
00165 int block_number;
00166
00167 const_reference getBit(size_type i) const
00168 {
00169 return blockBitField.getBit(block_number,i);
00170 }
00171
00172 template<class BS>
00173 bool equals(const BS & bs) const
00174 {
00175 bool eq = true;
00176 for(int i=0; i<block_size; ++i)
00177 eq &= (getBit(i) == bs[i]);
00178 return eq;
00179 }
00180
00181 private:
00186 void operator & ();
00187
00188 friend class BitSetVectorReference<block_size, Alloc>;
00189 };
00190
00203 template <int block_size, class Alloc>
00204 class BitSetVectorReference : public BitSetVectorConstReference<block_size,Alloc>
00205 {
00206 protected:
00207
00208 typedef Dune::BitSetVector<block_size, Alloc> BitSetVector;
00209 friend class Dune::BitSetVector<block_size, Alloc>;
00210
00211 typedef Dune::BitSetVectorConstReference<block_size,Alloc> BitSetVectorConstReference;
00212
00213 BitSetVectorReference(BitSetVector& blockBitField, int block_number) :
00214 BitSetVectorConstReference(blockBitField, block_number),
00215 blockBitField(blockBitField)
00216 {};
00217
00218 public:
00219 typedef std::bitset<block_size> bitset;
00220
00224 typedef typename std::vector<bool, Alloc>::reference reference;
00226 typedef typename std::vector<bool, Alloc>::const_reference const_reference;
00228
00230 typedef size_t size_type;
00231
00233 BitSetVectorReference& operator=(bool b)
00234 {
00235 for(int i=0; i<block_size; ++i)
00236 getBit(i) = b;
00237 return (*this);
00238 }
00239
00241 BitSetVectorReference& operator=(const bitset & b)
00242 {
00243 for(int i=0; i<block_size; ++i)
00244 getBit(i) = b.test(i);
00245 return (*this);
00246 }
00247
00249 BitSetVectorReference& operator=(const BitSetVectorConstReference & b)
00250 {
00251 for(int i=0; i<block_size; ++i)
00252 getBit(i) = b.test(i);
00253 return (*this);
00254 }
00255
00257 BitSetVectorReference& operator=(const BitSetVectorReference & b)
00258 {
00259 for(int i=0; i<block_size; ++i)
00260 getBit(i) = b.test(i);
00261 return (*this);
00262 }
00263
00265 BitSetVectorReference& operator&=(const bitset& x)
00266 {
00267 for (size_type i=0; i<block_size; i++)
00268 getBit(i) = (test(i) & x.test(i));
00269 return *this;
00270 }
00271
00273 BitSetVectorReference& operator&=(const BitSetVectorConstReference& x)
00274 {
00275 for (size_type i=0; i<block_size; i++)
00276 getBit(i) = (test(i) & x.test(i));
00277 return *this;
00278 }
00279
00281 BitSetVectorReference& operator|=(const bitset& x)
00282 {
00283 for (size_type i=0; i<block_size; i++)
00284 getBit(i) = (test(i) | x.test(i));
00285 return *this;
00286 }
00287
00289 BitSetVectorReference& operator|=(const BitSetVectorConstReference& x)
00290 {
00291 for (size_type i=0; i<block_size; i++)
00292 getBit(i) = (test(i) | x.test(i));
00293 return *this;
00294 }
00295
00297 BitSetVectorReference& operator^=(const bitset& x)
00298 {
00299 for (size_type i=0; i<block_size; i++)
00300 getBit(i) = (test(i) ^ x.test(i));
00301 return *this;
00302 }
00303
00305 BitSetVectorReference& operator^=(const BitSetVectorConstReference& x)
00306 {
00307 for (size_type i=0; i<block_size; i++)
00308 getBit(i) = (test(i) ^ x.test(i));
00309 return *this;
00310 }
00311
00313 BitSetVectorReference& operator<<=(size_type n)
00314 {
00315 for (size_type i=0; i<block_size-n; i++)
00316 getBit(i) = test(i+n);
00317 return *this;
00318 }
00319
00321 BitSetVectorReference& operator>>=(size_type n)
00322 {
00323 for (size_type i=0; i<block_size-n; i++)
00324 getBit(i+n) = test(i);
00325 return *this;
00326 }
00327
00328
00329 BitSetVectorReference& set()
00330 {
00331 for (size_type i=0; i<block_size; i++)
00332 set(i);
00333 return *this;
00334 }
00335
00337 BitSetVectorReference& flip()
00338 {
00339 for (size_type i=0; i<block_size; i++)
00340 flip(i);
00341 return *this;
00342 }
00343
00345 BitSetVectorReference& reset()
00346 {
00347 }
00348
00350 BitSetVectorReference& set(size_type n, int val = 1)
00351 {
00352 getBit(n) = val;
00353 return *this;
00354 }
00355
00357 BitSetVectorReference& reset(size_type n)
00358 {
00359 set(n, false);
00360 return *this;
00361 }
00362
00364 BitSetVectorReference& flip(size_type n)
00365 {
00366 getBit(n).flip();
00367 return *this;
00368 }
00369
00370 using BitSetVectorConstReference::test;
00371 using BitSetVectorConstReference::operator[];
00372
00373 reference operator[](size_type i)
00374 {
00375 return getBit(i);
00376 }
00377
00378 protected:
00379 BitSetVector& blockBitField;
00380
00381 using BitSetVectorConstReference::getBit;
00382
00383 reference getBit(size_type i)
00384 {
00385 return blockBitField.getBit(this->block_number,i);
00386 }
00387 };
00388
00392 template<int block_size, class Alloc>
00393 struct const_reference< BitSetVectorReference<block_size,Alloc> >
00394 {
00395 typedef BitSetVectorConstReference<block_size,Alloc> type;
00396 };
00397
00398 template<int block_size, class Alloc>
00399 struct const_reference< BitSetVectorConstReference<block_size,Alloc> >
00400 {
00401 typedef BitSetVectorConstReference<block_size,Alloc> type;
00402 };
00403
00404 template<int block_size, class Alloc>
00405 struct mutable_reference< BitSetVectorReference<block_size,Alloc> >
00406 {
00407 typedef BitSetVectorReference<block_size,Alloc> type;
00408 };
00409
00410 template<int block_size, class Alloc>
00411 struct mutable_reference< BitSetVectorConstReference<block_size,Alloc> >
00412 {
00413 typedef BitSetVectorReference<block_size,Alloc> type;
00414 };
00415
00419 template <int block_size, class Allocator=std::allocator<bool> >
00420 class BitSetVector : private std::vector<bool, Allocator>
00421 {
00423 typedef std::vector<bool, Allocator> BlocklessBaseClass;
00424
00425 public:
00428
00430 typedef std::bitset<block_size> value_type;
00431
00433 typedef BitSetVectorReference<block_size,Allocator> reference;
00434
00436 typedef BitSetVectorConstReference<block_size,Allocator> const_reference;
00437
00439 typedef BitSetVectorReference<block_size,Allocator>* pointer;
00440
00442 typedef BitSetVectorConstReference<block_size,Allocator>* const_pointer;
00443
00445 typedef typename std::vector<bool, Allocator>::size_type size_type;
00446
00448 typedef Allocator allocator_type;
00450
00453 typedef Dune::GenericIterator<BitSetVector<block_size,Allocator>, value_type, reference, std::ptrdiff_t, ForwardIteratorFacade> iterator;
00454 typedef Dune::GenericIterator<const BitSetVector<block_size,Allocator>, const value_type, const_reference, std::ptrdiff_t, ForwardIteratorFacade> const_iterator;
00456
00458 iterator begin(){
00459 return iterator(*this, 0);
00460 }
00461
00463 const_iterator begin() const{
00464 return const_iterator(*this, 0);
00465 }
00466
00468 iterator end(){
00469 return iterator(*this, size());
00470 }
00471
00473 const_iterator end() const{
00474 return const_iterator(*this, size());
00475 }
00476
00478 BitSetVector() :
00479 BlocklessBaseClass()
00480 {}
00481
00483 BitSetVector(const BlocklessBaseClass& blocklessBitField) :
00484 BlocklessBaseClass(blocklessBitField)
00485 {
00486 if (blocklessBitField.size()%block_size != 0)
00487 DUNE_THROW(RangeError, "Vector size is not a multiple of the block size!");
00488 }
00489
00493 explicit BitSetVector(int n) :
00494 BlocklessBaseClass(n*block_size)
00495 {}
00496
00498 BitSetVector(int n, bool v) :
00499 BlocklessBaseClass(n*block_size,v)
00500 {}
00501
00503 void clear()
00504 {
00505 BlocklessBaseClass::clear();
00506 }
00507
00509 void resize(int n, bool v = bool())
00510 {
00511 BlocklessBaseClass::resize(n*block_size, v);
00512 }
00513
00515 int size() const
00516 {
00517 return BlocklessBaseClass::size()/block_size;
00518 }
00519
00521 void setAll() {
00522 this->assign(BlocklessBaseClass::size(), true);
00523 }
00524
00526 void unsetAll() {
00527 this->assign(BlocklessBaseClass::size(), false);
00528 }
00529
00531 reference operator[](int i)
00532 {
00533 return reference(*this, i);
00534 }
00535
00537 const_reference operator[](int i) const
00538 {
00539 return const_reference(*this, i);
00540 }
00541
00543 reference back()
00544 {
00545 return reference(*this, size()-1);
00546 }
00547
00549 const_reference back() const
00550 {
00551 return const_reference(*this, size()-1);
00552 }
00553
00555 size_type nSetBits() const DUNE_DEPRECATED
00556 {
00557 return count();
00558 }
00559
00561 int nSetBits(int i) const DUNE_DEPRECATED
00562 {
00563 return countmasked(i);
00564 }
00565
00567 size_type count() const
00568 {
00569 size_type n = 0;
00570 for(size_type i=0; i<BlocklessBaseClass::size(); ++i)
00571 n += BlocklessBaseClass::operator[](i);
00572 return n;
00573 }
00574
00576 int countmasked(int j) const
00577 {
00578 size_type n = 0;
00579 size_type blocks = size();
00580 for(size_type i=0; i<blocks; ++i)
00581 n += getBit(i,j);
00582 return n;
00583 }
00584
00586 friend std::ostream& operator<< (std::ostream& s, const BitSetVector& v)
00587 {
00588 for (size_t i=0; i<v.size(); i++)
00589 s << v[i] << " ";
00590 return s;
00591 }
00592
00593 private:
00594
00595
00596 value_type getRepr(int i) const
00597 {
00598 value_type bits;
00599 for(int j=0; j<block_size; ++j)
00600 bits.set(j, getBit(i,j));
00601 return bits;
00602 }
00603
00604 typename std::vector<bool>::reference getBit(size_type i, size_type j) {
00605 return BlocklessBaseClass::operator[](i*block_size+j);
00606 }
00607
00608 typename std::vector<bool>::const_reference getBit(size_type i, size_type j) const {
00609 return BlocklessBaseClass::operator[](i*block_size+j);
00610 }
00611
00612 friend class BitSetVectorReference<block_size,Allocator>;
00613 friend class BitSetVectorConstReference<block_size,Allocator>;
00614 };
00615
00616 }
00617
00618 #endif