bitset

Go to the documentation of this file.
00001 // <bitset> -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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 
00047 #ifndef _GLIBCXX_BITSET
00048 #define _GLIBCXX_BITSET 1
00049 
00050 #pragma GCC system_header
00051 
00052 #include <cstddef>     // For size_t
00053 #include <cstring>     // For memset
00054 #include <limits>      // For numeric_limits
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 #define _GLIBCXX_BITSET_BITS_PER_WORD  numeric_limits<unsigned long>::digits
00062 #define _GLIBCXX_BITSET_WORDS(__n) \
00063  ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1) \
00064                   / _GLIBCXX_BITSET_BITS_PER_WORD)
00065 
00066 namespace _GLIBCXX_STD
00067 {
00076   template<size_t _Nw>
00077     struct _Base_bitset
00078     {
00079       typedef unsigned long _WordT;
00080 
00082       _WordT        _M_w[_Nw];
00083 
00084       _Base_bitset()
00085       { _M_do_reset(); }
00086 
00087       _Base_bitset(unsigned long __val)
00088       {
00089     _M_do_reset();
00090     _M_w[0] = __val;
00091       }
00092 
00093       static size_t
00094       _S_whichword(size_t __pos )
00095       { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; }
00096 
00097       static size_t
00098       _S_whichbyte(size_t __pos )
00099       { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; }
00100 
00101       static size_t
00102       _S_whichbit(size_t __pos )
00103       { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; }
00104 
00105       static _WordT
00106       _S_maskbit(size_t __pos )
00107       { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
00108 
00109       _WordT&
00110       _M_getword(size_t __pos)
00111       { return _M_w[_S_whichword(__pos)]; }
00112 
00113       _WordT
00114       _M_getword(size_t __pos) const
00115       { return _M_w[_S_whichword(__pos)]; }
00116 
00117       _WordT&
00118       _M_hiword()
00119       { return _M_w[_Nw - 1]; }
00120 
00121       _WordT
00122       _M_hiword() const
00123       { return _M_w[_Nw - 1]; }
00124 
00125       void
00126       _M_do_and(const _Base_bitset<_Nw>& __x)
00127       {
00128     for (size_t __i = 0; __i < _Nw; __i++)
00129       _M_w[__i] &= __x._M_w[__i];
00130       }
00131 
00132       void
00133       _M_do_or(const _Base_bitset<_Nw>& __x)
00134       {
00135     for (size_t __i = 0; __i < _Nw; __i++)
00136       _M_w[__i] |= __x._M_w[__i];
00137       }
00138 
00139       void
00140       _M_do_xor(const _Base_bitset<_Nw>& __x)
00141       {
00142     for (size_t __i = 0; __i < _Nw; __i++)
00143       _M_w[__i] ^= __x._M_w[__i];
00144       }
00145 
00146       void
00147       _M_do_left_shift(size_t __shift);
00148 
00149       void
00150       _M_do_right_shift(size_t __shift);
00151 
00152       void
00153       _M_do_flip()
00154       {
00155     for (size_t __i = 0; __i < _Nw; __i++)
00156       _M_w[__i] = ~_M_w[__i];
00157       }
00158 
00159       void
00160       _M_do_set()
00161       {
00162     for (size_t __i = 0; __i < _Nw; __i++)
00163       _M_w[__i] = ~static_cast<_WordT>(0);
00164       }
00165 
00166       void
00167       _M_do_reset()
00168       { std::memset(_M_w, 0, _Nw * sizeof(_WordT)); }
00169 
00170       bool
00171       _M_is_equal(const _Base_bitset<_Nw>& __x) const
00172       {
00173     for (size_t __i = 0; __i < _Nw; ++__i)
00174       {
00175         if (_M_w[__i] != __x._M_w[__i])
00176           return false;
00177       }
00178     return true;
00179       }
00180 
00181       bool
00182       _M_is_any() const
00183       {
00184     for (size_t __i = 0; __i < _Nw; __i++)
00185       {
00186         if (_M_w[__i] != static_cast<_WordT>(0))
00187           return true;
00188       }
00189     return false;
00190       }
00191 
00192       size_t
00193       _M_do_count() const
00194       {
00195     size_t __result = 0;
00196     for (size_t __i = 0; __i < _Nw; __i++)
00197       __result += __builtin_popcountl(_M_w[__i]);
00198     return __result;
00199       }
00200 
00201       unsigned long
00202       _M_do_to_ulong() const;
00203 
00204       // find first "on" bit
00205       size_t
00206       _M_do_find_first(size_t __not_found) const;
00207 
00208       // find the next "on" bit that follows "prev"
00209       size_t
00210       _M_do_find_next(size_t __prev, size_t __not_found) const;
00211     };
00212 
00213   // Definitions of non-inline functions from _Base_bitset.
00214   template<size_t _Nw>
00215     void
00216     _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift)
00217     {
00218       if (__builtin_expect(__shift != 0, 1))
00219     {
00220       const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD;
00221       const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD;
00222 
00223       if (__offset == 0)
00224         for (size_t __n = _Nw - 1; __n >= __wshift; --__n)
00225           _M_w[__n] = _M_w[__n - __wshift];
00226       else
00227         {
00228           const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD 
00229                        - __offset);
00230           for (size_t __n = _Nw - 1; __n > __wshift; --__n)
00231         _M_w[__n] = ((_M_w[__n - __wshift] << __offset)
00232                  | (_M_w[__n - __wshift - 1] >> __sub_offset));
00233           _M_w[__wshift] = _M_w[0] << __offset;
00234         }
00235 
00236       std::fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0));
00237     }
00238     }
00239 
00240   template<size_t _Nw>
00241     void
00242     _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift)
00243     {
00244       if (__builtin_expect(__shift != 0, 1))
00245     {
00246       const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD;
00247       const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD;
00248       const size_t __limit = _Nw - __wshift - 1;
00249 
00250       if (__offset == 0)
00251         for (size_t __n = 0; __n <= __limit; ++__n)
00252           _M_w[__n] = _M_w[__n + __wshift];
00253       else
00254         {
00255           const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD
00256                        - __offset);
00257           for (size_t __n = 0; __n < __limit; ++__n)
00258         _M_w[__n] = ((_M_w[__n + __wshift] >> __offset)
00259                  | (_M_w[__n + __wshift + 1] << __sub_offset));
00260           _M_w[__limit] = _M_w[_Nw-1] >> __offset;
00261         }
00262       
00263       std::fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0));
00264     }
00265     }
00266 
00267   template<size_t _Nw>
00268     unsigned long
00269     _Base_bitset<_Nw>::_M_do_to_ulong() const
00270     {
00271       for (size_t __i = 1; __i < _Nw; ++__i)
00272     if (_M_w[__i])
00273       __throw_overflow_error(__N("_Base_bitset::_M_do_to_ulong"));
00274       return _M_w[0];
00275     }
00276 
00277   template<size_t _Nw>
00278     size_t
00279     _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const
00280     {
00281       for (size_t __i = 0; __i < _Nw; __i++)
00282     {
00283       _WordT __thisword = _M_w[__i];
00284       if (__thisword != static_cast<_WordT>(0))
00285         return (__i * _GLIBCXX_BITSET_BITS_PER_WORD
00286             + __builtin_ctzl(__thisword));
00287     }
00288       // not found, so return an indication of failure.
00289       return __not_found;
00290     }
00291 
00292   template<size_t _Nw>
00293     size_t
00294     _Base_bitset<_Nw>::_M_do_find_next(size_t __prev, size_t __not_found) const
00295     {
00296       // make bound inclusive
00297       ++__prev;
00298 
00299       // check out of bounds
00300       if (__prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD)
00301     return __not_found;
00302 
00303       // search first word
00304       size_t __i = _S_whichword(__prev);
00305       _WordT __thisword = _M_w[__i];
00306 
00307       // mask off bits below bound
00308       __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev);
00309 
00310       if (__thisword != static_cast<_WordT>(0))
00311     return (__i * _GLIBCXX_BITSET_BITS_PER_WORD
00312         + __builtin_ctzl(__thisword));
00313 
00314       // check subsequent words
00315       __i++;
00316       for (; __i < _Nw; __i++)
00317     {
00318       __thisword = _M_w[__i];
00319       if (__thisword != static_cast<_WordT>(0))
00320         return (__i * _GLIBCXX_BITSET_BITS_PER_WORD
00321             + __builtin_ctzl(__thisword));
00322     }
00323       // not found, so return an indication of failure.
00324       return __not_found;
00325     } // end _M_do_find_next
00326 
00334   template<>
00335     struct _Base_bitset<1>
00336     {
00337       typedef unsigned long _WordT;
00338       _WordT _M_w;
00339 
00340       _Base_bitset(void)
00341       : _M_w(0)
00342       { }
00343 
00344       _Base_bitset(unsigned long __val)
00345       : _M_w(__val)
00346       { }
00347 
00348       static size_t
00349       _S_whichword(size_t __pos )
00350       { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; }
00351 
00352       static size_t
00353       _S_whichbyte(size_t __pos )
00354       { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; }
00355 
00356       static size_t
00357       _S_whichbit(size_t __pos )
00358       {  return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; }
00359 
00360       static _WordT
00361       _S_maskbit(size_t __pos )
00362       { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
00363 
00364       _WordT&
00365       _M_getword(size_t)
00366       { return _M_w; }
00367 
00368       _WordT
00369       _M_getword(size_t) const
00370       { return _M_w; }
00371 
00372       _WordT&
00373       _M_hiword()
00374       { return _M_w; }
00375 
00376       _WordT
00377       _M_hiword() const
00378       { return _M_w; }
00379 
00380       void
00381       _M_do_and(const _Base_bitset<1>& __x)
00382       { _M_w &= __x._M_w; }
00383 
00384       void
00385       _M_do_or(const _Base_bitset<1>& __x)
00386       { _M_w |= __x._M_w; }
00387 
00388       void
00389       _M_do_xor(const _Base_bitset<1>& __x)
00390       { _M_w ^= __x._M_w; }
00391 
00392       void
00393       _M_do_left_shift(size_t __shift)
00394       { _M_w <<= __shift; }
00395 
00396       void
00397       _M_do_right_shift(size_t __shift)
00398       { _M_w >>= __shift; }
00399 
00400       void
00401       _M_do_flip()
00402       { _M_w = ~_M_w; }
00403 
00404       void
00405       _M_do_set()
00406       { _M_w = ~static_cast<_WordT>(0); }
00407 
00408       void
00409       _M_do_reset()
00410       { _M_w = 0; }
00411 
00412       bool
00413       _M_is_equal(const _Base_bitset<1>& __x) const
00414       { return _M_w == __x._M_w; }
00415 
00416       bool
00417       _M_is_any() const
00418       { return _M_w != 0; }
00419 
00420       size_t
00421       _M_do_count() const
00422       { return __builtin_popcountl(_M_w); }
00423 
00424       unsigned long
00425       _M_do_to_ulong() const
00426       { return _M_w; }
00427 
00428       size_t
00429       _M_do_find_first(size_t __not_found) const
00430       {
00431         if (_M_w != 0)
00432           return __builtin_ctzl(_M_w);
00433         else
00434           return __not_found;
00435       }
00436 
00437       // find the next "on" bit that follows "prev"
00438       size_t
00439       _M_do_find_next(size_t __prev, size_t __not_found) const
00440       {
00441     ++__prev;
00442     if (__prev >= ((size_t) _GLIBCXX_BITSET_BITS_PER_WORD))
00443       return __not_found;
00444 
00445     _WordT __x = _M_w >> __prev;
00446     if (__x != 0)
00447       return __builtin_ctzl(__x) + __prev;
00448     else
00449       return __not_found;
00450       }
00451     };
00452 
00460   template<>
00461     struct _Base_bitset<0>
00462     {
00463       typedef unsigned long _WordT;
00464 
00465       _Base_bitset()
00466       { }
00467 
00468       _Base_bitset(unsigned long)
00469       { }
00470 
00471       static size_t
00472       _S_whichword(size_t __pos )
00473       { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; }
00474 
00475       static size_t
00476       _S_whichbyte(size_t __pos )
00477       { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; }
00478 
00479       static size_t
00480       _S_whichbit(size_t __pos )
00481       {  return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; }
00482 
00483       static _WordT
00484       _S_maskbit(size_t __pos )
00485       { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
00486 
00487       // This would normally give access to the data.  The bounds-checking
00488       // in the bitset class will prevent the user from getting this far,
00489       // but (1) it must still return an lvalue to compile, and (2) the
00490       // user might call _Unchecked_set directly, in which case this /needs/
00491       // to fail.  Let's not penalize zero-length users unless they actually
00492       // make an unchecked call; all the memory ugliness is therefore
00493       // localized to this single should-never-get-this-far function.
00494       _WordT&
00495       _M_getword(size_t) const
00496       { 
00497     __throw_out_of_range(__N("_Base_bitset::_M_getword")); 
00498     return *new _WordT; 
00499       }
00500 
00501       _WordT
00502       _M_hiword() const
00503       { return 0; }
00504 
00505       void
00506       _M_do_and(const _Base_bitset<0>&)
00507       { }
00508 
00509       void
00510       _M_do_or(const _Base_bitset<0>&)
00511       { }
00512 
00513       void
00514       _M_do_xor(const _Base_bitset<0>&)
00515       { }
00516 
00517       void
00518       _M_do_left_shift(size_t)
00519       { }
00520 
00521       void
00522       _M_do_right_shift(size_t)
00523       { }
00524 
00525       void
00526       _M_do_flip()
00527       { }
00528 
00529       void
00530       _M_do_set()
00531       { }
00532 
00533       void
00534       _M_do_reset()
00535       { }
00536 
00537       // Are all empty bitsets equal to each other?  Are they equal to
00538       // themselves?  How to compare a thing which has no state?  What is
00539       // the sound of one zero-length bitset clapping?
00540       bool
00541       _M_is_equal(const _Base_bitset<0>&) const
00542       { return true; }
00543 
00544       bool
00545       _M_is_any() const
00546       { return false; }
00547 
00548       size_t
00549       _M_do_count() const
00550       { return 0; }
00551 
00552       unsigned long
00553       _M_do_to_ulong() const
00554       { return 0; }
00555 
00556       // Normally "not found" is the size, but that could also be
00557       // misinterpreted as an index in this corner case.  Oh well.
00558       size_t
00559       _M_do_find_first(size_t) const
00560       { return 0; }
00561 
00562       size_t
00563       _M_do_find_next(size_t, size_t) const
00564       { return 0; }
00565     };
00566 
00567 
00568   // Helper class to zero out the unused high-order bits in the highest word.
00569   template<size_t _Extrabits>
00570     struct _Sanitize
00571     {
00572       static void _S_do_sanitize(unsigned long& __val)
00573       { __val &= ~((~static_cast<unsigned long>(0)) << _Extrabits); }
00574     };
00575 
00576   template<>
00577     struct _Sanitize<0>
00578     { static void _S_do_sanitize(unsigned long) {} };
00579 
00644   template<size_t _Nb>
00645     class bitset
00646     : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)>
00647     {
00648     private:
00649       typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base;
00650       typedef unsigned long _WordT;
00651 
00652       void
00653     _M_do_sanitize()
00654     {
00655       _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD>::
00656 	    _S_do_sanitize(this->_M_hiword());
00657     }
00658 
00659     public:
00672       class reference
00673       {
00674     friend class bitset;
00675 
00676     _WordT *_M_wp;
00677     size_t _M_bpos;
00678     
00679     // left undefined
00680     reference();
00681     
00682       public:
00683     reference(bitset& __b, size_t __pos)
00684     {
00685       _M_wp = &__b._M_getword(__pos);
00686       _M_bpos = _Base::_S_whichbit(__pos);
00687     }
00688 
00689     ~reference()
00690     { }
00691 
00692     // For b[i] = __x;
00693     reference&
00694     operator=(bool __x)
00695     {
00696       if (__x)
00697         *_M_wp |= _Base::_S_maskbit(_M_bpos);
00698       else
00699         *_M_wp &= ~_Base::_S_maskbit(_M_bpos);
00700       return *this;
00701     }
00702 
00703     // For b[i] = b[__j];
00704     reference&
00705     operator=(const reference& __j)
00706     {
00707       if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos)))
00708         *_M_wp |= _Base::_S_maskbit(_M_bpos);
00709       else
00710         *_M_wp &= ~_Base::_S_maskbit(_M_bpos);
00711       return *this;
00712     }
00713 
00714     // Flips the bit
00715     bool
00716     operator~() const
00717     { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; }
00718 
00719     // For __x = b[i];
00720     operator bool() const
00721     { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; }
00722 
00723     // For b[i].flip();
00724     reference&
00725     flip()
00726     {
00727       *_M_wp ^= _Base::_S_maskbit(_M_bpos);
00728       return *this;
00729     }
00730       };
00731       friend class reference;
00732 
00733       // 23.3.5.1 constructors:
00735       bitset()
00736       { }
00737 
00739       bitset(unsigned long __val)
00740       : _Base(__val)
00741       { _M_do_sanitize(); }
00742 
00752       template<class _CharT, class _Traits, class _Alloc>
00753     explicit
00754     bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
00755            size_t __position = 0)
00756     : _Base()
00757     {
00758       if (__position > __s.size())
00759         __throw_out_of_range(__N("bitset::bitset initial position "
00760                      "not valid"));
00761       _M_copy_from_string(__s, __position,
00762                   std::basic_string<_CharT, _Traits, _Alloc>::npos);
00763     }
00764 
00774       template<class _CharT, class _Traits, class _Alloc>
00775     bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
00776            size_t __position, size_t __n)
00777     : _Base()
00778     {
00779       if (__position > __s.size())
00780         __throw_out_of_range(__N("bitset::bitset initial position "
00781                      "not valid"));
00782       _M_copy_from_string(__s, __position, __n);
00783     }
00784       
00785       // 23.3.5.2 bitset operations:
00787 
00793       bitset<_Nb>&
00794       operator&=(const bitset<_Nb>& __rhs)
00795       {
00796     this->_M_do_and(__rhs);
00797     return *this;
00798       }
00799 
00800       bitset<_Nb>&
00801       operator|=(const bitset<_Nb>& __rhs)
00802       {
00803     this->_M_do_or(__rhs);
00804     return *this;
00805       }
00806 
00807       bitset<_Nb>&
00808       operator^=(const bitset<_Nb>& __rhs)
00809       {
00810     this->_M_do_xor(__rhs);
00811     return *this;
00812       }
00814       
00816 
00822       bitset<_Nb>&
00823       operator<<=(size_t __position)
00824       {
00825     if (__builtin_expect(__position < _Nb, 1))
00826       {
00827         this->_M_do_left_shift(__position);
00828         this->_M_do_sanitize();
00829       }
00830     else
00831       this->_M_do_reset();
00832     return *this;
00833       }
00834 
00835       bitset<_Nb>&
00836       operator>>=(size_t __position)
00837       {
00838     if (__builtin_expect(__position < _Nb, 1))
00839       {
00840         this->_M_do_right_shift(__position);
00841         this->_M_do_sanitize();
00842       }
00843     else
00844       this->_M_do_reset();
00845     return *this;
00846       }
00848       
00850 
00855       bitset<_Nb>&
00856       _Unchecked_set(size_t __pos)
00857       {
00858     this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
00859     return *this;
00860       }
00861 
00862       bitset<_Nb>&
00863       _Unchecked_set(size_t __pos, int __val)
00864       {
00865     if (__val)
00866       this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
00867     else
00868       this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
00869     return *this;
00870       }
00871 
00872       bitset<_Nb>&
00873       _Unchecked_reset(size_t __pos)
00874       {
00875     this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
00876     return *this;
00877       }
00878 
00879       bitset<_Nb>&
00880       _Unchecked_flip(size_t __pos)
00881       {
00882     this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos);
00883     return *this;
00884       }
00885 
00886       bool
00887       _Unchecked_test(size_t __pos) const
00888       { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos))
00889         != static_cast<_WordT>(0)); }
00891       
00892       // Set, reset, and flip.
00896       bitset<_Nb>&
00897       set()
00898       {
00899     this->_M_do_set();
00900     this->_M_do_sanitize();
00901     return *this;
00902       }
00903 
00910       bitset<_Nb>&
00911       set(size_t __position, bool __val = true)
00912       {
00913     if (__position >= _Nb)
00914       __throw_out_of_range(__N("bitset::set"));
00915     return _Unchecked_set(__position, __val);
00916       }
00917 
00921       bitset<_Nb>&
00922       reset()
00923       {
00924     this->_M_do_reset();
00925     return *this;
00926       }
00927 
00935       bitset<_Nb>&
00936       reset(size_t __position)
00937       {
00938     if (__position >= _Nb)
00939       __throw_out_of_range(__N("bitset::reset"));
00940     return _Unchecked_reset(__position);
00941       }
00942       
00946       bitset<_Nb>&
00947       flip()
00948       {
00949     this->_M_do_flip();
00950     this->_M_do_sanitize();
00951     return *this;
00952       }
00953 
00959       bitset<_Nb>&
00960       flip(size_t __position)
00961       {
00962     if (__position >= _Nb)
00963       __throw_out_of_range(__N("bitset::flip"));
00964     return _Unchecked_flip(__position);
00965       }
00966       
00968       bitset<_Nb>
00969       operator~() const
00970       { return bitset<_Nb>(*this).flip(); }
00971 
00973 
00989       reference
00990       operator[](size_t __position)
00991       { return reference(*this,__position); }
00992 
00993       bool
00994       operator[](size_t __position) const
00995       { return _Unchecked_test(__position); }
00997       
01004       unsigned long
01005       to_ulong() const
01006       { return this->_M_do_to_ulong(); }
01007 
01016       template<class _CharT, class _Traits, class _Alloc>
01017     std::basic_string<_CharT, _Traits, _Alloc>
01018     to_string() const
01019     {
01020       std::basic_string<_CharT, _Traits, _Alloc> __result;
01021       _M_copy_to_string(__result);
01022       return __result;
01023     }
01024 
01025       // _GLIBCXX_RESOLVE_LIB_DEFECTS
01026       // 434. bitset::to_string() hard to use.
01027       template<class _CharT, class _Traits>
01028     std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
01029     to_string() const
01030     { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
01031 
01032       template<class _CharT>
01033     std::basic_string<_CharT, std::char_traits<_CharT>,
01034                       std::allocator<_CharT> >
01035     to_string() const
01036     {
01037       return to_string<_CharT, std::char_traits<_CharT>,
01038                        std::allocator<_CharT> >();
01039     }
01040 
01041       std::basic_string<char, std::char_traits<char>, std::allocator<char> >
01042       to_string() const
01043       {
01044     return to_string<char, std::char_traits<char>,
01045                      std::allocator<char> >();
01046       }
01047 
01048       // Helper functions for string operations.
01049       template<class _CharT, class _Traits, class _Alloc>
01050     void
01051     _M_copy_from_string(const std::basic_string<_CharT,
01052                 _Traits, _Alloc>& __s,
01053                 size_t, size_t);
01054 
01055       template<class _CharT, class _Traits, class _Alloc>
01056     void
01057     _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>&) const;
01058 
01060       size_t
01061       count() const
01062       { return this->_M_do_count(); }
01063 
01065       size_t
01066       size() const
01067       { return _Nb; }
01068 
01070 
01071       bool
01072       operator==(const bitset<_Nb>& __rhs) const
01073       { return this->_M_is_equal(__rhs); }
01074 
01075       bool
01076       operator!=(const bitset<_Nb>& __rhs) const
01077       { return !this->_M_is_equal(__rhs); }
01079       
01086       bool
01087       test(size_t __position) const
01088       {
01089     if (__position >= _Nb)
01090       __throw_out_of_range(__N("bitset::test"));
01091     return _Unchecked_test(__position);
01092       }
01093       
01098       bool
01099       any() const
01100       { return this->_M_is_any(); }
01101 
01106       bool
01107       none() const
01108       { return !this->_M_is_any(); }
01109 
01111 
01112       bitset<_Nb>
01113       operator<<(size_t __position) const
01114       { return bitset<_Nb>(*this) <<= __position; }
01115 
01116       bitset<_Nb>
01117       operator>>(size_t __position) const
01118       { return bitset<_Nb>(*this) >>= __position; }
01120       
01127       size_t
01128       _Find_first() const
01129       { return this->_M_do_find_first(_Nb); }
01130 
01138       size_t
01139       _Find_next(size_t __prev ) const
01140       { return this->_M_do_find_next(__prev, _Nb); }
01141     };
01142 
01143   // Definitions of non-inline member functions.
01144   template<size_t _Nb>
01145     template<class _CharT, class _Traits, class _Alloc>
01146       void
01147       bitset<_Nb>::_M_copy_from_string(const std::basic_string<_CharT, _Traits,
01148                        _Alloc>& __s, size_t __pos, size_t __n)
01149       {
01150     reset();
01151     const size_t __nbits = std::min(_Nb, std::min(__n, __s.size() - __pos));
01152     for (size_t __i = 0; __i < __nbits; ++__i)
01153       {
01154         switch(__s[__pos + __nbits - __i - 1])
01155           {
01156           case '0':
01157         break;
01158           case '1':
01159         _Unchecked_set(__i);
01160         break;
01161           default:
01162         __throw_invalid_argument(__N("bitset::_M_copy_from_string"));
01163           }
01164       }
01165       }
01166 
01167   template<size_t _Nb>
01168     template<class _CharT, class _Traits, class _Alloc>
01169       void
01170       bitset<_Nb>::_M_copy_to_string(std::basic_string<_CharT, _Traits,
01171                      _Alloc>& __s) const
01172       {
01173     __s.assign(_Nb, '0');
01174     for (size_t __i = 0; __i < _Nb; ++__i)
01175       if (_Unchecked_test(__i))
01176         __s[_Nb - 1 - __i] = '1';
01177       }
01178 
01179   // 23.3.5.3 bitset operations:
01181 
01189   template<size_t _Nb>
01190     inline bitset<_Nb>
01191     operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01192     {
01193       bitset<_Nb> __result(__x);
01194       __result &= __y;
01195       return __result;
01196     }
01197 
01198   template<size_t _Nb>
01199     inline bitset<_Nb>
01200     operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01201     {
01202       bitset<_Nb> __result(__x);
01203       __result |= __y;
01204       return __result;
01205     }
01206 
01207   template <size_t _Nb>
01208     inline bitset<_Nb>
01209     operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01210     {
01211       bitset<_Nb> __result(__x);
01212       __result ^= __y;
01213       return __result;
01214     }
01216 
01218 
01226   template<class _CharT, class _Traits, size_t _Nb>
01227     std::basic_istream<_CharT, _Traits>&
01228     operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
01229     {
01230       typedef typename _Traits::char_type char_type;
01231       std::basic_string<_CharT, _Traits> __tmp;
01232       __tmp.reserve(_Nb);
01233 
01234       std::ios_base::iostate __state = std::ios_base::goodbit;
01235       typename std::basic_istream<_CharT, _Traits>::sentry __sentry(__is);
01236       if (__sentry)
01237     {
01238       try
01239         {
01240           basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
01241           // _GLIBCXX_RESOLVE_LIB_DEFECTS
01242           // 303. Bitset input operator underspecified
01243           const char_type __zero = __is.widen('0');
01244           const char_type __one = __is.widen('1');
01245           for (size_t __i = 0; __i < _Nb; ++__i)
01246         {
01247           static typename _Traits::int_type __eof = _Traits::eof();
01248           
01249           typename _Traits::int_type __c1 = __buf->sbumpc();
01250           if (_Traits::eq_int_type(__c1, __eof))
01251             {
01252               __state |= std::ios_base::eofbit;
01253               break;
01254             }
01255           else
01256             {
01257               const char_type __c2 = _Traits::to_char_type(__c1);
01258               if (__c2 == __zero)
01259             __tmp.push_back('0');
01260               else if (__c2 == __one)
01261             __tmp.push_back('1');
01262               else if (_Traits::eq_int_type(__buf->sputbackc(__c2),
01263                             __eof))
01264             {
01265               __state |= std::ios_base::failbit;
01266               break;
01267             }
01268             }
01269         }
01270         }
01271       catch(...)
01272         { __is._M_setstate(std::ios_base::badbit); }
01273     }
01274 
01275       if (__tmp.empty() && _Nb)
01276     __state |= std::ios_base::failbit;
01277       else
01278     __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb);
01279       if (__state)
01280     __is.setstate(__state);
01281       return __is;
01282     }
01283 
01284   template <class _CharT, class _Traits, size_t _Nb>
01285     std::basic_ostream<_CharT, _Traits>&
01286     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01287            const bitset<_Nb>& __x)
01288     {
01289       std::basic_string<_CharT, _Traits> __tmp;
01290       __x._M_copy_to_string(__tmp);
01291       return __os << __tmp;
01292     }
01294 } // namespace std
01295 
01296 #undef _GLIBCXX_BITSET_WORDS
01297 #undef _GLIBCXX_BITSET_BITS_PER_WORD
01298 
01299 #ifdef _GLIBCXX_DEBUG
01300 # include <debug/bitset>
01301 #endif
01302 
01303 #endif /* _GLIBCXX_BITSET */

Generated on Tue Feb 2 16:55:47 2010 for GNU C++ STL by  doxygen 1.4.7