bitset

Go to the documentation of this file.
00001 // <bitset> -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002 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 
00048 #ifndef _GLIBCPP_BITSET_H
00049 #define _GLIBCPP_BITSET_H
00050 
00051 #pragma GCC system_header
00052 
00053 #include <cstddef>     // for size_t
00054 #include <cstring>     // for memset
00055 #include <string>
00056 #include <bits/functexcept.h>   // for invalid_argument, out_of_range,
00057                                 // overflow_error
00058 #include <ostream>     // for ostream (operator<<)
00059 #include <istream>     // for istream (operator>>)
00060 
00061 
00062 #define _GLIBCPP_BITSET_BITS_PER_WORD (CHAR_BIT*sizeof(unsigned long))
00063 #define _GLIBCPP_BITSET_WORDS(__n) \
00064  ((__n) < 1 ? 1 : ((__n) + _GLIBCPP_BITSET_BITS_PER_WORD - 1)/_GLIBCPP_BITSET_BITS_PER_WORD)
00065 
00066 namespace std
00067 {
00068   extern unsigned char  _S_bit_count[256];
00069   extern unsigned char  _S_first_one[256];
00070 
00079   template<size_t _Nw>
00080     struct _Base_bitset
00081     {
00082       typedef unsigned long _WordT;
00083 
00085       _WordT        _M_w[_Nw];
00086 
00087       _Base_bitset() { _M_do_reset(); }
00088       _Base_bitset(unsigned long __val)
00089       {
00090     _M_do_reset();
00091     _M_w[0] = __val;
00092       }
00093 
00094       static size_t
00095       _S_whichword(size_t __pos )
00096       { return __pos / _GLIBCPP_BITSET_BITS_PER_WORD; }
00097 
00098       static size_t
00099       _S_whichbyte(size_t __pos )
00100       { return (__pos % _GLIBCPP_BITSET_BITS_PER_WORD) / CHAR_BIT; }
00101 
00102       static size_t
00103       _S_whichbit(size_t __pos )
00104       { return __pos % _GLIBCPP_BITSET_BITS_PER_WORD; }
00105 
00106       static _WordT
00107       _S_maskbit(size_t __pos )
00108       { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
00109 
00110       _WordT&
00111       _M_getword(size_t __pos)
00112       { return _M_w[_S_whichword(__pos)]; }
00113 
00114       _WordT
00115       _M_getword(size_t __pos) const
00116       { return _M_w[_S_whichword(__pos)]; }
00117 
00118       _WordT&
00119       _M_hiword() { return _M_w[_Nw - 1]; }
00120 
00121       _WordT
00122       _M_hiword() const { return _M_w[_Nw - 1]; }
00123 
00124       void
00125       _M_do_and(const _Base_bitset<_Nw>& __x)
00126       {
00127     for (size_t __i = 0; __i < _Nw; __i++)
00128       _M_w[__i] &= __x._M_w[__i];
00129       }
00130 
00131       void
00132       _M_do_or(const _Base_bitset<_Nw>& __x)
00133       {
00134     for (size_t __i = 0; __i < _Nw; __i++)
00135       _M_w[__i] |= __x._M_w[__i];
00136       }
00137 
00138       void
00139       _M_do_xor(const _Base_bitset<_Nw>& __x)
00140       {
00141     for (size_t __i = 0; __i < _Nw; __i++)
00142       _M_w[__i] ^= __x._M_w[__i];
00143       }
00144 
00145       void
00146       _M_do_left_shift(size_t __shift);
00147 
00148       void
00149       _M_do_right_shift(size_t __shift);
00150 
00151       void
00152       _M_do_flip()
00153       {
00154     for (size_t __i = 0; __i < _Nw; __i++)
00155       _M_w[__i] = ~_M_w[__i];
00156       }
00157 
00158       void
00159       _M_do_set()
00160       {
00161     for (size_t __i = 0; __i < _Nw; __i++)
00162       _M_w[__i] = ~static_cast<_WordT>(0);
00163       }
00164 
00165       void
00166       _M_do_reset() { memset(_M_w, 0, _Nw * sizeof(_WordT)); }
00167 
00168       bool
00169       _M_is_equal(const _Base_bitset<_Nw>& __x) const
00170       {
00171     for (size_t __i = 0; __i < _Nw; ++__i)
00172       {
00173         if (_M_w[__i] != __x._M_w[__i])
00174           return false;
00175       }
00176     return true;
00177       }
00178 
00179       bool
00180       _M_is_any() const
00181       {
00182     for (size_t __i = 0; __i < _Nw; __i++)
00183       {
00184         if (_M_w[__i] != static_cast<_WordT>(0))
00185           return true;
00186       }
00187     return false;
00188       }
00189 
00190       size_t
00191       _M_do_count() const
00192       {
00193     size_t __result = 0;
00194     const unsigned char* __byte_ptr = (const unsigned char*)_M_w;
00195     const unsigned char* __end_ptr = (const unsigned char*)(_M_w + _Nw);
00196 
00197     while ( __byte_ptr < __end_ptr )
00198       {
00199         __result += _S_bit_count[*__byte_ptr];
00200         __byte_ptr++;
00201       }
00202     return __result;
00203       }
00204 
00205       unsigned long
00206       _M_do_to_ulong() const;
00207 
00208       // find first "on" bit
00209       size_t
00210       _M_do_find_first(size_t __not_found) const;
00211 
00212       // find the next "on" bit that follows "prev"
00213       size_t
00214       _M_do_find_next(size_t __prev, size_t __not_found) const;
00215     };
00216 
00217   // Definitions of non-inline functions from _Base_bitset.
00218   template<size_t _Nw>
00219     void
00220     _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift)
00221     {
00222       if (__shift != 0)
00223     {
00224       const size_t __wshift = __shift / _GLIBCPP_BITSET_BITS_PER_WORD;
00225       const size_t __offset = __shift % _GLIBCPP_BITSET_BITS_PER_WORD;
00226 
00227       if (__offset == 0)
00228         for (size_t __n = _Nw - 1; __n >= __wshift; --__n)
00229           _M_w[__n] = _M_w[__n - __wshift];
00230       else
00231         {
00232           const size_t __sub_offset = _GLIBCPP_BITSET_BITS_PER_WORD - __offset;
00233           for (size_t __n = _Nw - 1; __n > __wshift; --__n)
00234         _M_w[__n] = (_M_w[__n - __wshift] << __offset) |
00235           (_M_w[__n - __wshift - 1] >> __sub_offset);
00236           _M_w[__wshift] = _M_w[0] << __offset;
00237         }
00238 
00239       fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0));
00240     }
00241     }
00242 
00243   template<size_t _Nw>
00244     void
00245     _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift)
00246     {
00247       if (__shift != 0)
00248     {
00249       const size_t __wshift = __shift / _GLIBCPP_BITSET_BITS_PER_WORD;
00250       const size_t __offset = __shift % _GLIBCPP_BITSET_BITS_PER_WORD;
00251       const size_t __limit = _Nw - __wshift - 1;
00252 
00253       if (__offset == 0)
00254         for (size_t __n = 0; __n <= __limit; ++__n)
00255           _M_w[__n] = _M_w[__n + __wshift];
00256       else
00257         {
00258           const size_t __sub_offset = _GLIBCPP_BITSET_BITS_PER_WORD - __offset;
00259           for (size_t __n = 0; __n < __limit; ++__n)
00260         _M_w[__n] = (_M_w[__n + __wshift] >> __offset) |
00261           (_M_w[__n + __wshift + 1] << __sub_offset);
00262           _M_w[__limit] = _M_w[_Nw-1] >> __offset;
00263         }
00264 
00265       fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0));
00266     }
00267     }
00268 
00269   template<size_t _Nw>
00270     unsigned long
00271     _Base_bitset<_Nw>::_M_do_to_ulong() const
00272     {
00273       for (size_t __i = 1; __i < _Nw; ++__i)
00274     if (_M_w[__i])
00275       __throw_overflow_error("bitset -- too large to fit in unsigned long");
00276       return _M_w[0];
00277     }
00278 
00279   template<size_t _Nw>
00280     size_t
00281     _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const
00282     {
00283       for (size_t __i = 0; __i < _Nw; __i++ )
00284     {
00285       _WordT __thisword = _M_w[__i];
00286       if ( __thisword != static_cast<_WordT>(0) )
00287         {
00288           // find byte within word
00289           for (size_t __j = 0; __j < sizeof(_WordT); __j++ )
00290         {
00291           unsigned char __this_byte
00292             = static_cast<unsigned char>(__thisword & (~(unsigned char)0));
00293           if (__this_byte)
00294             return __i*_GLIBCPP_BITSET_BITS_PER_WORD + __j*CHAR_BIT +
00295               _S_first_one[__this_byte];
00296 
00297           __thisword >>= CHAR_BIT;
00298         }
00299         }
00300     }
00301       // not found, so return an indication of failure.
00302       return __not_found;
00303     }
00304 
00305   template<size_t _Nw>
00306     size_t
00307     _Base_bitset<_Nw>::_M_do_find_next(size_t __prev, size_t __not_found) const
00308     {
00309       // make bound inclusive
00310       ++__prev;
00311 
00312       // check out of bounds
00313       if ( __prev >= _Nw * _GLIBCPP_BITSET_BITS_PER_WORD )
00314     return __not_found;
00315 
00316       // search first word
00317       size_t __i = _S_whichword(__prev);
00318       _WordT __thisword = _M_w[__i];
00319 
00320       // mask off bits below bound
00321       __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev);
00322 
00323       if ( __thisword != static_cast<_WordT>(0) )
00324     {
00325       // find byte within word
00326       // get first byte into place
00327       __thisword >>= _S_whichbyte(__prev) * CHAR_BIT;
00328       for (size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++)
00329         {
00330           unsigned char __this_byte
00331         = static_cast<unsigned char>(__thisword & (~(unsigned char)0));
00332           if ( __this_byte )
00333         return __i*_GLIBCPP_BITSET_BITS_PER_WORD + __j*CHAR_BIT +
00334           _S_first_one[__this_byte];
00335 
00336           __thisword >>= CHAR_BIT;
00337         }
00338     }
00339 
00340       // check subsequent words
00341       __i++;
00342       for ( ; __i < _Nw; __i++ )
00343     {
00344       __thisword = _M_w[__i];
00345       if ( __thisword != static_cast<_WordT>(0) )
00346         {
00347           // find byte within word
00348           for (size_t __j = 0; __j < sizeof(_WordT); __j++ )
00349         {
00350           unsigned char __this_byte
00351             = static_cast<unsigned char>(__thisword & (~(unsigned char)0));
00352           if ( __this_byte )
00353             return __i*_GLIBCPP_BITSET_BITS_PER_WORD + __j*CHAR_BIT +
00354               _S_first_one[__this_byte];
00355 
00356           __thisword >>= CHAR_BIT;
00357         }
00358         }
00359     }
00360       // not found, so return an indication of failure.
00361       return __not_found;
00362     } // end _M_do_find_next
00363 
00364 
00372   template<>
00373     struct _Base_bitset<1>
00374     {
00375       typedef unsigned long _WordT;
00376       _WordT _M_w;
00377 
00378       _Base_bitset( void ) : _M_w(0) {}
00379       _Base_bitset(unsigned long __val) : _M_w(__val) {}
00380 
00381       static size_t
00382       _S_whichword(size_t __pos )
00383       { return __pos / _GLIBCPP_BITSET_BITS_PER_WORD; }
00384 
00385       static size_t
00386       _S_whichbyte(size_t __pos )
00387       { return (__pos % _GLIBCPP_BITSET_BITS_PER_WORD) / CHAR_BIT; }
00388 
00389       static size_t
00390       _S_whichbit(size_t __pos )
00391       {  return __pos % _GLIBCPP_BITSET_BITS_PER_WORD; }
00392 
00393       static _WordT
00394       _S_maskbit(size_t __pos )
00395       { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
00396 
00397       _WordT&
00398       _M_getword(size_t) { return _M_w; }
00399 
00400       _WordT
00401       _M_getword(size_t) const { return _M_w; }
00402 
00403       _WordT&
00404       _M_hiword() { return _M_w; }
00405 
00406       _WordT
00407       _M_hiword() const { return _M_w; }
00408 
00409       void
00410       _M_do_and(const _Base_bitset<1>& __x) { _M_w &= __x._M_w; }
00411 
00412       void
00413       _M_do_or(const _Base_bitset<1>& __x)  { _M_w |= __x._M_w; }
00414 
00415       void
00416       _M_do_xor(const _Base_bitset<1>& __x) { _M_w ^= __x._M_w; }
00417 
00418       void
00419       _M_do_left_shift(size_t __shift) { _M_w <<= __shift; }
00420 
00421       void
00422       _M_do_right_shift(size_t __shift) { _M_w >>= __shift; }
00423 
00424       void
00425       _M_do_flip() { _M_w = ~_M_w; }
00426 
00427       void
00428       _M_do_set() { _M_w = ~static_cast<_WordT>(0); }
00429 
00430       void
00431       _M_do_reset() { _M_w = 0; }
00432 
00433       bool
00434       _M_is_equal(const _Base_bitset<1>& __x) const
00435       { return _M_w == __x._M_w; }
00436 
00437       bool
00438       _M_is_any() const { return _M_w != 0; }
00439 
00440       size_t
00441       _M_do_count() const
00442       {
00443     size_t __result = 0;
00444     const unsigned char* __byte_ptr = (const unsigned char*)&_M_w;
00445     const unsigned char* __end_ptr
00446       = ((const unsigned char*)&_M_w)+sizeof(_M_w);
00447     while ( __byte_ptr < __end_ptr )
00448       {
00449         __result += _S_bit_count[*__byte_ptr];
00450         __byte_ptr++;
00451       }
00452     return __result;
00453       }
00454 
00455       unsigned long
00456       _M_do_to_ulong() const { return _M_w; }
00457 
00458       size_t
00459       _M_do_find_first(size_t __not_found) const;
00460 
00461       // find the next "on" bit that follows "prev"
00462       size_t
00463       _M_do_find_next(size_t __prev, size_t __not_found) const;
00464     };
00465 
00466   // Helper class to zero out the unused high-order bits in the highest word.
00467   template<size_t _Extrabits>
00468     struct _Sanitize
00469     {
00470       static void _S_do_sanitize(unsigned long& __val)
00471       { __val &= ~((~static_cast<unsigned long>(0)) << _Extrabits); }
00472     };
00473 
00474   template<>
00475     struct _Sanitize<0>
00476     { static void _S_do_sanitize(unsigned long) { } };
00477 
00539   template<size_t _Nb>
00540     class bitset : private _Base_bitset<_GLIBCPP_BITSET_WORDS(_Nb)>
00541   {
00542   private:
00543     typedef _Base_bitset<_GLIBCPP_BITSET_WORDS(_Nb)> _Base;
00544     typedef unsigned long _WordT;
00545 
00546     void
00547     _M_do_sanitize()
00548     {
00549       _Sanitize<_Nb%_GLIBCPP_BITSET_BITS_PER_WORD>::
00550           _S_do_sanitize(this->_M_hiword());
00551     }
00552 
00553   public:
00566     class reference
00567     {
00568       friend class bitset;
00569 
00570       _WordT *_M_wp;
00571       size_t _M_bpos;
00572 
00573       // left undefined
00574       reference();
00575 
00576     public:
00577       reference(bitset& __b, size_t __pos)
00578       {
00579     _M_wp = &__b._M_getword(__pos);
00580     _M_bpos = _Base::_S_whichbit(__pos);
00581       }
00582 
00583       ~reference() { }
00584 
00585       // for b[i] = __x;
00586       reference&
00587       operator=(bool __x)
00588       {
00589     if ( __x )
00590       *_M_wp |= _Base::_S_maskbit(_M_bpos);
00591     else
00592       *_M_wp &= ~_Base::_S_maskbit(_M_bpos);
00593     return *this;
00594       }
00595 
00596       // for b[i] = b[__j];
00597       reference&
00598       operator=(const reference& __j)
00599       {
00600     if ( (*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos)) )
00601       *_M_wp |= _Base::_S_maskbit(_M_bpos);
00602     else
00603       *_M_wp &= ~_Base::_S_maskbit(_M_bpos);
00604     return *this;
00605       }
00606 
00607       // flips the bit
00608       bool
00609       operator~() const
00610       { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; }
00611 
00612       // for __x = b[i];
00613       operator bool() const
00614       { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; }
00615 
00616       // for b[i].flip();
00617       reference&
00618       flip()
00619       {
00620     *_M_wp ^= _Base::_S_maskbit(_M_bpos);
00621     return *this;
00622       }
00623     };
00624     friend class reference;
00625 
00626     // 23.3.5.1 constructors:
00628     bitset() { }
00629 
00631     bitset(unsigned long __val) : _Base(__val)
00632     { _M_do_sanitize(); }
00633 
00643     template<class _CharT, class _Traits, class _Alloc>
00644       explicit bitset(const basic_string<_CharT, _Traits, _Alloc>& __s,
00645               size_t __pos = 0) : _Base()
00646       {
00647     if (__pos > __s.size())
00648       __throw_out_of_range("bitset -- initial position is larger than "
00649                            "the string itself");
00650     _M_copy_from_string(__s, __pos,
00651                 basic_string<_CharT, _Traits, _Alloc>::npos);
00652       }
00653 
00663     template<class _CharT, class _Traits, class _Alloc>
00664       bitset(const basic_string<_CharT, _Traits, _Alloc>& __s,
00665          size_t __pos, size_t __n) : _Base()
00666       {
00667     if (__pos > __s.size())
00668       __throw_out_of_range("bitset -- initial position is larger than "
00669                            "the string itself");
00670     _M_copy_from_string(__s, __pos, __n);
00671       }
00672 
00673     // 23.3.5.2 bitset operations:
00675 
00681     bitset<_Nb>&
00682     operator&=(const bitset<_Nb>& __rhs)
00683     {
00684       this->_M_do_and(__rhs);
00685       return *this;
00686     }
00687 
00688     bitset<_Nb>&
00689     operator|=(const bitset<_Nb>& __rhs)
00690     {
00691       this->_M_do_or(__rhs);
00692       return *this;
00693     }
00694 
00695     bitset<_Nb>&
00696     operator^=(const bitset<_Nb>& __rhs)
00697     {
00698       this->_M_do_xor(__rhs);
00699       return *this;
00700     }
00702 
00704 
00710     bitset<_Nb>&
00711     operator<<=(size_t __pos)
00712     {
00713       this->_M_do_left_shift(__pos);
00714       this->_M_do_sanitize();
00715       return *this;
00716     }
00717 
00718     bitset<_Nb>&
00719     operator>>=(size_t __pos)
00720     {
00721       this->_M_do_right_shift(__pos);
00722       this->_M_do_sanitize();
00723       return *this;
00724     }
00726 
00728 
00733     bitset<_Nb>&
00734     _Unchecked_set(size_t __pos)
00735     {
00736       this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
00737       return *this;
00738     }
00739 
00740     bitset<_Nb>&
00741     _Unchecked_set(size_t __pos, int __val)
00742     {
00743       if (__val)
00744     this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
00745       else
00746     this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
00747       return *this;
00748     }
00749 
00750     bitset<_Nb>&
00751     _Unchecked_reset(size_t __pos)
00752     {
00753       this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
00754       return *this;
00755     }
00756 
00757     bitset<_Nb>&
00758     _Unchecked_flip(size_t __pos)
00759     {
00760       this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos);
00761       return *this;
00762     }
00763 
00764     bool
00765     _Unchecked_test(size_t __pos) const
00766     {
00767       return (this->_M_getword(__pos) & _Base::_S_maskbit(__pos))
00768     != static_cast<_WordT>(0);
00769     }
00771 
00772     // Set, reset, and flip.
00776     bitset<_Nb>&
00777     set()
00778     {
00779       this->_M_do_set();
00780       this->_M_do_sanitize();
00781       return *this;
00782     }
00783 
00790     bitset<_Nb>&
00791     set(size_t __pos, bool __val = true)
00792     {
00793       if (__pos >= _Nb)
00794     __throw_out_of_range("bitset -- set() argument too large");
00795       return _Unchecked_set(__pos, __val);
00796     }
00797 
00801     bitset<_Nb>&
00802     reset()
00803     {
00804       this->_M_do_reset();
00805       return *this;
00806     }
00807 
00815     bitset<_Nb>&
00816     reset(size_t __pos)
00817     {
00818       if (__pos >= _Nb)
00819     __throw_out_of_range("bitset -- reset() argument too large");
00820       return _Unchecked_reset(__pos);
00821     }
00822 
00826     bitset<_Nb>&
00827     flip()
00828     {
00829       this->_M_do_flip();
00830       this->_M_do_sanitize();
00831       return *this;
00832     }
00833 
00839     bitset<_Nb>&
00840     flip(size_t __pos)
00841     {
00842       if (__pos >= _Nb)
00843     __throw_out_of_range("bitset -- flip() argument too large");
00844       return _Unchecked_flip(__pos);
00845     }
00846 
00848     bitset<_Nb>
00849     operator~() const { return bitset<_Nb>(*this).flip(); }
00850 
00852 
00868     reference
00869     operator[](size_t __pos) { return reference(*this,__pos); }
00870 
00871     bool
00872     operator[](size_t __pos) const { return _Unchecked_test(__pos); }
00874 
00881     unsigned long
00882     to_ulong() const { return this->_M_do_to_ulong(); }
00883 
00898     template<class _CharT, class _Traits, class _Alloc>
00899       basic_string<_CharT, _Traits, _Alloc>
00900       to_string() const
00901       {
00902     basic_string<_CharT, _Traits, _Alloc> __result;
00903     _M_copy_to_string(__result);
00904     return __result;
00905       }
00906 
00907     // Helper functions for string operations.
00908     template<class _CharT, class _Traits, class _Alloc>
00909       void
00910       _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s,
00911                           size_t, size_t);
00912 
00913     template<class _CharT, class _Traits, class _Alloc>
00914       void
00915       _M_copy_to_string(basic_string<_CharT,_Traits,_Alloc>&) const;
00916 
00918     size_t
00919     count() const { return this->_M_do_count(); }
00920 
00922     size_t
00923     size() const { return _Nb; }
00924 
00926 
00927     bool
00928     operator==(const bitset<_Nb>& __rhs) const
00929     { return this->_M_is_equal(__rhs); }
00930 
00931     bool
00932     operator!=(const bitset<_Nb>& __rhs) const
00933     { return !this->_M_is_equal(__rhs); }
00935 
00942     bool
00943     test(size_t __pos) const
00944     {
00945       if (__pos >= _Nb)
00946     __throw_out_of_range("bitset -- test() argument too large");
00947       return _Unchecked_test(__pos);
00948     }
00949 
00954     bool
00955     any() const { return this->_M_is_any(); }
00956 
00961     bool
00962     none() const { return !this->_M_is_any(); }
00963 
00965 
00966     bitset<_Nb>
00967     operator<<(size_t __pos) const
00968     { return bitset<_Nb>(*this) <<= __pos; }
00969 
00970     bitset<_Nb>
00971     operator>>(size_t __pos) const
00972     { return bitset<_Nb>(*this) >>= __pos; }
00974 
00981     size_t
00982     _Find_first() const
00983     { return this->_M_do_find_first(_Nb); }
00984 
00992     size_t
00993     _Find_next(size_t __prev ) const
00994     { return this->_M_do_find_next(__prev, _Nb); }
00995   };
00996 
00997   // Definitions of non-inline member functions.
00998   template<size_t _Nb>
00999     template<class _CharT, class _Traits, class _Alloc>
01000     void
01001     bitset<_Nb>::_M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, size_t __pos, size_t __n)
01002     {
01003       reset();
01004       const size_t __nbits = min(_Nb, min(__n, __s.size() - __pos));
01005       for (size_t __i = 0; __i < __nbits; ++__i)
01006     {
01007       switch(__s[__pos + __nbits - __i - 1])
01008         {
01009         case '0':
01010           break;
01011         case '1':
01012           set(__i);
01013           break;
01014         default:
01015           __throw_invalid_argument("bitset -- string contains characters "
01016                                    "which are neither 0 nor 1");
01017         }
01018     }
01019     }
01020 
01021   template<size_t _Nb>
01022     template<class _CharT, class _Traits, class _Alloc>
01023     void
01024     bitset<_Nb>::_M_copy_to_string(basic_string<_CharT, _Traits, _Alloc>& __s) const
01025     {
01026       __s.assign(_Nb, '0');
01027       for (size_t __i = 0; __i < _Nb; ++__i)
01028     if (_Unchecked_test(__i))
01029       __s[_Nb - 1 - __i] = '1';
01030     }
01031 
01032   // 23.3.5.3 bitset operations:
01034 
01042   template<size_t _Nb>
01043     inline bitset<_Nb>
01044     operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01045     {
01046       bitset<_Nb> __result(__x);
01047       __result &= __y;
01048       return __result;
01049     }
01050 
01051   template<size_t _Nb>
01052     inline bitset<_Nb>
01053     operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01054     {
01055       bitset<_Nb> __result(__x);
01056       __result |= __y;
01057       return __result;
01058     }
01059 
01060   template <size_t _Nb>
01061     inline bitset<_Nb>
01062     operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01063     {
01064       bitset<_Nb> __result(__x);
01065       __result ^= __y;
01066       return __result;
01067     }
01069 
01071 
01079   template<class _CharT, class _Traits, size_t _Nb>
01080     basic_istream<_CharT, _Traits>&
01081     operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
01082     {
01083       typedef typename _Traits::char_type char_type;
01084       basic_string<_CharT, _Traits> __tmp;
01085       __tmp.reserve(_Nb);
01086 
01087       // Skip whitespace
01088       typename basic_istream<_CharT, _Traits>::sentry __sentry(__is);
01089       if (__sentry)
01090     {
01091       basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
01092       for (size_t __i = 0; __i < _Nb; ++__i)
01093         {
01094           static typename _Traits::int_type __eof = _Traits::eof();
01095 
01096           typename _Traits::int_type __c1 = __buf->sbumpc();
01097           if (_Traits::eq_int_type(__c1, __eof))
01098         {
01099           __is.setstate(ios_base::eofbit);
01100           break;
01101         }
01102           else
01103         {
01104           char_type __c2 = _Traits::to_char_type(__c1);
01105           char_type __c  = __is.narrow(__c2, '*');
01106 
01107           if (__c == '0' || __c == '1')
01108             __tmp.push_back(__c);
01109           else if (_Traits::eq_int_type(__buf->sputbackc(__c2),
01110                         __eof))
01111             {
01112               __is.setstate(ios_base::failbit);
01113               break;
01114             }
01115         }
01116         }
01117 
01118       if (__tmp.empty())
01119         __is.setstate(ios_base::failbit);
01120       else
01121         __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb);
01122     }
01123 
01124       return __is;
01125     }
01126 
01127   template <class _CharT, class _Traits, size_t _Nb>
01128     basic_ostream<_CharT, _Traits>&
01129     operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x)
01130     {
01131       basic_string<_CharT, _Traits> __tmp;
01132       __x._M_copy_to_string(__tmp);
01133       return __os << __tmp;
01134     }
01136 } // namespace std
01137 
01138 #undef _GLIBCPP_BITSET_WORDS
01139 
01140 #endif /* _GLIBCPP_BITSET_H */

Generated on Wed May 1 19:19:30 2002 for libstdc++-v3 Source by doxygen1.2.15