bitset.hxx

Go to the documentation of this file.
00001 // bitset.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_MISC_BITSET_HXX
00018 # define VCSN_MISC_BITSET_HXX
00019 
00027 # include <vaucanson/misc/bitset.hh>
00028 # include <vaucanson/misc/contract.hh>
00029 
00030 # include <cstdlib>
00031 
00032 namespace utility
00033 {
00034   /*-------.
00035   | Bitset |
00036   `-------*/
00037 
00038   // Default contructors.
00039   inline
00040   Bitset::Bitset(size_type max) : data_size_    (get_data_size(max)),
00041                                   data_         (new data_type[data_size_]),
00042                                   max_size_     (max),
00043                                   size_         (0),
00044                                   end_  (bit_iterator(get_index(max_size_),
00045                                                       get_bitnum(max_size_)))
00046   {
00047     bzero(data_, data_size_ * sizeof (data_type));
00048   }
00049 
00050   inline
00051   Bitset::Bitset(size_type max, const data_type* data)
00052     : data_size_        (get_data_size(max)),
00053       data_             (new data_type[data_size_]),
00054       max_size_         (max),
00055       size_             (invalid_size),
00056       end_              (bit_iterator(get_index(max_size_),
00057                                       get_bitnum(max_size_)))
00058   {
00059     memcpy(data_, data, data_size_ * sizeof (data_type));
00060   }
00061 
00062   // Copy constructor.
00063   inline
00064   Bitset::Bitset(const Bitset& bs) : data_size_ (bs.data_size_),
00065                                      data_      (new data_type[data_size_]),
00066                                      max_size_  (bs.max_size_),
00067                                      size_      (bs.size_),
00068                                      end_       (bs.end_)
00069   {
00070     memcpy(data_, bs.data_, data_size_ * sizeof (data_type));
00071   }
00072 
00073   // Constructor from iterators.
00074   template <class InputIterator>
00075   Bitset::Bitset(InputIterator first, InputIterator last)
00076   {
00077     value_type  max = 0;
00078 
00079     for (InputIterator i = first; i != last; ++i)
00080       {
00081         assertion(*i >= 0);
00082         if (*i > max)
00083           max = *i;
00084       }
00085     data_size_ = get_data_size(max + 1);
00086     data_ = new data_type[data_size_];
00087     bzero(data_, data_size_ * sizeof (data_type));
00088     max_size_ = max + 1;
00089     size_ = 0;
00090     end_ = bit_iterator(get_index(max_size_), get_bitnum(max_size_));
00091     insert(first, last);
00092   }
00093 
00094   // Destructor.
00095   inline
00096   Bitset::~Bitset()
00097   {
00098     delete[] data_;
00099   }
00100 
00101   // Assignment.
00102   inline
00103   Bitset&
00104   Bitset::operator = (const Bitset& rhs)
00105   {
00106     if (this != &rhs)
00107       {
00108         data_size_ = rhs.data_size_;
00109         delete[] data_;
00110         data_ = new data_type[data_size_];
00111         memcpy(data_, rhs.data_, data_size_ * sizeof (data_type));
00112         max_size_ = rhs.max_size_;
00113         size_ = rhs.size_;
00114         end_ = rhs.end_;
00115       }
00116     postcondition(*this == rhs);
00117     return *this;
00118   }
00119 
00120   /*------------.
00121   | Iterators.  |
00122   `------------*/
00123 
00124   // begin
00125   inline
00126   Bitset::iterator
00127   Bitset::begin()
00128   {
00129     return iterator (this);
00130   }
00131 
00132   inline
00133   Bitset::const_iterator
00134   Bitset::begin() const
00135   {
00136     return const_iterator (this);
00137   }
00138 
00139   // end
00140   inline
00141   Bitset::iterator
00142   Bitset::end()
00143   {
00144     return iterator (this, end_);
00145   }
00146 
00147   inline
00148   Bitset::const_iterator
00149   Bitset::end() const
00150   {
00151     return const_iterator (this, end_);
00152   }
00153 
00154   /*--------------------.
00155   | Reverse Iterators.  |
00156   `--------------------*/
00157 
00158   // rbegin
00159   inline
00160   Bitset::reverse_iterator
00161   Bitset::rbegin()
00162   {
00163     return reverse_iterator (end());
00164   }
00165 
00166   inline
00167   Bitset::const_reverse_iterator
00168   Bitset::rbegin() const
00169   {
00170     return const_reverse_iterator (end());
00171   }
00172 
00173   // rend
00174   inline
00175   Bitset::reverse_iterator
00176   Bitset::rend()
00177   {
00178     return reverse_iterator (begin());
00179   }
00180 
00181   inline
00182   Bitset::const_reverse_iterator
00183   Bitset::rend() const
00184   {
00185     return const_reverse_iterator (begin());
00186   }
00187 
00188   /*------------------.
00189   | Misc. functions.  |
00190   `------------------*/
00191 
00192   // empty
00193   inline
00194   bool
00195   Bitset::empty() const
00196   {
00197     return size_ == 0;
00198   }
00199 
00200   // size
00201   inline
00202   Bitset::size_type
00203   Bitset::size() const
00204   {
00205     return size_ == invalid_size ? compute_size() : size_;
00206   }
00207 
00208   // max_size
00209   inline
00210   Bitset::size_type
00211   Bitset::max_size() const
00212   {
00213     return max_size_;
00214   }
00215 
00216   /*-------------.
00217   | Insertions.  |
00218   `-------------*/
00219 
00220   inline
00221   std::pair<Bitset::iterator, bool>
00222   Bitset::insert(const value_type& x)
00223   {
00224     precondition(static_cast<size_type> (x) < max_size_);
00225 
00226     size_type   idx = get_index(x);
00227     size_type   bnm = get_bitnum(x);
00228 
00229     if (get_bit(idx, bnm))
00230       return std::make_pair(end(), false);
00231     else
00232       {
00233         data_[idx] |= (1 << bnm);
00234         if (size_ != invalid_size)
00235           size_++;
00236         return std::make_pair(iterator (this, bit_iterator (idx, bnm)), true);
00237       }
00238   }
00239 
00240   inline
00241   Bitset::iterator
00242   Bitset::insert(iterator, const value_type& x)
00243   {
00244     return insert(x).first;
00245   }
00246 
00247   template <class InputIterator>
00248   void
00249   Bitset::insert(InputIterator first, InputIterator last)
00250   {
00251     while (first != last)
00252       {
00253         insert(*first);
00254         ++first;
00255       }
00256   }
00257 
00258   /*------.
00259   | Erase |
00260   `------*/
00261 
00262   inline
00263   void
00264   Bitset::erase(iterator position)
00265   {
00266     precondition(static_cast<size_type> (*position) < max_size_);
00267 
00268     erase(*position);
00269   }
00270 
00271   inline
00272   Bitset::size_type
00273   Bitset::erase(const key_type& x)
00274   {
00275     precondition(static_cast<size_type> (x) < max_size_);
00276 
00277     size_type   idx = get_index(x);
00278     size_type   bnm = get_bitnum(x);
00279 
00280     if (get_bit(idx, bnm))
00281       {
00282         data_[idx] &= ~(1 << bnm);
00283         if (size_ != invalid_size)
00284           --size_;
00285         return 1;
00286       }
00287     else
00288       return 0;
00289   }
00290 
00291   inline
00292   void
00293   Bitset::erase(iterator first, iterator last)
00294   {
00295     while (first != last)
00296       {
00297         erase(*first);
00298         ++first;
00299       }
00300   }
00301 
00302   /*------------------.
00303   | Misc. functions.  |
00304   `------------------*/
00305 
00306   // swap
00307   inline
00308   void
00309   Bitset::swap(Bitset& other)
00310   {
00311     std::swap(data_size_, other.data_size_);
00312     std::swap(data_, other.data_);
00313     std::swap(max_size_, other.max_size_);
00314     std::swap(size_, other.size_);
00315     std::swap(end_, other.end_);
00316   }
00317 
00318   // clear
00319   inline
00320   void
00321   Bitset::clear()
00322   {
00323     bzero(data_, data_size_ * sizeof (data_type));
00324     size_ = 0;
00325   }
00326 
00327   // key_compare
00328   inline
00329   Bitset::key_compare
00330   Bitset::key_comp() const
00331   {
00332     return key_compare ();
00333   }
00334 
00335   // value_compare
00336   inline
00337   Bitset::value_compare
00338   Bitset::value_comp() const
00339   {
00340     return value_compare ();
00341   }
00342 
00343   // find
00344   inline
00345   Bitset::iterator
00346   Bitset::find(const key_type& x) const
00347   {
00348     precondition(static_cast<size_type> (x) < max_size_);
00349 
00350     bit_iterator        it(get_index(x), get_bitnum(x));
00351     if (get_bit(it))
00352       return iterator (this, it);
00353     else
00354       return iterator (this, end_);
00355   }
00356 
00357   // count
00358   inline
00359   Bitset::size_type
00360   Bitset::count(const key_type& x) const
00361   {
00362     precondition(static_cast<size_type> (x) < max_size_);
00363 
00364     return get_bit(get_index(x), get_bitnum(x)) ? 1 : 0;
00365   }
00366 
00367   // lower_bound
00368   inline
00369   Bitset::iterator
00370   Bitset::lower_bound(const key_type& x) const
00371   {
00372     precondition(static_cast<size_type> (x) < max_size_);
00373 
00374     bit_iterator        it(get_index(x), get_bitnum(x));
00375 
00376     while ((it != bit_end()) && !get_bit(it))
00377       ++it;
00378     return iterator (this, it);
00379   }
00380 
00381   // upper_bound
00382   inline
00383   Bitset::iterator
00384   Bitset::upper_bound(const key_type& x) const
00385   {
00386     precondition(static_cast<size_type> (x) < max_size_);
00387 
00388     bit_iterator        it(get_index(x), get_bitnum(x));
00389 
00390     if (it == bit_begin())
00391       return iterator (this, end_);
00392     else
00393       {
00394         do
00395           {
00396             --it;
00397           }
00398         while ((it != bit_begin()) && !get_bit(it));
00399         return iterator (this, get_bit(it) ? it : end_);
00400       }
00401   }
00402 
00403   // equal_range
00404   inline
00405   std::pair<Bitset::iterator, Bitset::iterator>
00406   Bitset::equal_range(const key_type& x) const
00407   {
00408     // FIXME: Could be optimized.
00409     return std::make_pair(lower_bound(x), upper_bound(x));
00410   }
00411 
00412   /*------------.
00413   | Operators.  |
00414   `------------*/
00415 
00416   inline
00417   bool
00418   Bitset::operator == (const Bitset& rhs) const
00419   {
00420     if (rhs.data_size_ < data_size_)
00421       return rhs.operator == (*this);
00422     else
00423       {
00424         for (size_type i = 0; i < data_size_; ++i)
00425           if (data_[i] != rhs.data_[i])
00426             return false;
00427         for (size_type i = data_size_; i < rhs.data_size_; ++i)
00428           if (rhs.data_[i])
00429             return false;
00430         return true;
00431       }
00432   }
00433 
00434   inline
00435   bool
00436   Bitset::operator < (const Bitset& rhs) const
00437   {
00438     // Case 1: rhs is longer than *this.
00439     for (size_type i = rhs.data_size_ - 1; i >= data_size_; ++i)
00440       if (rhs.data_[i])
00441         return true;
00442     // Case 2: *this is longer than rhs.
00443     for (size_type i = data_size_ - 1; i >= rhs.data_size_; ++i)
00444       if (data_[i])
00445         return false;
00446     // Common case: compare the bits rhs and *this have in common.
00447     for (int i = std::min(data_size_, rhs.data_size_) - 1; i >= 0; ++i)
00448       if (rhs.data_[i] != data_[i])
00449         return rhs.data_[i] > data_[i];
00450     // If we get out from the previous loop, then the bitsets are equals.
00451     return false;
00452   }
00453 
00454   inline
00455   bool
00456   Bitset::operator != (const Bitset& rhs) const
00457   {
00458     return !(*this == rhs);
00459   }
00460 
00461   inline
00462   bool
00463   Bitset::operator > (const Bitset& rhs) const
00464   {
00465     return rhs < *this;
00466   }
00467 
00468   inline
00469   bool
00470   Bitset::operator <= (const Bitset& rhs) const
00471   {
00472     return !(*this > rhs);
00473   }
00474 
00475   inline
00476   bool
00477   Bitset::operator >= (const Bitset& rhs) const
00478   {
00479     return !(*this < rhs);
00480   }
00481 
00482   inline
00483   Bitset
00484   Bitset::operator & (const Bitset& rhs) const
00485   {
00486     const size_type     r_data_size = std::min(data_size_, rhs.data_size_);
00487     const size_type     r_max_size = std::min(max_size_, rhs.max_size_);
00488     Bitset              result (r_max_size);
00489 
00490     for (size_type i = 0; i < r_data_size; ++i)
00491       {
00492         result.data_[i] = data_[i] & rhs.data_[i];
00493         if (result.data_[i])
00494           result.size_ = invalid_size;
00495       }
00496     return result;
00497   }
00498 
00499   inline
00500   Bitset
00501   Bitset::operator | (const Bitset& rhs) const
00502   {
00503     if (rhs.data_size_ < data_size_)
00504       return rhs.operator | (*this);
00505     else
00506       {
00507         Bitset  result (rhs.max_size_);
00508 
00509         for (size_type i = 0; i < data_size_; ++i)
00510           {
00511             result.data_[i] = data_[i] | rhs.data_[i];
00512             if (result.data_[i])
00513               result.size_ = invalid_size;
00514           }
00515         for (size_type i = data_size_; i < rhs.data_size_; ++i)
00516           {
00517             result.data_[i] = rhs.data_[i];
00518             if (result.data_[i])
00519               result.size_ = invalid_size;
00520           }
00521         return result;
00522       }
00523   }
00524 
00525   inline
00526   bool
00527   Bitset::operator [] (const key_type& x) const
00528   {
00529     return count(x);
00530   }
00531 
00532   /*------------------------------.
00533   | Projection and Unprojection.  |
00534   `------------------------------*/
00535 
00536   inline
00537   Bitset
00538   Bitset::project(const Bitset& b) const
00539   {
00540     BitActionCount<int, -1, 1> bit_counter;
00541     Bitset result(b.size());
00542 
00543     for (bit_iterator it = bit_begin();
00544          (it != bit_end()) && (it != b.bit_end());
00545          ++it)
00546       {
00547         if (b.do_on_bit(bit_counter, it) && get_bit(it))
00548           result.insert(bit_counter.value);
00549       }
00550     return result;
00551   }
00552 
00553   inline
00554   Bitset
00555   Bitset::unproject(const Bitset& b) const
00556   {
00557     BitActionCount<int, 0, 1> bit_counter;
00558     Bitset result(b.max_size());
00559     bit_iterator b_it = b.bit_begin();
00560 
00561     while ((b_it != b.bit_end()) && !b.get_bit(b_it))
00562       ++b_it;
00563     for (bit_iterator it = bit_begin(); it != bit_end(); ++it)
00564       if (get_bit(it))
00565         {
00566           while ((b_it != b.bit_end()) && (bit_counter.value < *it))
00567             b.do_on_bit(bit_counter, ++b_it);
00568           assertion(bit_counter.value == *it);
00569           result.insert(*b_it);
00570         }
00571     return result;
00572   }
00573 
00574   /*--------.
00575   | Casts.  |
00576   `--------*/
00577 
00578   inline
00579   unsigned
00580   Bitset::to_unsigned() const
00581   {
00582     return cast<unsigned>();
00583   }
00584 
00585   template <class Type>
00586   const Type
00587   Bitset::cast() const
00588   {
00589     const Type* ptr = reinterpret_cast<const Type*> (data_);
00590     return *ptr;
00591   }
00592 
00593   /*--------.
00594   | Print.  |
00595   `--------*/
00596 
00597   inline
00598   std::ostream&
00599   Bitset::print(std::ostream& ostr) const
00600   {
00601     ostr << "{ ";
00602     for (Bitset::bit_iterator it = bit_begin(); it != bit_end(); ++it)
00603       if (get_bit(it))
00604         ostr << *it << ' ';
00605     return ostr << "}";
00606   }
00607 
00608   /*------------------.
00609   | Protected stuff.  |
00610   `------------------*/
00611 
00612   // get_data_size
00613   inline
00614   Bitset::size_type
00615   Bitset::get_data_size(size_type max)
00616   {
00617     precondition(max > 0);
00618 
00619     const size_type data_bits = sizeof (data_type) * 8;
00620     return max / data_bits + (max % data_bits ? 1 : 0);
00621   }
00622 
00623   // get_index
00624   inline
00625   Bitset::size_type
00626   Bitset::get_index(const key_type& x)
00627   {
00628     return x / (sizeof (data_type) * 8);
00629   }
00630 
00631   // get_bitnum
00632   inline
00633   Bitset::size_type
00634   Bitset::get_bitnum(const key_type& x)
00635   {
00636     return x % (sizeof (data_type) * 8);
00637   }
00638 
00639   // get_bit
00640   inline
00641   bool
00642   Bitset::get_bit(size_type index, size_type bit) const
00643   {
00644     return (data_[index] & (1 << bit)) != 0;
00645   }
00646 
00647   inline
00648   bool
00649   Bitset::get_bit(const bit_iterator& it) const
00650   {
00651     return get_bit(it.get_index(), it.get_bitnum());
00652   }
00653 
00654   // compute_size
00655   inline
00656   Bitset::size_type
00657   Bitset::compute_size() const
00658   {
00659     BitActionCount<int, 0, 1> bc;
00660     for (bit_iterator it = bit_begin(); it != bit_end(); ++it)
00661       do_on_bit(bc, it);
00662     return size_ = bc.value;
00663   }
00664 
00665   /*---------------.
00666   | Bit iterator.  |
00667   `---------------*/
00668 
00669   // constructors.
00670   inline
00671   Bitset::
00672   bit_iterator::bit_iterator(size_type index, size_type bitnum) :
00673     index_      (index),
00674     bitnum_     (bitnum),
00675     value_      (index_ * sizeof (data_type) * 8 + bitnum_)
00676   {
00677   }
00678 
00679   // operators.
00680   inline
00681   const Bitset::bit_iterator&
00682   Bitset::bit_iterator::operator -- ()
00683   {
00684     --value_;
00685     if (bitnum_)
00686       --bitnum_;
00687     else
00688       {
00689         bitnum_ = sizeof (data_type) * 8 - 1;
00690         --index_;
00691       }
00692     return (*this);
00693   }
00694 
00695   inline
00696   const Bitset::bit_iterator&
00697   Bitset::bit_iterator::operator ++ ()
00698   {
00699     ++value_;
00700     if (++bitnum_ >= sizeof (data_type) * 8)
00701       {
00702         bitnum_ = 0;
00703         ++index_;
00704       }
00705     return *this;
00706   }
00707 
00708   inline
00709   Bitset::value_type
00710   Bitset::bit_iterator::operator * () const
00711   {
00712     return value_;
00713   }
00714 
00715   inline
00716   bool
00717   Bitset::bit_iterator::operator == (const bit_iterator& rhs) const
00718   {
00719     return rhs.value_ == value_;
00720   }
00721 
00722   inline
00723   bool
00724   Bitset::bit_iterator::operator != (const bit_iterator& rhs) const
00725   {
00726     return !(*this == rhs);
00727   }
00728 
00729   // get_index
00730   inline
00731   Bitset::size_type
00732   Bitset::bit_iterator::get_index() const
00733   {
00734     return index_;
00735   }
00736 
00737   // get_bitnum
00738   inline
00739   Bitset::size_type
00740   Bitset::bit_iterator::get_bitnum() const
00741   {
00742     return bitnum_;
00743   }
00744 
00745   // bit_begin
00746   inline
00747   Bitset::bit_iterator
00748   Bitset::bit_begin() const
00749   {
00750     return bit_iterator ();
00751   }
00752 
00753   // bit_end
00754   inline
00755   const Bitset::bit_iterator&
00756   Bitset::bit_end() const
00757   {
00758     return end_;
00759   }
00760 
00761   /*--------------.
00762   | Bit actions.  |
00763   `--------------*/
00764 
00765   // Count
00766   template <typename CountType, CountType Start, CountType Step>
00767   Bitset::
00768   BitActionCount<CountType, Start, Step>::BitActionCount() : value(Start)
00769   {
00770   }
00771 
00772   template <typename CountType, CountType Start, CountType Step>
00773   bool
00774   Bitset::
00775   BitActionCount<CountType, Start, Step>::operator () (const Bitset&,
00776                                                        size_type,
00777                                                        size_type,
00778                                                        bool val)
00779   {
00780     if (val)
00781       value += Step;
00782     return val;
00783   }
00784 
00785   /*------------.
00786   | do_on_bit.  |
00787   `------------*/
00788 
00789   // non-const
00790   template <class BitAction>
00791   bool
00792   Bitset::do_on_bit(BitAction& action, const key_type& x)
00793   {
00794     precondition(x < max_size_);
00795 
00796     const size_type index       = get_index(x);
00797     const size_type bit         = get_bitnum(x);
00798     const bool value            = get_bit(index, bit);
00799     return action(*this, index, bit, value);
00800   }
00801 
00802   template <class BitAction>
00803   bool
00804   Bitset::do_on_bit(BitAction& action, const bit_iterator& it)
00805   {
00806     return action(*this, it.get_index(), it.get_bitnum(), get_bit(it));
00807   }
00808 
00809   // const
00810   template <class ConstBitAction>
00811   bool
00812   Bitset::do_on_bit(ConstBitAction& action, const key_type& x) const
00813   {
00814     precondition(x < max_size_);
00815 
00816     const size_type index       = get_index(x);
00817     const size_type bit         = get_bitnum(x);
00818     const bool value            = get_bit(index, bit);
00819     return action(*this, index, bit, value);
00820   }
00821 
00822   template <class ConstBitAction>
00823   bool
00824   Bitset::do_on_bit(ConstBitAction& action, const bit_iterator& it) const
00825   {
00826     return action(*this, it.get_index(), it.get_bitnum(), get_bit(it));
00827   }
00828 
00829   /*---------------.
00830   | const_iterator |
00831   `---------------*/
00832 
00833   // Default constructors.
00834   inline
00835   Bitset::const_iterator::const_iterator() : bs_ (0), cbit_ ()
00836   {
00837     warning("The constructor Bitset::const_iterator::const_iterator() "
00838             "is dangerous and therefore should not be used.");
00839   }
00840 
00841   inline
00842   Bitset::const_iterator::const_iterator(const Bitset* bs) : bs_(bs),
00843                                                              cbit_()
00844   {
00845     skip_zeros_forward();
00846   }
00847 
00848   inline
00849   Bitset::const_iterator::const_iterator(const Bitset* bs,
00850                                          const bit_iterator& cbit)
00851     : bs_(bs),
00852       cbit_(cbit)
00853   {
00854     skip_zeros_forward();
00855   }
00856 
00857   // Copy constructors.
00858   inline
00859   Bitset::const_iterator::const_iterator(const const_iterator& it)
00860     : bs_(it.bs_), cbit_(it.cbit_)
00861   {
00862   }
00863 
00864   inline
00865   Bitset::const_iterator::const_iterator(const iterator& it)
00866     : bs_(it.bs_), cbit_(it.cbit_)
00867   {
00868   }
00869 
00870   // Operators.
00871   inline
00872   const Bitset::const_iterator&
00873   Bitset::const_iterator::operator ++ ()
00874   {
00875     ++cbit_;
00876     skip_zeros_forward();
00877     return *this;
00878   }
00879 
00880   inline
00881   Bitset::const_iterator
00882   Bitset::const_iterator::operator ++ (int)
00883   {
00884     const_iterator ret(*this);
00885 
00886     operator ++ ();
00887     return ret;
00888   }
00889 
00890   inline
00891   const Bitset::const_iterator&
00892   Bitset::const_iterator::operator -- ()
00893   {
00894     --cbit_;
00895     skip_zeros_backward();
00896     return *this;
00897   }
00898 
00899   inline
00900   Bitset::const_iterator
00901   Bitset::const_iterator::operator -- (int)
00902   {
00903     const_iterator ret (*this);
00904 
00905     operator -- ();
00906     return ret;
00907   }
00908 
00909   inline
00910   bool
00911   Bitset::const_iterator::operator == (const const_iterator& rhs) const
00912   {
00913     return *(*this) == *rhs;
00914   }
00915 
00916   inline
00917   bool
00918   Bitset::const_iterator::operator == (const iterator& rhs) const
00919   {
00920     return *(*this) == *rhs;
00921   }
00922 
00923   inline
00924   bool
00925   Bitset::const_iterator::operator != (const const_iterator& rhs) const
00926   {
00927     return !(*this == rhs);
00928   }
00929 
00930   inline
00931   bool
00932   Bitset::const_iterator::operator != (const iterator& rhs) const
00933   {
00934     return !(*this == rhs);
00935   }
00936 
00937   inline
00938   Bitset::value_type
00939   Bitset::const_iterator::operator * () const
00940   {
00941     return *cbit_;
00942   }
00943 
00944   inline
00945   void
00946   Bitset::const_iterator::skip_zeros_forward()
00947   {
00948     precondition(bs_ != 0);
00949 
00950     while ((cbit_ != bs_->bit_end()) && !bs_->get_bit(cbit_))
00951       ++cbit_;
00952   }
00953 
00954   inline
00955   void
00956   Bitset::const_iterator::skip_zeros_backward()
00957   {
00958     precondition(bs_ != 0);
00959 
00960     while ((cbit_ != bs_->bit_begin()) && !bs_->get_bit(cbit_))
00961       --cbit_;
00962   }
00963 
00964   /*---------.
00965   | iterator |
00966   `---------*/
00967 
00968   // Default constructors.
00969   inline
00970   Bitset::iterator::iterator() : bs_ (0), cbit_ ()
00971   {
00972     warning("The constructor Bitset::iterator::iterator() is dangerous "
00973             "and therefore should not be used.");
00974   }
00975 
00976   inline
00977   Bitset::iterator::iterator(const Bitset* bs)
00978     : bs_(bs),
00979       cbit_()
00980   {
00981     skip_zeros_forward();
00982   }
00983 
00984   inline
00985   Bitset::iterator::iterator(const Bitset* bs, const bit_iterator& cbit)
00986     : bs_(bs),
00987       cbit_(cbit)
00988   {
00989     skip_zeros_forward();
00990   }
00991 
00992   // Copy constructor.
00993   inline
00994   Bitset::iterator::iterator(const iterator& it) : bs_(it.bs_), cbit_(it.cbit_)
00995   {
00996   }
00997 
00998   // Operators
00999   inline
01000   const Bitset::iterator&
01001   Bitset::iterator::operator ++ ()
01002   {
01003     ++cbit_;
01004     skip_zeros_forward();
01005     return *this;
01006   }
01007 
01008   inline
01009   Bitset::iterator
01010   Bitset::iterator::operator ++ (int)
01011   {
01012     iterator res(*this);
01013 
01014     operator ++ ();
01015     return res;
01016   }
01017 
01018   inline
01019   const Bitset::iterator&
01020   Bitset::iterator::operator -- ()
01021   {
01022     --cbit_;
01023     skip_zeros_backward();
01024     return *this;
01025   }
01026 
01027   inline
01028   Bitset::iterator
01029   Bitset::iterator::operator -- (int)
01030   {
01031     iterator res (*this);
01032 
01033     operator -- ();
01034     return res;
01035   }
01036 
01037   inline
01038   bool
01039   Bitset::iterator::operator == (const iterator& rhs) const
01040   {
01041     return *(*this) == *rhs;
01042   }
01043 
01044   inline
01045   bool
01046   Bitset::iterator::operator == (const const_iterator& rhs) const
01047   {
01048     return *(*this) == *rhs;
01049   }
01050 
01051   inline
01052   bool
01053   Bitset::iterator::operator != (const iterator& rhs) const
01054   {
01055     return !(*this == rhs);
01056   }
01057 
01058   inline
01059   bool
01060   Bitset::iterator::operator != (const const_iterator& rhs) const
01061   {
01062     return !(*this == rhs);
01063   }
01064 
01065   inline
01066   Bitset::value_type
01067   Bitset::iterator::operator * () const
01068   {
01069     return *cbit_;
01070   }
01071 
01072   inline
01073   void
01074   Bitset::iterator::skip_zeros_forward()
01075   {
01076     precondition(bs_ != 0);
01077 
01078     while ((cbit_ != bs_->bit_end()) && !bs_->get_bit(cbit_))
01079       ++cbit_;
01080   }
01081 
01082   inline
01083   void
01084   Bitset::iterator::skip_zeros_backward()
01085   {
01086     precondition(bs_ != 0);
01087 
01088     while ((cbit_ != bs_->bit_begin()) && !bs_->get_bit(cbit_))
01089       --cbit_;
01090   }
01091 
01092   inline
01093   std::ostream&
01094   operator << (std::ostream& ostr, const Bitset& set)
01095   {
01096     return set.print(ostr);
01097   }
01098 
01099 } // namespace bts
01100 
01101 namespace std
01102 {
01103   template <>
01104   inline
01105   void swap(utility::Bitset& lhs, utility::Bitset& rhs)
01106   {
01107     lhs.swap(rhs);
01108   }
01109 
01110   inline
01111   insert_iterator<utility::Bitset>::insert_iterator(utility::Bitset& x,
01112                                                     utility::Bitset::iterator)
01113   {
01114     container = &x;
01115   }
01116 
01117   inline
01118   insert_iterator<utility::Bitset>&
01119   insert_iterator<utility::Bitset>::operator = (utility::Bitset::
01120                                                 const_reference value)
01121   {
01122     container->insert(value);
01123     return *this;
01124   }
01125 
01126   inline
01127   insert_iterator<utility::Bitset>&
01128   insert_iterator<utility::Bitset>::operator * ()
01129   {
01130     return *this;
01131   }
01132 
01133   inline
01134   insert_iterator<utility::Bitset>&
01135   insert_iterator<utility::Bitset>::operator ++ ()
01136   {
01137     return *this;
01138   }
01139 
01140   inline
01141   insert_iterator<utility::Bitset>&
01142   insert_iterator<utility::Bitset>::operator ++ (int)
01143   {
01144     return *this;
01145   }
01146 }
01147 
01148 #endif // ! VCSN_MISC_BITSET_HXX

Generated on Fri Jul 28 12:18:30 2006 for Vaucanson by  doxygen 1.4.6