Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

std_bitset.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1998
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Permission to use, copy, modify, distribute and sell this software
00006  * and its documentation for any purpose is hereby granted without fee,
00007  * provided that the above copyright notice appear in all copies and
00008  * that both that copyright notice and this permission notice appear
00009  * in supporting documentation.  Silicon Graphics makes no
00010  * representations about the suitability of this software for any
00011  * purpose.  It is provided "as is" without express or implied warranty.
00012  */ 
00013 
00014 #ifndef __SGI_STL_BITSET
00015 #define __SGI_STL_BITSET
00016 
00017 #pragma GCC system_header
00018 
00019 // A bitset of size N has N % (sizeof(unsigned long) * CHAR_BIT) unused 
00020 // bits.  (They are the high- order bits in the highest word.)  It is
00021 // a class invariant of class bitset<> that those unused bits are
00022 // always zero.
00023 
00024 // Most of the actual code isn't contained in bitset<> itself, but in the 
00025 // base class _Base_bitset.  The base class works with whole words, not with
00026 // individual bits.  This allows us to specialize _Base_bitset for the
00027 // important special case where the bitset is only a single word.
00028 
00029 // The C++ standard does not define the precise semantics of operator[].
00030 // In this implementation the const version of operator[] is equivalent
00031 // to test(), except that it does no range checking.  The non-const version
00032 // returns a reference to a bit, again without doing any range checking.
00033 
00034 
00035 #include <bits/std_cstddef.h>     // for size_t
00036 #include <bits/std_cstring.h>     // for memset
00037 #include <bits/std_string.h>
00038 #include <bits/std_stdexcept.h>   // for invalid_argument, out_of_range, 
00039                   // overflow_error
00040 
00041 #include <bits/std_ostream.h>     // for ostream (operator<<)
00042 #include <bits/std_istream.h>     // for istream (operator>>)
00043 
00044 #define _GLIBCPP_BITSET_BITS_PER_WORD (CHAR_BIT*sizeof(unsigned long))
00045 #define __BITSET_WORDS(__n) \
00046  ((__n) < 1 ? 1 : ((__n) + _GLIBCPP_BITSET_BITS_PER_WORD - 1)/_GLIBCPP_BITSET_BITS_PER_WORD)
00047 
00048 namespace std
00049 {
00050 
00051 // structure to aid in counting bits
00052 template<bool __dummy> 
00053 struct _Bit_count {
00054   static unsigned char _S_bit_count[256];
00055 };
00056 
00057 // Mapping from 8 bit unsigned integers to the index of the first one
00058 // bit:
00059 template<bool __dummy> 
00060 struct _First_one {
00061   static unsigned char _S_first_one[256];
00062 };
00063 
00064 //
00065 // Base class: general case.
00066 //
00067 
00068 template<size_t _Nw>
00069 struct _Base_bitset {
00070   typedef unsigned long _WordT;
00071 
00072   _WordT _M_w[_Nw];                // 0 is the least significant word.
00073 
00074   _Base_bitset( void ) { _M_do_reset(); }
00075   _Base_bitset(unsigned long __val) {
00076     _M_do_reset();
00077     _M_w[0] = __val;
00078   }
00079 
00080   static size_t _S_whichword( size_t __pos )
00081     { return __pos / _GLIBCPP_BITSET_BITS_PER_WORD; }
00082   static size_t _S_whichbyte( size_t __pos )
00083     { return (__pos % _GLIBCPP_BITSET_BITS_PER_WORD) / CHAR_BIT; }
00084   static size_t _S_whichbit( size_t __pos )
00085     { return __pos % _GLIBCPP_BITSET_BITS_PER_WORD; }
00086   static _WordT _S_maskbit( size_t __pos )
00087     { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
00088 
00089   _WordT& _M_getword(size_t __pos)       { return _M_w[_S_whichword(__pos)]; }
00090   _WordT  _M_getword(size_t __pos) const { return _M_w[_S_whichword(__pos)]; }
00091 
00092   _WordT& _M_hiword()       { return _M_w[_Nw - 1]; }
00093   _WordT  _M_hiword() const { return _M_w[_Nw - 1]; }
00094 
00095   void _M_do_and(const _Base_bitset<_Nw>& __x) {
00096     for ( size_t __i = 0; __i < _Nw; __i++ ) {
00097       _M_w[__i] &= __x._M_w[__i];
00098     }
00099   }
00100 
00101   void _M_do_or(const _Base_bitset<_Nw>& __x) {
00102     for ( size_t __i = 0; __i < _Nw; __i++ ) {
00103       _M_w[__i] |= __x._M_w[__i];
00104     }
00105   }
00106 
00107   void _M_do_xor(const _Base_bitset<_Nw>& __x) {
00108     for ( size_t __i = 0; __i < _Nw; __i++ ) {
00109       _M_w[__i] ^= __x._M_w[__i];
00110     }
00111   }
00112 
00113   void _M_do_left_shift(size_t __shift);
00114   void _M_do_right_shift(size_t __shift);
00115 
00116   void _M_do_flip() {
00117     for ( size_t __i = 0; __i < _Nw; __i++ ) {
00118       _M_w[__i] = ~_M_w[__i];
00119     }
00120   }
00121 
00122   void _M_do_set() {
00123     for ( size_t __i = 0; __i < _Nw; __i++ ) {
00124       _M_w[__i] = ~static_cast<_WordT>(0);
00125     }
00126   }
00127 
00128   void _M_do_reset() { memset(_M_w, 0, _Nw * sizeof(_WordT)); }
00129 
00130   bool _M_is_equal(const _Base_bitset<_Nw>& __x) const {
00131     for (size_t __i = 0; __i < _Nw; ++__i) {
00132       if (_M_w[__i] != __x._M_w[__i])
00133         return false;
00134     }
00135     return true;
00136   }
00137 
00138   bool _M_is_any() const {
00139     for ( size_t __i = 0; __i < _Nw; __i++ ) {
00140       if ( _M_w[__i] != static_cast<_WordT>(0) )
00141         return true;
00142     }
00143     return false;
00144   }
00145 
00146   size_t _M_do_count() const {
00147     size_t __result = 0;
00148     const unsigned char* __byte_ptr = (const unsigned char*)_M_w;
00149     const unsigned char* __end_ptr = (const unsigned char*)(_M_w+_Nw);
00150 
00151     while ( __byte_ptr < __end_ptr ) {
00152       __result += _Bit_count<true>::_S_bit_count[*__byte_ptr];
00153       __byte_ptr++;
00154     }
00155     return __result;
00156   }
00157 
00158   unsigned long _M_do_to_ulong() const; 
00159 
00160   // find first "on" bit
00161   size_t _M_do_find_first(size_t __not_found) const;
00162 
00163   // find the next "on" bit that follows "prev"
00164   size_t _M_do_find_next(size_t __prev, size_t __not_found) const;
00165 };
00166 
00167 //
00168 // Definitions of non-inline functions from _Base_bitset.
00169 // 
00170 
00171 template<size_t _Nw>
00172 void _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift) 
00173 {
00174   if (__shift != 0) {
00175     const size_t __wshift = __shift / _GLIBCPP_BITSET_BITS_PER_WORD;
00176     const size_t __offset = __shift % _GLIBCPP_BITSET_BITS_PER_WORD;
00177 
00178     if (__offset == 0)
00179       for (size_t __n = _Nw - 1; __n >= __wshift; --__n)
00180         _M_w[__n] = _M_w[__n - __wshift];
00181 
00182     else {
00183       const size_t __sub_offset = _GLIBCPP_BITSET_BITS_PER_WORD - __offset;
00184       for (size_t __n = _Nw - 1; __n > __wshift; --__n)
00185         _M_w[__n] = (_M_w[__n - __wshift] << __offset) | 
00186                     (_M_w[__n - __wshift - 1] >> __sub_offset);
00187       _M_w[__wshift] = _M_w[0] << __offset;
00188     }
00189 
00190     fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0));
00191   }
00192 }
00193 
00194 template<size_t _Nw>
00195 void _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift) 
00196 {
00197   if (__shift != 0) {
00198     const size_t __wshift = __shift / _GLIBCPP_BITSET_BITS_PER_WORD;
00199     const size_t __offset = __shift % _GLIBCPP_BITSET_BITS_PER_WORD;
00200     const size_t __limit = _Nw - __wshift - 1;
00201 
00202     if (__offset == 0)
00203       for (size_t __n = 0; __n <= __limit; ++__n)
00204         _M_w[__n] = _M_w[__n + __wshift];
00205 
00206     else {
00207       const size_t __sub_offset = _GLIBCPP_BITSET_BITS_PER_WORD - __offset;
00208       for (size_t __n = 0; __n < __limit; ++__n)
00209         _M_w[__n] = (_M_w[__n + __wshift] >> __offset) |
00210                     (_M_w[__n + __wshift + 1] << __sub_offset);
00211       _M_w[__limit] = _M_w[_Nw-1] >> __offset;
00212     }
00213 
00214     fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0));
00215   }
00216 }
00217 
00218 template<size_t _Nw>
00219 unsigned long _Base_bitset<_Nw>::_M_do_to_ulong() const
00220 {
00221   for (size_t __i = 1; __i < _Nw; ++__i) 
00222     if (_M_w[__i]) 
00223       __STL_THROW(overflow_error("bitset"));
00224   
00225   return _M_w[0];
00226 }
00227 
00228 template<size_t _Nw>
00229 size_t _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const 
00230 {
00231   for ( size_t __i = 0; __i < _Nw; __i++ ) {
00232     _WordT __thisword = _M_w[__i];
00233     if ( __thisword != static_cast<_WordT>(0) ) {
00234       // find byte within word
00235       for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) {
00236         unsigned char __this_byte
00237           = static_cast<unsigned char>(__thisword & (~(unsigned char)0));
00238         if ( __this_byte )
00239           return __i*_GLIBCPP_BITSET_BITS_PER_WORD + __j*CHAR_BIT +
00240             _First_one<true>::_S_first_one[__this_byte];
00241 
00242         __thisword >>= CHAR_BIT;
00243       }
00244     }
00245   }
00246   // not found, so return an indication of failure.
00247   return __not_found;
00248 }
00249 
00250 template<size_t _Nw>
00251 size_t
00252 _Base_bitset<_Nw>::_M_do_find_next(size_t __prev, size_t __not_found) const
00253 {
00254   // make bound inclusive
00255   ++__prev;
00256 
00257   // check out of bounds
00258   if ( __prev >= _Nw * _GLIBCPP_BITSET_BITS_PER_WORD )
00259     return __not_found;
00260 
00261     // search first word
00262   size_t __i = _S_whichword(__prev);
00263   _WordT __thisword = _M_w[__i];
00264 
00265     // mask off bits below bound
00266   __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev);
00267 
00268   if ( __thisword != static_cast<_WordT>(0) ) {
00269     // find byte within word
00270     // get first byte into place
00271     __thisword >>= _S_whichbyte(__prev) * CHAR_BIT;
00272     for ( size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++ ) {
00273       unsigned char __this_byte
00274         = static_cast<unsigned char>(__thisword & (~(unsigned char)0));
00275       if ( __this_byte )
00276         return __i*_GLIBCPP_BITSET_BITS_PER_WORD + __j*CHAR_BIT +
00277           _First_one<true>::_S_first_one[__this_byte];
00278 
00279       __thisword >>= CHAR_BIT;
00280     }
00281   }
00282 
00283   // check subsequent words
00284   __i++;
00285   for ( ; __i < _Nw; __i++ ) {
00286     __thisword = _M_w[__i];
00287     if ( __thisword != static_cast<_WordT>(0) ) {
00288       // find byte within word
00289       for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) {
00290         unsigned char __this_byte
00291           = static_cast<unsigned char>(__thisword & (~(unsigned char)0));
00292         if ( __this_byte )
00293           return __i*_GLIBCPP_BITSET_BITS_PER_WORD + __j*CHAR_BIT +
00294             _First_one<true>::_S_first_one[__this_byte];
00295 
00296         __thisword >>= CHAR_BIT;
00297       }
00298     }
00299   }
00300 
00301   // not found, so return an indication of failure.
00302   return __not_found;
00303 } // end _M_do_find_next
00304 
00305 
00306 // ------------------------------------------------------------
00307 
00308 //
00309 // Base class: specialization for a single word.
00310 //
00311 
00312 template<> struct _Base_bitset<1> {
00313   typedef unsigned long _WordT;
00314   _WordT _M_w;
00315 
00316   _Base_bitset( void ) : _M_w(0) {}
00317   _Base_bitset(unsigned long __val) : _M_w(__val) {}
00318 
00319   static size_t _S_whichword( size_t __pos )
00320     { return __pos / _GLIBCPP_BITSET_BITS_PER_WORD; }
00321   static size_t _S_whichbyte( size_t __pos )
00322     { return (__pos % _GLIBCPP_BITSET_BITS_PER_WORD) / CHAR_BIT; }
00323   static size_t _S_whichbit( size_t __pos )
00324     {  return __pos % _GLIBCPP_BITSET_BITS_PER_WORD; }
00325   static _WordT _S_maskbit( size_t __pos )
00326     { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
00327 
00328   _WordT& _M_getword(size_t)       { return _M_w; }
00329   _WordT  _M_getword(size_t) const { return _M_w; }
00330 
00331   _WordT& _M_hiword()       { return _M_w; }
00332   _WordT  _M_hiword() const { return _M_w; }
00333 
00334   void _M_do_and(const _Base_bitset<1>& __x) { _M_w &= __x._M_w; }
00335   void _M_do_or(const _Base_bitset<1>& __x)  { _M_w |= __x._M_w; }
00336   void _M_do_xor(const _Base_bitset<1>& __x) { _M_w ^= __x._M_w; }
00337   void _M_do_left_shift(size_t __shift)     { _M_w <<= __shift; }
00338   void _M_do_right_shift(size_t __shift)    { _M_w >>= __shift; }
00339   void _M_do_flip()                       { _M_w = ~_M_w; }
00340   void _M_do_set()                        { _M_w = ~static_cast<_WordT>(0); }
00341   void _M_do_reset()                      { _M_w = 0; }
00342 
00343   bool _M_is_equal(const _Base_bitset<1>& __x) const
00344     { return _M_w == __x._M_w; }
00345   bool _M_is_any() const
00346     { return _M_w != 0; }
00347 
00348   size_t _M_do_count() const {
00349     size_t __result = 0;
00350     const unsigned char* __byte_ptr = (const unsigned char*)&_M_w;
00351     const unsigned char* __end_ptr
00352       = ((const unsigned char*)&_M_w)+sizeof(_M_w);
00353     while ( __byte_ptr < __end_ptr ) {
00354       __result += _Bit_count<true>::_S_bit_count[*__byte_ptr];
00355       __byte_ptr++;
00356     }
00357     return __result;
00358   }
00359 
00360   unsigned long _M_do_to_ulong() const { return _M_w; }
00361 
00362   size_t _M_do_find_first(size_t __not_found) const;
00363 
00364   // find the next "on" bit that follows "prev"
00365   size_t _M_do_find_next(size_t __prev, size_t __not_found) const; 
00366 
00367 };
00368 
00369 
00370 // ------------------------------------------------------------
00371 // Helper class to zero out the unused high-order bits in the highest word.
00372 
00373 template <size_t _Extrabits> struct _Sanitize {
00374   static void _M_do_sanitize(unsigned long& __val)
00375     { __val &= ~((~static_cast<unsigned long>(0)) << _Extrabits); }
00376 };
00377 
00378 template<> struct _Sanitize<0> {
00379   static void _M_do_sanitize(unsigned long) {}
00380 };
00381 
00382 
00383 
00384 // ------------------------------------------------------------
00385 // Class bitset.
00386 //   _Nb may be any nonzero number of type size_t.
00387 
00388 template<size_t _Nb>
00389 class bitset : private _Base_bitset<__BITSET_WORDS(_Nb)>
00390 {
00391 private:
00392   typedef _Base_bitset<__BITSET_WORDS(_Nb)> _Base;
00393   typedef unsigned long _WordT;
00394 
00395 private:
00396   void _M_do_sanitize() {
00397     _Sanitize<_Nb%_GLIBCPP_BITSET_BITS_PER_WORD>::_M_do_sanitize(this->_M_hiword());
00398   }
00399 
00400 public:
00401 
00402   // bit reference:
00403   class reference;
00404   friend class reference;
00405 
00406   class reference {
00407     friend class bitset;
00408 
00409     _WordT *_M_wp;
00410     size_t _M_bpos;
00411 
00412     // left undefined
00413     reference();
00414 
00415   public:
00416     reference( bitset& __b, size_t __pos ) {
00417       _M_wp = &__b._M_getword(__pos);
00418       _M_bpos = _Base::_S_whichbit(__pos);
00419     }
00420 
00421     ~reference() {}
00422 
00423     // for b[i] = __x;
00424     reference& operator=(bool __x) {
00425       if ( __x )
00426         *_M_wp |= _Base::_S_maskbit(_M_bpos);
00427       else
00428         *_M_wp &= ~_Base::_S_maskbit(_M_bpos);
00429 
00430       return *this;
00431     }
00432 
00433     // for b[i] = b[__j];
00434     reference& operator=(const reference& __j) {
00435       if ( (*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos)) )
00436         *_M_wp |= _Base::_S_maskbit(_M_bpos);
00437       else
00438         *_M_wp &= ~_Base::_S_maskbit(_M_bpos);
00439 
00440       return *this;
00441     }
00442 
00443     // flips the bit
00444     bool operator~() const
00445       { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; }
00446 
00447     // for __x = b[i];
00448     operator bool() const
00449       { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; }
00450 
00451     // for b[i].flip();
00452     reference& flip() {
00453       *_M_wp ^= _Base::_S_maskbit(_M_bpos);
00454       return *this;
00455     }
00456   };
00457 
00458   // 23.3.5.1 constructors:
00459   bitset() {}
00460   bitset(unsigned long __val) : _Base_bitset<__BITSET_WORDS(_Nb)>(__val) 
00461     { _M_do_sanitize(); }
00462 
00463   template<class _CharT, class _Traits, class _Alloc>
00464   explicit bitset(const basic_string<_CharT, _Traits, _Alloc>& __s,
00465                   size_t __pos = 0)
00466     : _Base() 
00467   {
00468     if (__pos > __s.size()) 
00469       __STL_THROW(out_of_range("bitset"));
00470     _M_copy_from_string(__s, __pos,
00471                         basic_string<_CharT, _Traits, _Alloc>::npos);
00472   }
00473   template<class _CharT, class _Traits, class _Alloc>
00474   bitset(const basic_string<_CharT, _Traits, _Alloc>& __s,
00475          size_t __pos,
00476          size_t __n)
00477     : _Base() 
00478   {
00479     if (__pos > __s.size()) 
00480       __STL_THROW(out_of_range("bitset"));
00481     _M_copy_from_string(__s, __pos, __n);
00482   }
00483 
00484   // 23.3.5.2 bitset operations:
00485   bitset<_Nb>& operator&=(const bitset<_Nb>& __rhs) {
00486     this->_M_do_and(__rhs);
00487     return *this;
00488   }
00489 
00490   bitset<_Nb>& operator|=(const bitset<_Nb>& __rhs) {
00491     this->_M_do_or(__rhs);
00492     return *this;
00493   }
00494 
00495   bitset<_Nb>& operator^=(const bitset<_Nb>& __rhs) {
00496     this->_M_do_xor(__rhs);
00497     return *this;
00498   }
00499 
00500   bitset<_Nb>& operator<<=(size_t __pos) {
00501     this->_M_do_left_shift(__pos);
00502     this->_M_do_sanitize();
00503     return *this;
00504   }
00505 
00506   bitset<_Nb>& operator>>=(size_t __pos) {
00507     this->_M_do_right_shift(__pos);
00508     this->_M_do_sanitize();
00509     return *this;
00510   }
00511 
00512   //
00513   // Extension:
00514   // Versions of single-bit set, reset, flip, test with no range checking.
00515   //
00516 
00517   bitset<_Nb>& _Unchecked_set(size_t __pos) {
00518     this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
00519     return *this;
00520   }
00521 
00522   bitset<_Nb>& _Unchecked_set(size_t __pos, int __val) {
00523     if (__val)
00524       this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
00525     else
00526       this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
00527 
00528     return *this;
00529   }
00530 
00531   bitset<_Nb>& _Unchecked_reset(size_t __pos) {
00532     this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
00533     return *this;
00534   }
00535 
00536   bitset<_Nb>& _Unchecked_flip(size_t __pos) {
00537     this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos);
00538     return *this;
00539   }
00540 
00541   bool _Unchecked_test(size_t __pos) const {
00542     return (this->_M_getword(__pos) & _Base::_S_maskbit(__pos))
00543       != static_cast<_WordT>(0);
00544   }
00545 
00546   // Set, reset, and flip.
00547 
00548   bitset<_Nb>& set() {
00549     this->_M_do_set();
00550     this->_M_do_sanitize();
00551     return *this;
00552   }
00553 
00554   bitset<_Nb>& set(size_t __pos) {
00555     if (__pos >= _Nb)
00556       __STL_THROW(out_of_range("bitset"));
00557 
00558     return _Unchecked_set(__pos);
00559   }
00560 
00561   bitset<_Nb>& set(size_t __pos, int __val) {
00562     if (__pos >= _Nb)
00563       __STL_THROW(out_of_range("bitset"));
00564 
00565     return _Unchecked_set(__pos, __val);
00566   }
00567 
00568   bitset<_Nb>& reset() {
00569     this->_M_do_reset();
00570     return *this;
00571   }
00572 
00573   bitset<_Nb>& reset(size_t __pos) {
00574     if (__pos >= _Nb)
00575       __STL_THROW(out_of_range("bitset"));
00576 
00577     return _Unchecked_reset(__pos);
00578   }
00579 
00580   bitset<_Nb>& flip() {
00581     this->_M_do_flip();
00582     this->_M_do_sanitize();
00583     return *this;
00584   }
00585 
00586   bitset<_Nb>& flip(size_t __pos) {
00587     if (__pos >= _Nb)
00588       __STL_THROW(out_of_range("bitset"));
00589 
00590     return _Unchecked_flip(__pos);
00591   }
00592 
00593   bitset<_Nb> operator~() const { 
00594     return bitset<_Nb>(*this).flip();
00595   }
00596 
00597   // element access:
00598   //for b[i];
00599   reference operator[](size_t __pos) { return reference(*this,__pos); }
00600   bool operator[](size_t __pos) const { return _Unchecked_test(__pos); }
00601 
00602   unsigned long to_ulong() const { return this->_M_do_to_ulong(); }
00603 
00604   template <class _CharT, class _Traits, class _Alloc>
00605   basic_string<_CharT, _Traits, _Alloc> to_string() const {
00606     basic_string<_CharT, _Traits, _Alloc> __result;
00607     _M_copy_to_string(__result);
00608     return __result;
00609   }
00610 
00611   // Helper functions for string operations.
00612   template<class _CharT, class _Traits, class _Alloc>
00613   void _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s,
00614                           size_t,
00615                           size_t);
00616 
00617   template<class _CharT, class _Traits, class _Alloc>
00618   void _M_copy_to_string(basic_string<_CharT,_Traits,_Alloc>&) const;
00619 
00620   size_t count() const { return this->_M_do_count(); }
00621 
00622   size_t size() const { return _Nb; }
00623 
00624   bool operator==(const bitset<_Nb>& __rhs) const {
00625     return this->_M_is_equal(__rhs);
00626   }
00627   bool operator!=(const bitset<_Nb>& __rhs) const {
00628     return !this->_M_is_equal(__rhs);
00629   }
00630 
00631   bool test(size_t __pos) const {
00632     if (__pos > _Nb)
00633       __STL_THROW(out_of_range("bitset"));
00634 
00635     return _Unchecked_test(__pos);
00636   }
00637 
00638   bool any() const { return this->_M_is_any(); }
00639   bool none() const { return !this->_M_is_any(); }
00640 
00641   bitset<_Nb> operator<<(size_t __pos) const
00642     { return bitset<_Nb>(*this) <<= __pos; }
00643   bitset<_Nb> operator>>(size_t __pos) const
00644     { return bitset<_Nb>(*this) >>= __pos; }
00645 
00646   //
00647   // EXTENSIONS: bit-find operations.  These operations are
00648   // experimental, and are subject to change or removal in future
00649   // versions.
00650   // 
00651 
00652   // find the index of the first "on" bit
00653   size_t _Find_first() const 
00654     { return this->_M_do_find_first(_Nb); }
00655 
00656   // find the index of the next "on" bit after prev
00657   size_t _Find_next( size_t __prev ) const 
00658     { return this->_M_do_find_next(__prev, _Nb); }
00659 
00660 };
00661 
00662 //
00663 // Definitions of non-inline member functions.
00664 //
00665 
00666 template <size_t _Nb>
00667 template<class _CharT, class _Traits, class _Alloc>
00668 void bitset<_Nb>
00669   ::_M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s,
00670                         size_t __pos,
00671                         size_t __n)
00672 {
00673   reset();
00674   const size_t __nbits = min(_Nb, min(__n, __s.size() - __pos));
00675   for (size_t __i = 0; __i < __nbits; ++__i) {
00676     switch(__s[__pos + __nbits - __i - 1]) {
00677     case '0':
00678       break;
00679     case '1':
00680       set(__i);
00681       break;
00682     default:
00683       __STL_THROW(invalid_argument("bitset"));
00684     }
00685   }
00686 }
00687 
00688 template <size_t _Nb>
00689 template <class _CharT, class _Traits, class _Alloc>
00690 void bitset<_Nb>
00691   ::_M_copy_to_string(basic_string<_CharT, _Traits, _Alloc>& __s) const
00692 {
00693   __s.assign(_Nb, '0');
00694   
00695   for (size_t __i = 0; __i < _Nb; ++__i) 
00696     if (_Unchecked_test(__i))
00697       __s[_Nb - 1 - __i] = '1';
00698 }
00699 
00700 // ------------------------------------------------------------
00701 
00702 //
00703 // 23.3.5.3 bitset operations:
00704 //
00705 
00706 template <size_t _Nb>
00707 inline bitset<_Nb> operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) {
00708   bitset<_Nb> __result(__x);
00709   __result &= __y;
00710   return __result;
00711 }
00712 
00713 
00714 template <size_t _Nb>
00715 inline bitset<_Nb> operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) {
00716   bitset<_Nb> __result(__x);
00717   __result |= __y;
00718   return __result;
00719 }
00720 
00721 template <size_t _Nb>
00722 inline bitset<_Nb> operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) {
00723   bitset<_Nb> __result(__x);
00724   __result ^= __y;
00725   return __result;
00726 }
00727 
00728 template <class _CharT, class _Traits, size_t _Nb>
00729 basic_istream<_CharT, _Traits>&
00730 operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
00731 {
00732   typedef typename _Traits::char_type char_type;
00733   basic_string<_CharT, _Traits> __tmp;
00734   __tmp.reserve(_Nb);
00735 
00736   // Skip whitespace
00737   typename basic_istream<_CharT, _Traits>::sentry __sentry(__is);
00738   if (__sentry) {
00739     basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
00740     for (size_t __i = 0; __i < _Nb; ++__i) {
00741       static typename _Traits::int_type __eof = _Traits::eof();
00742 
00743       typename _Traits::int_type __c1 = __buf->sbumpc();
00744       if (_Traits::eq_int_type(__c1, __eof)) {
00745         __is.setstate(ios_base::eofbit);
00746         break;
00747       }
00748       else {
00749         char_type __c2 = _Traits::to_char_type(__c1);
00750         char_type __c  = __is.narrow(__c2, '*');
00751 
00752         if (__c == '0' || __c == '1')
00753           __tmp.push_back(__c);
00754         else if (_Traits::eq_int_type(__buf->sputbackc(__c2), __eof)) {
00755           __is.setstate(ios_base::failbit);
00756           break;
00757         }
00758       }
00759     }
00760 
00761     if (__tmp.empty())
00762       __is.setstate(ios_base::failbit);
00763     else
00764       __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb);
00765   }
00766 
00767   return __is;
00768 }
00769 
00770 template <class _CharT, class _Traits, size_t _Nb>
00771 basic_ostream<_CharT, _Traits>&
00772 operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x)
00773 {
00774   basic_string<_CharT, _Traits> __tmp;
00775   __x._M_copy_to_string(__tmp);
00776   return __os << __tmp;
00777 }
00778 
00779 } // namespace std
00780 
00781 #undef __BITSET_WORDS
00782 
00783 #endif /* __SGI_STL_BITSET */
00784 
00785 
00786 // Local Variables:
00787 // mode:C++
00788 // End:
00789 

Generated at Tue May 1 16:28:38 2001 for libstdc++-v3 by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001