- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 #ifndef DUNE_BLOCK_BITFIELD_HH 00002 #define DUNE_BLOCK_BITFIELD_HH 00003 00008 #include <vector> 00009 #include <bitset> 00010 #include <iostream> 00011 #include <algorithm> 00012 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 // bitset interface typedefs 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 // Sets every bit. 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 size_type 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 count() const 00556 { 00557 return std::count(BlocklessBaseClass::begin(), BlocklessBaseClass::end(), true); 00558 } 00559 00561 size_type countmasked(int j) const 00562 { 00563 size_type n = 0; 00564 size_type blocks = size(); 00565 for(size_type i=0; i<blocks; ++i) 00566 n += getBit(i,j); 00567 return n; 00568 } 00569 00571 friend std::ostream& operator<< (std::ostream& s, const BitSetVector& v) 00572 { 00573 for (size_t i=0; i<v.size(); i++) 00574 s << v[i] << " "; 00575 return s; 00576 } 00577 00578 private: 00579 00580 // get a prepresentation as value_type 00581 value_type getRepr(int i) const 00582 { 00583 value_type bits; 00584 for(int j=0; j<block_size; ++j) 00585 bits.set(j, getBit(i,j)); 00586 return bits; 00587 } 00588 00589 typename std::vector<bool>::reference getBit(size_type i, size_type j) { 00590 return BlocklessBaseClass::operator[](i*block_size+j); 00591 } 00592 00593 typename std::vector<bool>::const_reference getBit(size_type i, size_type j) const { 00594 return BlocklessBaseClass::operator[](i*block_size+j); 00595 } 00596 00597 friend class BitSetVectorReference<block_size,Allocator>; 00598 friend class BitSetVectorConstReference<block_size,Allocator>; 00599 }; 00600 00601 } // namespace Dune 00602 00603 #endif
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].