Whole document tree
    

Whole document tree

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

Generated on Mon Apr 8 03:11:32 2002 for libstdc++-v3 Source by doxygen1.2.15