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
00201 template <int block_size, class Alloc>
00202 class BitSetVectorReference : public BitSetVectorConstReference<block_size,Alloc>
00203 {
00204 protected:
00205
00206 typedef Dune::BitSetVector<block_size, Alloc> BitSetVector;
00207 friend class Dune::BitSetVector<block_size, Alloc>;
00208
00209 typedef Dune::BitSetVectorConstReference<block_size,Alloc> BitSetVectorConstReference;
00210
00211 BitSetVectorReference(BitSetVector& blockBitField, int block_number) :
00212 BitSetVectorConstReference(blockBitField, block_number),
00213 blockBitField(blockBitField)
00214 {};
00215
00216 public:
00217 typedef std::bitset<block_size> bitset;
00218
00222 typedef typename std::vector<bool, Alloc>::reference reference;
00224 typedef typename std::vector<bool, Alloc>::const_reference const_reference;
00226
00228 typedef size_t size_type;
00229
00231 BitSetVectorReference& operator=(bool b)
00232 {
00233 for(int i=0; i<block_size; ++i)
00234 getBit(i) = b;
00235
00236 return (*this);
00237 }
00238
00240 BitSetVectorReference& operator=(const bitset & b)
00241 {
00242 for(int i=0; i<block_size; ++i)
00243 getBit(i) = b[i];
00244
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[i];
00253
00254 return (*this);
00255 }
00256
00258 BitSetVectorReference& operator=(const BitSetVectorReference & b)
00259 {
00260 for(int i=0; i<block_size; ++i)
00261 getBit(i) = b.getBit(i);
00262
00263 return (*this);
00264 }
00265
00267 BitSetVectorReference& operator&=(const BitSetVectorConstReference& x)
00268 {
00269 for (size_type i=0; i<block_size; i++)
00270 set(i, getBit(i) & x.getBit(i));
00271 return *this;
00272 }
00273
00275 BitSetVectorReference& operator|=(const BitSetVectorConstReference& x)
00276 {
00277 for (size_type i=0; i<block_size; i++)
00278 set(i, getBit(i) | x.getBit(i));
00279 return *this;
00280 }
00281
00283 BitSetVectorReference& operator^=(const BitSetVectorConstReference& x)
00284 {
00285 for (size_type i=0; i<block_size; i++)
00286 set(i, getBit(i) ^ x.getBit(i));
00287 return *this;
00288 }
00289
00291 BitSetVectorReference& operator<<=(size_type n)
00292 {
00293 for (size_type i=0; i<block_size-n; i++)
00294 set(i, getBit(i+n));
00295 return *this;
00296 }
00297
00299 BitSetVectorReference& operator>>=(size_type n)
00300 {
00301 for (size_type i=0; i<block_size-n; i++)
00302 set(i+n, getBit(i));
00303 return *this;
00304 }
00305
00306
00307 BitSetVectorReference& set()
00308 {
00309 for (size_type i=0; i<block_size; i++)
00310 set(i);
00311 return *this;
00312 }
00313
00315 BitSetVectorReference& flip()
00316 {
00317 for (size_type i=0; i<block_size; i++)
00318 flip(i);
00319 return *this;
00320 }
00321
00323 BitSetVectorReference& reset()
00324 {
00325 }
00326
00328 BitSetVectorReference& set(size_type n, int val = 1)
00329 {
00330 getBit(n) = val;
00331 return *this;
00332 }
00333
00335 BitSetVectorReference& reset(size_type n)
00336 {
00337 set(n, false);
00338 return *this;
00339 }
00340
00342 BitSetVectorReference& flip(size_type n)
00343 {
00344 getBit(n).flip();
00345 return *this;
00346 }
00347
00348 using BitSetVectorConstReference::operator[];
00349
00350 reference operator[](size_type i)
00351 {
00352 return getBit(i);
00353 }
00354
00355 protected:
00356 BitSetVector& blockBitField;
00357
00358 using BitSetVectorConstReference::getBit;
00359
00360 reference getBit(size_type i)
00361 {
00362 return blockBitField.getBit(this->block_number,i);
00363 }
00364 };
00365
00369 template<int block_size, class Alloc>
00370 struct const_reference< BitSetVectorReference<block_size,Alloc> >
00371 {
00372 typedef BitSetVectorConstReference<block_size,Alloc> type;
00373 };
00374
00375 template<int block_size, class Alloc>
00376 struct const_reference< BitSetVectorConstReference<block_size,Alloc> >
00377 {
00378 typedef BitSetVectorConstReference<block_size,Alloc> type;
00379 };
00380
00381 template<int block_size, class Alloc>
00382 struct mutable_reference< BitSetVectorReference<block_size,Alloc> >
00383 {
00384 typedef BitSetVectorReference<block_size,Alloc> type;
00385 };
00386
00387 template<int block_size, class Alloc>
00388 struct mutable_reference< BitSetVectorConstReference<block_size,Alloc> >
00389 {
00390 typedef BitSetVectorReference<block_size,Alloc> type;
00391 };
00392
00396 template <int block_size, class Allocator=std::allocator<bool> >
00397 class BitSetVector : private std::vector<bool, Allocator>
00398 {
00400 typedef std::vector<bool, Allocator> BlocklessBaseClass;
00401
00402 public:
00405
00407 typedef std::bitset<block_size> value_type;
00408
00410 typedef BitSetVectorReference<block_size,Allocator> reference;
00411
00413 typedef BitSetVectorConstReference<block_size,Allocator> const_reference;
00414
00416 typedef BitSetVectorReference<block_size,Allocator>* pointer;
00417
00419 typedef BitSetVectorConstReference<block_size,Allocator>* const_pointer;
00420
00422 typedef typename std::vector<bool, Allocator>::size_type size_type;
00423
00425 typedef Allocator allocator_type;
00427
00430 typedef Dune::GenericIterator<BitSetVector<block_size,Allocator>, value_type, reference, std::ptrdiff_t, ForwardIteratorFacade> iterator;
00431 typedef Dune::GenericIterator<const BitSetVector<block_size,Allocator>, const value_type, const_reference, std::ptrdiff_t, ForwardIteratorFacade> const_iterator;
00433
00435 iterator begin(){
00436 return iterator(*this, 0);
00437 }
00438
00440 const_iterator begin() const{
00441 return const_iterator(*this, 0);
00442 }
00443
00445 iterator end(){
00446 return iterator(*this, size());
00447 }
00448
00450 const_iterator end() const{
00451 return const_iterator(*this, size());
00452 }
00453
00455 BitSetVector() :
00456 BlocklessBaseClass()
00457 {}
00458
00460 BitSetVector(const BlocklessBaseClass& blocklessBitField) :
00461 BlocklessBaseClass(blocklessBitField)
00462 {
00463 if (blocklessBitField.size()%block_size != 0)
00464 DUNE_THROW(RangeError, "Vector size is not a multiple of the block size!");
00465 }
00466
00470 explicit BitSetVector(int n) :
00471 BlocklessBaseClass(n*block_size)
00472 {}
00473
00475 BitSetVector(int n, bool v) :
00476 BlocklessBaseClass(n*block_size,v)
00477 {}
00478
00480 void clear()
00481 {
00482 BlocklessBaseClass::clear();
00483 }
00484
00486 void resize(int n, bool v = bool())
00487 {
00488 BlocklessBaseClass::resize(n*block_size, v);
00489 }
00490
00492 int size() const
00493 {
00494 return BlocklessBaseClass::size()/block_size;
00495 }
00496
00498 void setAll() {
00499 this->assign(BlocklessBaseClass::size(), true);
00500 }
00501
00503 void unsetAll() {
00504 this->assign(BlocklessBaseClass::size(), false);
00505 }
00506
00508 reference operator[](int i)
00509 {
00510 return reference(*this, i);
00511 }
00512
00514 const_reference operator[](int i) const
00515 {
00516 return const_reference(*this, i);
00517 }
00518
00520 reference back()
00521 {
00522 return reference(*this, size()-1);
00523 }
00524
00526 const_reference back() const
00527 {
00528 return const_reference(*this, size()-1);
00529 }
00530
00532 size_type nSetBits() const DUNE_DEPRECATED
00533 {
00534 return count();
00535 }
00536
00538 int nSetBits(int i) const DUNE_DEPRECATED
00539 {
00540 return countmasked(i);
00541 }
00542
00544 size_type count() const
00545 {
00546 size_type n = 0;
00547 for(size_type i=0; i<BlocklessBaseClass::size(); ++i)
00548 n += BlocklessBaseClass::operator[](i);
00549 return n;
00550 }
00551
00553 int countmasked(int j) const
00554 {
00555 size_type n = 0;
00556 size_type blocks = size();
00557 for(size_type i=0; i<blocks; ++i)
00558 n += getBit(i,j);
00559 return n;
00560 }
00561
00563 friend std::ostream& operator<< (std::ostream& s, const BitSetVector& v)
00564 {
00565 for (size_t i=0; i<v.size(); i++)
00566 s << v[i] << " ";
00567 return s;
00568 }
00569
00570 private:
00571
00572
00573 value_type getRepr(int i) const
00574 {
00575 value_type bits;
00576 for(int j=0; j<block_size; ++j)
00577 bits.set(j, getBit(i,j));
00578 return bits;
00579 }
00580
00581 typename std::vector<bool>::reference getBit(size_type i, size_type j) {
00582 return BlocklessBaseClass::operator[](i*block_size+j);
00583 }
00584
00585 typename std::vector<bool>::const_reference getBit(size_type i, size_type j) const {
00586 return BlocklessBaseClass::operator[](i*block_size+j);
00587 }
00588
00589 friend class BitSetVectorReference<block_size,Allocator>;
00590 friend class BitSetVectorConstReference<block_size,Allocator>;
00591 };
00592
00593 }
00594
00595 #endif