bitsetvector.hh

Go to the documentation of this file.
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         // 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         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         // get a prepresentation as value_type
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 }  // namespace Dune
00617 
00618 #endif
Generated on Mon Apr 26 10:45:21 2010 for dune-common by  doxygen 1.6.3