Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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

Generated on Mon Jul 24 16:56:37 2006 for Vaucanson by  doxygen 1.4.4