bitset

Go to the documentation of this file.
00001 // <bitset> -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /*
00027  * Copyright (c) 1998
00028  * Silicon Graphics Computer Systems, Inc.
00029  *
00030  * Permission to use, copy, modify, distribute and sell this software
00031  * and its documentation for any purpose is hereby granted without fee,
00032  * provided that the above copyright notice appear in all copies and
00033  * that both that copyright notice and this permission notice appear
00034  * in supporting documentation.  Silicon Graphics makes no
00035  * representations about the suitability of this software for any
00036  * purpose.  It is provided "as is" without express or implied warranty.
00037  */
00038 
00039 /** @file include/bitset
00040  *  This is a Standard C++ Library header.
00041  */
00042 
00043 #ifndef _GLIBCXX_BITSET
00044 #define _GLIBCXX_BITSET 1
00045 
00046 #pragma GCC system_header
00047 
00048 #include <cstddef>     // For size_t
00049 #include <string>
00050 #include <bits/functexcept.h>   // For invalid_argument, out_of_range,
00051                                 // overflow_error
00052 #include <iosfwd>
00053 #include <cxxabi-forced.h>
00054 
00055 #define _GLIBCXX_BITSET_BITS_PER_WORD  (__CHAR_BIT__ * sizeof(unsigned long))
00056 #define _GLIBCXX_BITSET_WORDS(__n) \
00057  ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1) \
00058                   / _GLIBCXX_BITSET_BITS_PER_WORD)
00059 
00060 _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
00061 
00062   /**
00063    *  Base class, general case.  It is a class invariant that _Nw will be
00064    *  nonnegative.
00065    *
00066    *  See documentation for bitset.
00067   */
00068   template<size_t _Nw>
00069     struct _Base_bitset
00070     {
00071       typedef unsigned long _WordT;
00072 
00073       /// 0 is the least significant word.
00074       _WordT        _M_w[_Nw];
00075 
00076       _Base_bitset()
00077       { _M_do_reset(); }
00078 
00079 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00080       _Base_bitset(unsigned long long __val)
00081 #else
00082       _Base_bitset(unsigned long __val)
00083 #endif
00084       {
00085     _M_do_reset();
00086     _M_w[0] = __val;
00087 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00088     if (sizeof(unsigned long long) > sizeof(unsigned long))
00089       _M_w[1] = __val >> _GLIBCXX_BITSET_BITS_PER_WORD;
00090 #endif
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       { __builtin_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       if (_M_w[__i] != __x._M_w[__i])
00175         return false;
00176     return true;
00177       }
00178 
00179       size_t
00180       _M_are_all_aux() const
00181       {
00182     for (size_t __i = 0; __i < _Nw - 1; __i++)
00183       if (_M_w[__i] != ~static_cast<_WordT>(0))
00184         return 0;
00185     return ((_Nw - 1) * _GLIBCXX_BITSET_BITS_PER_WORD
00186         + __builtin_popcountl(_M_hiword()));
00187       }
00188 
00189       bool
00190       _M_is_any() const
00191       {
00192     for (size_t __i = 0; __i < _Nw; __i++)
00193       if (_M_w[__i] != static_cast<_WordT>(0))
00194         return true;
00195     return false;
00196       }
00197 
00198       size_t
00199       _M_do_count() const
00200       {
00201     size_t __result = 0;
00202     for (size_t __i = 0; __i < _Nw; __i++)
00203       __result += __builtin_popcountl(_M_w[__i]);
00204     return __result;
00205       }
00206 
00207       unsigned long
00208       _M_do_to_ulong() const;
00209 
00210 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00211       unsigned long long
00212       _M_do_to_ullong() const;
00213 #endif
00214 
00215       // find first "on" bit
00216       size_t
00217       _M_do_find_first(size_t __not_found) const;
00218 
00219       // find the next "on" bit that follows "prev"
00220       size_t
00221       _M_do_find_next(size_t __prev, size_t __not_found) const;
00222     };
00223 
00224   // Definitions of non-inline functions from _Base_bitset.
00225   template<size_t _Nw>
00226     void
00227     _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift)
00228     {
00229       if (__builtin_expect(__shift != 0, 1))
00230     {
00231       const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD;
00232       const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD;
00233 
00234       if (__offset == 0)
00235         for (size_t __n = _Nw - 1; __n >= __wshift; --__n)
00236           _M_w[__n] = _M_w[__n - __wshift];
00237       else
00238         {
00239           const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD 
00240                        - __offset);
00241           for (size_t __n = _Nw - 1; __n > __wshift; --__n)
00242         _M_w[__n] = ((_M_w[__n - __wshift] << __offset)
00243                  | (_M_w[__n - __wshift - 1] >> __sub_offset));
00244           _M_w[__wshift] = _M_w[0] << __offset;
00245         }
00246 
00247       std::fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0));
00248     }
00249     }
00250 
00251   template<size_t _Nw>
00252     void
00253     _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift)
00254     {
00255       if (__builtin_expect(__shift != 0, 1))
00256     {
00257       const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD;
00258       const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD;
00259       const size_t __limit = _Nw - __wshift - 1;
00260 
00261       if (__offset == 0)
00262         for (size_t __n = 0; __n <= __limit; ++__n)
00263           _M_w[__n] = _M_w[__n + __wshift];
00264       else
00265         {
00266           const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD
00267                        - __offset);
00268           for (size_t __n = 0; __n < __limit; ++__n)
00269         _M_w[__n] = ((_M_w[__n + __wshift] >> __offset)
00270                  | (_M_w[__n + __wshift + 1] << __sub_offset));
00271           _M_w[__limit] = _M_w[_Nw-1] >> __offset;
00272         }
00273       
00274       std::fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0));
00275     }
00276     }
00277 
00278   template<size_t _Nw>
00279     unsigned long
00280     _Base_bitset<_Nw>::_M_do_to_ulong() const
00281     {
00282       for (size_t __i = 1; __i < _Nw; ++__i)
00283     if (_M_w[__i])
00284       __throw_overflow_error(__N("_Base_bitset::_M_do_to_ulong"));
00285       return _M_w[0];
00286     }
00287 
00288 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00289   template<size_t _Nw>
00290     unsigned long long
00291     _Base_bitset<_Nw>::_M_do_to_ullong() const
00292     {
00293       const bool __dw = sizeof(unsigned long long) > sizeof(unsigned long);
00294       for (size_t __i = 1 + __dw; __i < _Nw; ++__i)
00295     if (_M_w[__i])
00296       __throw_overflow_error(__N("_Base_bitset::_M_do_to_ullong"));
00297 
00298       if (__dw)
00299     return _M_w[0] + (static_cast<unsigned long long>(_M_w[1])
00300               << _GLIBCXX_BITSET_BITS_PER_WORD);
00301       return _M_w[0];
00302     }
00303 #endif
00304 
00305   template<size_t _Nw>
00306     size_t
00307     _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const
00308     {
00309       for (size_t __i = 0; __i < _Nw; __i++)
00310     {
00311       _WordT __thisword = _M_w[__i];
00312       if (__thisword != static_cast<_WordT>(0))
00313         return (__i * _GLIBCXX_BITSET_BITS_PER_WORD
00314             + __builtin_ctzl(__thisword));
00315     }
00316       // not found, so return an indication of failure.
00317       return __not_found;
00318     }
00319 
00320   template<size_t _Nw>
00321     size_t
00322     _Base_bitset<_Nw>::_M_do_find_next(size_t __prev, size_t __not_found) const
00323     {
00324       // make bound inclusive
00325       ++__prev;
00326 
00327       // check out of bounds
00328       if (__prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD)
00329     return __not_found;
00330 
00331       // search first word
00332       size_t __i = _S_whichword(__prev);
00333       _WordT __thisword = _M_w[__i];
00334 
00335       // mask off bits below bound
00336       __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev);
00337 
00338       if (__thisword != static_cast<_WordT>(0))
00339     return (__i * _GLIBCXX_BITSET_BITS_PER_WORD
00340         + __builtin_ctzl(__thisword));
00341 
00342       // check subsequent words
00343       __i++;
00344       for (; __i < _Nw; __i++)
00345     {
00346       __thisword = _M_w[__i];
00347       if (__thisword != static_cast<_WordT>(0))
00348         return (__i * _GLIBCXX_BITSET_BITS_PER_WORD
00349             + __builtin_ctzl(__thisword));
00350     }
00351       // not found, so return an indication of failure.
00352       return __not_found;
00353     } // end _M_do_find_next
00354 
00355   /**
00356    *  Base class, specialization for a single word.
00357    *
00358    *  See documentation for bitset.
00359   */
00360   template<>
00361     struct _Base_bitset<1>
00362     {
00363       typedef unsigned long _WordT;
00364       _WordT _M_w;
00365 
00366       _Base_bitset(void)
00367       : _M_w(0)
00368       { }
00369 
00370 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00371       _Base_bitset(unsigned long long __val)
00372 #else
00373       _Base_bitset(unsigned long __val)
00374 #endif
00375       : _M_w(__val)
00376       { }
00377 
00378       static size_t
00379       _S_whichword(size_t __pos )
00380       { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; }
00381 
00382       static size_t
00383       _S_whichbyte(size_t __pos )
00384       { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; }
00385 
00386       static size_t
00387       _S_whichbit(size_t __pos )
00388       {  return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; }
00389 
00390       static _WordT
00391       _S_maskbit(size_t __pos )
00392       { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
00393 
00394       _WordT&
00395       _M_getword(size_t)
00396       { return _M_w; }
00397 
00398       _WordT
00399       _M_getword(size_t) const
00400       { return _M_w; }
00401 
00402       _WordT&
00403       _M_hiword()
00404       { return _M_w; }
00405 
00406       _WordT
00407       _M_hiword() const
00408       { return _M_w; }
00409 
00410       void
00411       _M_do_and(const _Base_bitset<1>& __x)
00412       { _M_w &= __x._M_w; }
00413 
00414       void
00415       _M_do_or(const _Base_bitset<1>& __x)
00416       { _M_w |= __x._M_w; }
00417 
00418       void
00419       _M_do_xor(const _Base_bitset<1>& __x)
00420       { _M_w ^= __x._M_w; }
00421 
00422       void
00423       _M_do_left_shift(size_t __shift)
00424       { _M_w <<= __shift; }
00425 
00426       void
00427       _M_do_right_shift(size_t __shift)
00428       { _M_w >>= __shift; }
00429 
00430       void
00431       _M_do_flip()
00432       { _M_w = ~_M_w; }
00433 
00434       void
00435       _M_do_set()
00436       { _M_w = ~static_cast<_WordT>(0); }
00437 
00438       void
00439       _M_do_reset()
00440       { _M_w = 0; }
00441 
00442       bool
00443       _M_is_equal(const _Base_bitset<1>& __x) const
00444       { return _M_w == __x._M_w; }
00445 
00446       size_t
00447       _M_are_all_aux() const
00448       { return __builtin_popcountl(_M_w); }
00449 
00450       bool
00451       _M_is_any() const
00452       { return _M_w != 0; }
00453 
00454       size_t
00455       _M_do_count() const
00456       { return __builtin_popcountl(_M_w); }
00457 
00458       unsigned long
00459       _M_do_to_ulong() const
00460       { return _M_w; }
00461 
00462 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00463       unsigned long long
00464       _M_do_to_ullong() const
00465       { return _M_w; }
00466 #endif
00467 
00468       size_t
00469       _M_do_find_first(size_t __not_found) const
00470       {
00471         if (_M_w != 0)
00472           return __builtin_ctzl(_M_w);
00473         else
00474           return __not_found;
00475       }
00476 
00477       // find the next "on" bit that follows "prev"
00478       size_t
00479       _M_do_find_next(size_t __prev, size_t __not_found) const
00480       {
00481     ++__prev;
00482     if (__prev >= ((size_t) _GLIBCXX_BITSET_BITS_PER_WORD))
00483       return __not_found;
00484 
00485     _WordT __x = _M_w >> __prev;
00486     if (__x != 0)
00487       return __builtin_ctzl(__x) + __prev;
00488     else
00489       return __not_found;
00490       }
00491     };
00492 
00493   /**
00494    *  Base class, specialization for no storage (zero-length %bitset).
00495    *
00496    *  See documentation for bitset.
00497   */
00498   template<>
00499     struct _Base_bitset<0>
00500     {
00501       typedef unsigned long _WordT;
00502 
00503       _Base_bitset()
00504       { }
00505 
00506 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00507       _Base_bitset(unsigned long long)
00508 #else
00509       _Base_bitset(unsigned long)
00510 #endif
00511       { }
00512 
00513       static size_t
00514       _S_whichword(size_t __pos )
00515       { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; }
00516 
00517       static size_t
00518       _S_whichbyte(size_t __pos )
00519       { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; }
00520 
00521       static size_t
00522       _S_whichbit(size_t __pos )
00523       {  return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; }
00524 
00525       static _WordT
00526       _S_maskbit(size_t __pos )
00527       { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
00528 
00529       // This would normally give access to the data.  The bounds-checking
00530       // in the bitset class will prevent the user from getting this far,
00531       // but (1) it must still return an lvalue to compile, and (2) the
00532       // user might call _Unchecked_set directly, in which case this /needs/
00533       // to fail.  Let's not penalize zero-length users unless they actually
00534       // make an unchecked call; all the memory ugliness is therefore
00535       // localized to this single should-never-get-this-far function.
00536       _WordT&
00537       _M_getword(size_t) const
00538       { 
00539     __throw_out_of_range(__N("_Base_bitset::_M_getword")); 
00540     return *new _WordT; 
00541       }
00542 
00543       _WordT
00544       _M_hiword() const
00545       { return 0; }
00546 
00547       void
00548       _M_do_and(const _Base_bitset<0>&)
00549       { }
00550 
00551       void
00552       _M_do_or(const _Base_bitset<0>&)
00553       { }
00554 
00555       void
00556       _M_do_xor(const _Base_bitset<0>&)
00557       { }
00558 
00559       void
00560       _M_do_left_shift(size_t)
00561       { }
00562 
00563       void
00564       _M_do_right_shift(size_t)
00565       { }
00566 
00567       void
00568       _M_do_flip()
00569       { }
00570 
00571       void
00572       _M_do_set()
00573       { }
00574 
00575       void
00576       _M_do_reset()
00577       { }
00578 
00579       // Are all empty bitsets equal to each other?  Are they equal to
00580       // themselves?  How to compare a thing which has no state?  What is
00581       // the sound of one zero-length bitset clapping?
00582       bool
00583       _M_is_equal(const _Base_bitset<0>&) const
00584       { return true; }
00585 
00586       size_t
00587       _M_are_all_aux() const
00588       { return 0; }
00589 
00590       bool
00591       _M_is_any() const
00592       { return false; }
00593 
00594       size_t
00595       _M_do_count() const
00596       { return 0; }
00597 
00598       unsigned long
00599       _M_do_to_ulong() const
00600       { return 0; }
00601 
00602 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00603       unsigned long long
00604       _M_do_to_ullong() const
00605       { return 0; }
00606 #endif
00607 
00608       // Normally "not found" is the size, but that could also be
00609       // misinterpreted as an index in this corner case.  Oh well.
00610       size_t
00611       _M_do_find_first(size_t) const
00612       { return 0; }
00613 
00614       size_t
00615       _M_do_find_next(size_t, size_t) const
00616       { return 0; }
00617     };
00618 
00619 
00620   // Helper class to zero out the unused high-order bits in the highest word.
00621   template<size_t _Extrabits>
00622     struct _Sanitize
00623     {
00624       static void _S_do_sanitize(unsigned long& __val)
00625       { __val &= ~((~static_cast<unsigned long>(0)) << _Extrabits); }
00626     };
00627 
00628   template<>
00629     struct _Sanitize<0>
00630     { static void _S_do_sanitize(unsigned long) {} };
00631 
00632   /**
00633    *  @brief  The %bitset class represents a @e fixed-size sequence of bits.
00634    *
00635    *  @ingroup containers
00636    *
00637    *  (Note that %bitset does @e not meet the formal requirements of a
00638    *  <a href="tables.html#65">container</a>.  Mainly, it lacks iterators.)
00639    *
00640    *  The template argument, @a Nb, may be any non-negative number,
00641    *  specifying the number of bits (e.g., "0", "12", "1024*1024").
00642    *
00643    *  In the general unoptimized case, storage is allocated in word-sized
00644    *  blocks.  Let B be the number of bits in a word, then (Nb+(B-1))/B
00645    *  words will be used for storage.  B - Nb%B bits are unused.  (They are
00646    *  the high-order bits in the highest word.)  It is a class invariant
00647    *  that those unused bits are always zero.
00648    *
00649    *  If you think of %bitset as <em>a simple array of bits</em>, be
00650    *  aware that your mental picture is reversed: a %bitset behaves
00651    *  the same way as bits in integers do, with the bit at index 0 in
00652    *  the <em>least significant / right-hand</em> position, and the bit at
00653    *  index Nb-1 in the <em>most significant / left-hand</em> position.
00654    *  Thus, unlike other containers, a %bitset's index <em>counts from
00655    *  right to left</em>, to put it very loosely.
00656    *
00657    *  This behavior is preserved when translating to and from strings.  For
00658    *  example, the first line of the following program probably prints
00659    *  <em>b(&apos;a&apos;) is 0001100001</em> on a modern ASCII system.
00660    *
00661    *  @code
00662    *     #include <bitset>
00663    *     #include <iostream>
00664    *     #include <sstream>
00665    *
00666    *     using namespace std;
00667    *
00668    *     int main()
00669    *     {
00670    *         long         a = 'a';
00671    *         bitset<10>   b(a);
00672    *
00673    *         cout << "b('a') is " << b << endl;
00674    *
00675    *         ostringstream s;
00676    *         s << b;
00677    *         string  str = s.str();
00678    *         cout << "index 3 in the string is " << str[3] << " but\n"
00679    *              << "index 3 in the bitset is " << b[3] << endl;
00680    *     }
00681    *  @endcode
00682    *
00683    *  Also see:
00684    *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt12ch33s02.html
00685    *  for a description of extensions.
00686    *
00687    *  Most of the actual code isn't contained in %bitset<> itself, but in the
00688    *  base class _Base_bitset.  The base class works with whole words, not with
00689    *  individual bits.  This allows us to specialize _Base_bitset for the
00690    *  important special case where the %bitset is only a single word.
00691    *
00692    *  Extra confusion can result due to the fact that the storage for
00693    *  _Base_bitset @e is a regular array, and is indexed as such.  This is
00694    *  carefully encapsulated.
00695   */
00696   template<size_t _Nb>
00697     class bitset
00698     : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)>
00699     {
00700     private:
00701       typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base;
00702       typedef unsigned long _WordT;
00703 
00704       void
00705     _M_do_sanitize()
00706     {
00707       _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD>::
00708         _S_do_sanitize(this->_M_hiword());
00709     }
00710 
00711     public:
00712       /**
00713        *  This encapsulates the concept of a single bit.  An instance of this
00714        *  class is a proxy for an actual bit; this way the individual bit
00715        *  operations are done as faster word-size bitwise instructions.
00716        *
00717        *  Most users will never need to use this class directly; conversions
00718        *  to and from bool are automatic and should be transparent.  Overloaded
00719        *  operators help to preserve the illusion.
00720        *
00721        *  (On a typical system, this <em>bit %reference</em> is 64
00722        *  times the size of an actual bit.  Ha.)
00723        */
00724       class reference
00725       {
00726     friend class bitset;
00727 
00728     _WordT *_M_wp;
00729     size_t _M_bpos;
00730     
00731     // left undefined
00732     reference();
00733     
00734       public:
00735     reference(bitset& __b, size_t __pos)
00736     {
00737       _M_wp = &__b._M_getword(__pos);
00738       _M_bpos = _Base::_S_whichbit(__pos);
00739     }
00740 
00741     ~reference()
00742     { }
00743 
00744     // For b[i] = __x;
00745     reference&
00746     operator=(bool __x)
00747     {
00748       if (__x)
00749         *_M_wp |= _Base::_S_maskbit(_M_bpos);
00750       else
00751         *_M_wp &= ~_Base::_S_maskbit(_M_bpos);
00752       return *this;
00753     }
00754 
00755     // For b[i] = b[__j];
00756     reference&
00757     operator=(const reference& __j)
00758     {
00759       if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos)))
00760         *_M_wp |= _Base::_S_maskbit(_M_bpos);
00761       else
00762         *_M_wp &= ~_Base::_S_maskbit(_M_bpos);
00763       return *this;
00764     }
00765 
00766     // Flips the bit
00767     bool
00768     operator~() const
00769     { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; }
00770 
00771     // For __x = b[i];
00772     operator bool() const
00773     { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; }
00774 
00775     // For b[i].flip();
00776     reference&
00777     flip()
00778     {
00779       *_M_wp ^= _Base::_S_maskbit(_M_bpos);
00780       return *this;
00781     }
00782       };
00783       friend class reference;
00784 
00785       // 23.3.5.1 constructors:
00786       /// All bits set to zero.
00787       bitset()
00788       { }
00789 
00790       /// Initial bits bitwise-copied from a single word (others set to zero).
00791 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00792       bitset(unsigned long long __val)
00793 #else
00794       bitset(unsigned long __val)
00795 #endif
00796       : _Base(__val)
00797       { _M_do_sanitize(); }
00798 
00799       /**
00800        *  @brief  Use a subset of a string.
00801        *  @param  s  A string of @a 0 and @a 1 characters.
00802        *  @param  position  Index of the first character in @a s to use;
00803        *                    defaults to zero.
00804        *  @throw  std::out_of_range  If @a pos is bigger the size of @a s.
00805        *  @throw  std::invalid_argument  If a character appears in the string
00806        *                                 which is neither @a 0 nor @a 1.
00807        */
00808       template<class _CharT, class _Traits, class _Alloc>
00809     explicit
00810     bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
00811            size_t __position = 0)
00812     : _Base()
00813     {
00814       if (__position > __s.size())
00815         __throw_out_of_range(__N("bitset::bitset initial position "
00816                      "not valid"));
00817       _M_copy_from_string(__s, __position,
00818                   std::basic_string<_CharT, _Traits, _Alloc>::npos,
00819                   _CharT('0'), _CharT('1'));
00820     }
00821 
00822       /**
00823        *  @brief  Use a subset of a string.
00824        *  @param  s  A string of @a 0 and @a 1 characters.
00825        *  @param  position  Index of the first character in @a s to use.
00826        *  @param  n    The number of characters to copy.
00827        *  @throw  std::out_of_range  If @a pos is bigger the size of @a s.
00828        *  @throw  std::invalid_argument  If a character appears in the string
00829        *                                 which is neither @a 0 nor @a 1.
00830        */
00831       template<class _CharT, class _Traits, class _Alloc>
00832     bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
00833            size_t __position, size_t __n)
00834     : _Base()
00835     {
00836       if (__position > __s.size())
00837         __throw_out_of_range(__N("bitset::bitset initial position "
00838                      "not valid"));
00839       _M_copy_from_string(__s, __position, __n, _CharT('0'), _CharT('1'));
00840     }
00841 
00842       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00843       // 396. what are characters zero and one.
00844       template<class _CharT, class _Traits, class _Alloc>
00845     bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
00846            size_t __position, size_t __n,
00847            _CharT __zero, _CharT __one = _CharT('1'))
00848     : _Base()
00849     {
00850       if (__position > __s.size())
00851         __throw_out_of_range(__N("bitset::bitset initial position "
00852                      "not valid"));
00853       _M_copy_from_string(__s, __position, __n, __zero, __one);
00854     }
00855 
00856 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00857       /**
00858        *  @brief  Construct from a string.
00859        *  @param  str  A string of @a 0 and @a 1 characters.
00860        *  @throw  std::invalid_argument  If a character appears in the string
00861        *                                 which is neither @a 0 nor @a 1.
00862        */
00863       explicit
00864       bitset(const char* __str)
00865       : _Base()
00866       {
00867     if (!__str)
00868       __throw_logic_error(__N("bitset::bitset(const char*)"));
00869 
00870     const size_t __len = __builtin_strlen(__str);
00871     _M_copy_from_ptr<char, std::char_traits<char>>(__str, __len, 0,
00872                                __len, '0', '1');
00873       }
00874 #endif
00875 
00876       // 23.3.5.2 bitset operations:
00877       //@{
00878       /**
00879        *  @brief  Operations on bitsets.
00880        *  @param  rhs  A same-sized bitset.
00881        *
00882        *  These should be self-explanatory.
00883        */
00884       bitset<_Nb>&
00885       operator&=(const bitset<_Nb>& __rhs)
00886       {
00887     this->_M_do_and(__rhs);
00888     return *this;
00889       }
00890 
00891       bitset<_Nb>&
00892       operator|=(const bitset<_Nb>& __rhs)
00893       {
00894     this->_M_do_or(__rhs);
00895     return *this;
00896       }
00897 
00898       bitset<_Nb>&
00899       operator^=(const bitset<_Nb>& __rhs)
00900       {
00901     this->_M_do_xor(__rhs);
00902     return *this;
00903       }
00904       //@}
00905       
00906       //@{
00907       /**
00908        *  @brief  Operations on bitsets.
00909        *  @param  position  The number of places to shift.
00910        *
00911        *  These should be self-explanatory.
00912        */
00913       bitset<_Nb>&
00914       operator<<=(size_t __position)
00915       {
00916     if (__builtin_expect(__position < _Nb, 1))
00917       {
00918         this->_M_do_left_shift(__position);
00919         this->_M_do_sanitize();
00920       }
00921     else
00922       this->_M_do_reset();
00923     return *this;
00924       }
00925 
00926       bitset<_Nb>&
00927       operator>>=(size_t __position)
00928       {
00929     if (__builtin_expect(__position < _Nb, 1))
00930       {
00931         this->_M_do_right_shift(__position);
00932         this->_M_do_sanitize();
00933       }
00934     else
00935       this->_M_do_reset();
00936     return *this;
00937       }
00938       //@}
00939       
00940       //@{
00941       /**
00942        *  These versions of single-bit set, reset, flip, and test are
00943        *  extensions from the SGI version.  They do no range checking.
00944        *  @ingroup SGIextensions
00945        */
00946       bitset<_Nb>&
00947       _Unchecked_set(size_t __pos)
00948       {
00949     this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
00950     return *this;
00951       }
00952 
00953       bitset<_Nb>&
00954       _Unchecked_set(size_t __pos, int __val)
00955       {
00956     if (__val)
00957       this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
00958     else
00959       this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
00960     return *this;
00961       }
00962 
00963       bitset<_Nb>&
00964       _Unchecked_reset(size_t __pos)
00965       {
00966     this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
00967     return *this;
00968       }
00969 
00970       bitset<_Nb>&
00971       _Unchecked_flip(size_t __pos)
00972       {
00973     this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos);
00974     return *this;
00975       }
00976 
00977       bool
00978       _Unchecked_test(size_t __pos) const
00979       { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos))
00980         != static_cast<_WordT>(0)); }
00981       //@}
00982       
00983       // Set, reset, and flip.
00984       /**
00985        *  @brief Sets every bit to true.
00986        */
00987       bitset<_Nb>&
00988       set()
00989       {
00990     this->_M_do_set();
00991     this->_M_do_sanitize();
00992     return *this;
00993       }
00994 
00995       /**
00996        *  @brief Sets a given bit to a particular value.
00997        *  @param  position  The index of the bit.
00998        *  @param  val  Either true or false, defaults to true.
00999        *  @throw  std::out_of_range  If @a pos is bigger the size of the %set.
01000        */
01001       bitset<_Nb>&
01002       set(size_t __position, bool __val = true)
01003       {
01004     if (__position >= _Nb)
01005       __throw_out_of_range(__N("bitset::set"));
01006     return _Unchecked_set(__position, __val);
01007       }
01008 
01009       /**
01010        *  @brief Sets every bit to false.
01011        */
01012       bitset<_Nb>&
01013       reset()
01014       {
01015     this->_M_do_reset();
01016     return *this;
01017       }
01018 
01019       /**
01020        *  @brief Sets a given bit to false.
01021        *  @param  position  The index of the bit.
01022        *  @throw  std::out_of_range  If @a pos is bigger the size of the %set.
01023        *
01024        *  Same as writing @c set(pos,false).
01025        */
01026       bitset<_Nb>&
01027       reset(size_t __position)
01028       {
01029     if (__position >= _Nb)
01030       __throw_out_of_range(__N("bitset::reset"));
01031     return _Unchecked_reset(__position);
01032       }
01033       
01034       /**
01035        *  @brief Toggles every bit to its opposite value.
01036        */
01037       bitset<_Nb>&
01038       flip()
01039       {
01040     this->_M_do_flip();
01041     this->_M_do_sanitize();
01042     return *this;
01043       }
01044 
01045       /**
01046        *  @brief Toggles a given bit to its opposite value.
01047        *  @param  position  The index of the bit.
01048        *  @throw  std::out_of_range  If @a pos is bigger the size of the %set.
01049        */
01050       bitset<_Nb>&
01051       flip(size_t __position)
01052       {
01053     if (__position >= _Nb)
01054       __throw_out_of_range(__N("bitset::flip"));
01055     return _Unchecked_flip(__position);
01056       }
01057       
01058       /// See the no-argument flip().
01059       bitset<_Nb>
01060       operator~() const
01061       { return bitset<_Nb>(*this).flip(); }
01062 
01063       //@{
01064       /**
01065        *  @brief  Array-indexing support.
01066        *  @param  position  Index into the %bitset.
01067        *  @return  A bool for a <em>const %bitset</em>.  For non-const bitsets, an
01068        *           instance of the reference proxy class.
01069        *  @note  These operators do no range checking and throw no exceptions,
01070        *         as required by DR 11 to the standard.
01071        *
01072        *  _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already
01073        *  resolves DR 11 (items 1 and 2), but does not do the range-checking
01074        *  required by that DR's resolution.  -pme
01075        *  The DR has since been changed:  range-checking is a precondition
01076        *  (users' responsibility), and these functions must not throw.  -pme
01077        */
01078       reference
01079       operator[](size_t __position)
01080       { return reference(*this,__position); }
01081 
01082       bool
01083       operator[](size_t __position) const
01084       { return _Unchecked_test(__position); }
01085       //@}
01086       
01087       /**
01088        *  @brief Returns a numerical interpretation of the %bitset.
01089        *  @return  The integral equivalent of the bits.
01090        *  @throw  std::overflow_error  If there are too many bits to be
01091        *                               represented in an @c unsigned @c long.
01092        */
01093       unsigned long
01094       to_ulong() const
01095       { return this->_M_do_to_ulong(); }
01096 
01097 #ifdef __GXX_EXPERIMENTAL_CXX0X__
01098       unsigned long long
01099       to_ullong() const
01100       { return this->_M_do_to_ullong(); }
01101 #endif
01102 
01103       /**
01104        *  @brief Returns a character interpretation of the %bitset.
01105        *  @return  The string equivalent of the bits.
01106        *
01107        *  Note the ordering of the bits:  decreasing character positions
01108        *  correspond to increasing bit positions (see the main class notes for
01109        *  an example).
01110        */
01111       template<class _CharT, class _Traits, class _Alloc>
01112     std::basic_string<_CharT, _Traits, _Alloc>
01113     to_string() const
01114     {
01115       std::basic_string<_CharT, _Traits, _Alloc> __result;
01116       _M_copy_to_string(__result, _CharT('0'), _CharT('1'));
01117       return __result;
01118     }
01119 
01120       // _GLIBCXX_RESOLVE_LIB_DEFECTS
01121       // 396. what are characters zero and one.
01122       template<class _CharT, class _Traits, class _Alloc>
01123     std::basic_string<_CharT, _Traits, _Alloc>
01124     to_string(_CharT __zero, _CharT __one = _CharT('1')) const
01125     {
01126       std::basic_string<_CharT, _Traits, _Alloc> __result;
01127       _M_copy_to_string(__result, __zero, __one);
01128       return __result;
01129     }
01130 
01131       // _GLIBCXX_RESOLVE_LIB_DEFECTS
01132       // 434. bitset::to_string() hard to use.
01133       template<class _CharT, class _Traits>
01134     std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
01135     to_string() const
01136     { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
01137 
01138       // _GLIBCXX_RESOLVE_LIB_DEFECTS
01139       // 853. to_string needs updating with zero and one.
01140       template<class _CharT, class _Traits>
01141     std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
01142     to_string(_CharT __zero, _CharT __one = _CharT('1')) const
01143     { return to_string<_CharT, _Traits,
01144                        std::allocator<_CharT> >(__zero, __one); }
01145 
01146       template<class _CharT>
01147     std::basic_string<_CharT, std::char_traits<_CharT>,
01148                       std::allocator<_CharT> >
01149     to_string() const
01150     {
01151       return to_string<_CharT, std::char_traits<_CharT>,
01152                        std::allocator<_CharT> >();
01153     }
01154 
01155       template<class _CharT>
01156     std::basic_string<_CharT, std::char_traits<_CharT>,
01157                       std::allocator<_CharT> >
01158     to_string(_CharT __zero, _CharT __one = _CharT('1')) const
01159     {
01160       return to_string<_CharT, std::char_traits<_CharT>,
01161                        std::allocator<_CharT> >(__zero, __one);
01162     }
01163 
01164       std::basic_string<char, std::char_traits<char>, std::allocator<char> >
01165       to_string() const
01166       {
01167     return to_string<char, std::char_traits<char>,
01168                      std::allocator<char> >();
01169       }
01170 
01171       std::basic_string<char, std::char_traits<char>, std::allocator<char> >
01172       to_string(char __zero, char __one = '1') const
01173       {
01174     return to_string<char, std::char_traits<char>,
01175                      std::allocator<char> >(__zero, __one);
01176       }
01177 
01178       // Helper functions for string operations.
01179       template<class _CharT, class _Traits>
01180         void
01181         _M_copy_from_ptr(const _CharT*, size_t, size_t, size_t,
01182              _CharT, _CharT);
01183 
01184       template<class _CharT, class _Traits, class _Alloc>
01185     void
01186     _M_copy_from_string(const std::basic_string<_CharT,
01187                 _Traits, _Alloc>& __s, size_t __pos, size_t __n,
01188                 _CharT __zero, _CharT __one)
01189     { _M_copy_from_ptr<_CharT, _Traits>(__s.data(), __s.size(), __pos, __n,
01190                         __zero, __one); }
01191 
01192       template<class _CharT, class _Traits, class _Alloc>
01193     void
01194         _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>&,
01195               _CharT, _CharT) const;
01196 
01197       // NB: Backward compat.
01198       template<class _CharT, class _Traits, class _Alloc>
01199     void
01200     _M_copy_from_string(const std::basic_string<_CharT,
01201                 _Traits, _Alloc>& __s, size_t __pos, size_t __n)
01202     { _M_copy_from_string(__s, __pos, __n, _CharT('0'), _CharT('1')); }
01203 
01204       template<class _CharT, class _Traits, class _Alloc>
01205     void
01206         _M_copy_to_string(std::basic_string<_CharT, _Traits,_Alloc>& __s) const
01207     { _M_copy_to_string(__s, _CharT('0'), _CharT('1')); }
01208 
01209       /// Returns the number of bits which are set.
01210       size_t
01211       count() const
01212       { return this->_M_do_count(); }
01213 
01214       /// Returns the total number of bits.
01215       size_t
01216       size() const
01217       { return _Nb; }
01218 
01219       //@{
01220       /// These comparisons for equality/inequality are, well, @e bitwise.
01221       bool
01222       operator==(const bitset<_Nb>& __rhs) const
01223       { return this->_M_is_equal(__rhs); }
01224 
01225       bool
01226       operator!=(const bitset<_Nb>& __rhs) const
01227       { return !this->_M_is_equal(__rhs); }
01228       //@}
01229       
01230       /**
01231        *  @brief Tests the value of a bit.
01232        *  @param  position  The index of a bit.
01233        *  @return  The value at @a pos.
01234        *  @throw  std::out_of_range  If @a pos is bigger the size of the %set.
01235        */
01236       bool
01237       test(size_t __position) const
01238       {
01239     if (__position >= _Nb)
01240       __throw_out_of_range(__N("bitset::test"));
01241     return _Unchecked_test(__position);
01242       }
01243 
01244       // _GLIBCXX_RESOLVE_LIB_DEFECTS
01245       // DR 693. std::bitset::all() missing.
01246       /**
01247        *  @brief Tests whether all the bits are on.
01248        *  @return  True if all the bits are set.
01249        */
01250       bool
01251       all() const
01252       { return this->_M_are_all_aux() == _Nb; }
01253 
01254       /**
01255        *  @brief Tests whether any of the bits are on.
01256        *  @return  True if at least one bit is set.
01257        */
01258       bool
01259       any() const
01260       { return this->_M_is_any(); }
01261 
01262       /**
01263        *  @brief Tests whether any of the bits are on.
01264        *  @return  True if none of the bits are set.
01265        */
01266       bool
01267       none() const
01268       { return !this->_M_is_any(); }
01269 
01270       //@{
01271       /// Self-explanatory.
01272       bitset<_Nb>
01273       operator<<(size_t __position) const
01274       { return bitset<_Nb>(*this) <<= __position; }
01275 
01276       bitset<_Nb>
01277       operator>>(size_t __position) const
01278       { return bitset<_Nb>(*this) >>= __position; }
01279       //@}
01280       
01281       /**
01282        *  @brief  Finds the index of the first "on" bit.
01283        *  @return  The index of the first bit set, or size() if not found.
01284        *  @ingroup SGIextensions
01285        *  @sa  _Find_next
01286        */
01287       size_t
01288       _Find_first() const
01289       { return this->_M_do_find_first(_Nb); }
01290 
01291       /**
01292        *  @brief  Finds the index of the next "on" bit after prev.
01293        *  @return  The index of the next bit set, or size() if not found.
01294        *  @param  prev  Where to start searching.
01295        *  @ingroup SGIextensions
01296        *  @sa  _Find_first
01297        */
01298       size_t
01299       _Find_next(size_t __prev ) const
01300       { return this->_M_do_find_next(__prev, _Nb); }
01301     };
01302 
01303   // Definitions of non-inline member functions.
01304   template<size_t _Nb>
01305     template<class _CharT, class _Traits>
01306       void
01307       bitset<_Nb>::
01308       _M_copy_from_ptr(const _CharT* __s, size_t __len,
01309                size_t __pos, size_t __n, _CharT __zero, _CharT __one)
01310       {
01311     reset();
01312     const size_t __nbits = std::min(_Nb, std::min(__n, __len - __pos));
01313     for (size_t __i = __nbits; __i > 0; --__i)
01314       {
01315         const _CharT __c = __s[__pos + __nbits - __i];
01316         if (_Traits::eq(__c, __zero))
01317           ;
01318         else if (_Traits::eq(__c, __one))
01319           _Unchecked_set(__i - 1);
01320         else
01321           __throw_invalid_argument(__N("bitset::_M_copy_from_ptr"));
01322       }
01323       }
01324 
01325   template<size_t _Nb>
01326     template<class _CharT, class _Traits, class _Alloc>
01327       void
01328       bitset<_Nb>::
01329       _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>& __s,
01330             _CharT __zero, _CharT __one) const
01331       {
01332     __s.assign(_Nb, __zero);
01333     for (size_t __i = _Nb; __i > 0; --__i)
01334       if (_Unchecked_test(__i - 1))
01335         _Traits::assign(__s[_Nb - __i], __one);
01336       }
01337 
01338   // 23.3.5.3 bitset operations:
01339   //@{
01340   /**
01341    *  @brief  Global bitwise operations on bitsets.
01342    *  @param  x  A bitset.
01343    *  @param  y  A bitset of the same size as @a x.
01344    *  @return  A new bitset.
01345    *
01346    *  These should be self-explanatory.
01347   */
01348   template<size_t _Nb>
01349     inline bitset<_Nb>
01350     operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01351     {
01352       bitset<_Nb> __result(__x);
01353       __result &= __y;
01354       return __result;
01355     }
01356 
01357   template<size_t _Nb>
01358     inline bitset<_Nb>
01359     operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01360     {
01361       bitset<_Nb> __result(__x);
01362       __result |= __y;
01363       return __result;
01364     }
01365 
01366   template <size_t _Nb>
01367     inline bitset<_Nb>
01368     operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01369     {
01370       bitset<_Nb> __result(__x);
01371       __result ^= __y;
01372       return __result;
01373     }
01374   //@}
01375 
01376   //@{
01377   /**
01378    *  @brief Global I/O operators for bitsets.
01379    *
01380    *  Direct I/O between streams and bitsets is supported.  Output is
01381    *  straightforward.  Input will skip whitespace, only accept @a 0 and @a 1
01382    *  characters, and will only extract as many digits as the %bitset will
01383    *  hold.
01384   */
01385   template<class _CharT, class _Traits, size_t _Nb>
01386     std::basic_istream<_CharT, _Traits>&
01387     operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
01388     {
01389       typedef typename _Traits::char_type          char_type;
01390       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01391       typedef typename __istream_type::ios_base    __ios_base;
01392 
01393       std::basic_string<_CharT, _Traits> __tmp;
01394       __tmp.reserve(_Nb);
01395 
01396       // _GLIBCXX_RESOLVE_LIB_DEFECTS
01397       // 303. Bitset input operator underspecified
01398       const char_type __zero = __is.widen('0');
01399       const char_type __one = __is.widen('1');
01400 
01401       typename __ios_base::iostate __state = __ios_base::goodbit;
01402       typename __istream_type::sentry __sentry(__is);
01403       if (__sentry)
01404     {
01405       __try
01406         {
01407           for (size_t __i = _Nb; __i > 0; --__i)
01408         {
01409           static typename _Traits::int_type __eof = _Traits::eof();
01410           
01411           typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc();
01412           if (_Traits::eq_int_type(__c1, __eof))
01413             {
01414               __state |= __ios_base::eofbit;
01415               break;
01416             }
01417           else
01418             {
01419               const char_type __c2 = _Traits::to_char_type(__c1);
01420               if (_Traits::eq(__c2, __zero))
01421             __tmp.push_back(__zero);
01422               else if (_Traits::eq(__c2, __one))
01423             __tmp.push_back(__one);
01424               else if (_Traits::
01425                    eq_int_type(__is.rdbuf()->sputbackc(__c2),
01426                        __eof))
01427             {
01428               __state |= __ios_base::failbit;
01429               break;
01430             }
01431             }
01432         }
01433         }
01434       __catch(__cxxabiv1::__forced_unwind&)
01435         {
01436           __is._M_setstate(__ios_base::badbit);     
01437           __throw_exception_again;
01438         }
01439       __catch(...)
01440         { __is._M_setstate(__ios_base::badbit); }
01441     }
01442 
01443       if (__tmp.empty() && _Nb)
01444     __state |= __ios_base::failbit;
01445       else
01446     __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb,
01447                 __zero, __one);
01448       if (__state)
01449     __is.setstate(__state);
01450       return __is;
01451     }
01452 
01453   template <class _CharT, class _Traits, size_t _Nb>
01454     std::basic_ostream<_CharT, _Traits>&
01455     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01456            const bitset<_Nb>& __x)
01457     {
01458       std::basic_string<_CharT, _Traits> __tmp;
01459 
01460       // _GLIBCXX_RESOLVE_LIB_DEFECTS
01461       // 396. what are characters zero and one.
01462       const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__os.getloc());
01463       __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1'));
01464       return __os << __tmp;
01465     }
01466   //@}
01467 
01468 _GLIBCXX_END_NESTED_NAMESPACE
01469 
01470 #undef _GLIBCXX_BITSET_WORDS
01471 #undef _GLIBCXX_BITSET_BITS_PER_WORD
01472 
01473 #ifdef _GLIBCXX_DEBUG
01474 # include <debug/bitset>
01475 #endif
01476 
01477 #ifdef _GLIBCXX_PROFILE
01478 # include <profile/bitset>
01479 #endif
01480 
01481 #endif /* _GLIBCXX_BITSET */

Generated on 9 Feb 2010 for libstdc++ by  doxygen 1.6.1