bitset

Go to the documentation of this file.
00001 // <bitset> -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 /*
00031  * Copyright (c) 1998
00032  * Silicon Graphics Computer Systems, Inc.
00033  *
00034  * Permission to use, copy, modify, distribute and sell this software
00035  * and its documentation for any purpose is hereby granted without fee,
00036  * provided that the above copyright notice appear in all copies and
00037  * that both that copyright notice and this permission notice appear
00038  * in supporting documentation.  Silicon Graphics makes no
00039  * representations about the suitability of this software for any
00040  * purpose.  It is provided "as is" without express or implied warranty.
00041  */
00042 
00043 /** @file bitset
00044  *  This is a Standard C++ Library header.
00045  */
00046 
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 {
00068   /**
00069    *  @if maint
00070    *  Base class, general case.  It is a class inveriant that _Nw will be
00071    *  nonnegative.
00072    *
00073    *  See documentation for bitset.
00074    *  @endif
00075   */
00076   template<size_t _Nw>
00077     struct _Base_bitset
00078     {
00079       typedef unsigned long _WordT;
00080 
00081       /// 0 is the least significant word.
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 
00327   /**
00328    *  @if maint
00329    *  Base class, specialization for a single word.
00330    *
00331    *  See documentation for bitset.
00332    *  @endif
00333   */
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 
00453   /**
00454    *  @if maint
00455    *  Base class, specialization for no storage (zero-length %bitset).
00456    *
00457    *  See documentation for bitset.
00458    *  @endif
00459   */
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 
00580   /**
00581    *  @brief  The %bitset class represents a @e fixed-size sequence of bits.
00582    *
00583    *  @ingroup Containers
00584    *
00585    *  (Note that %bitset does @e not meet the formal requirements of a
00586    *  <a href="tables.html#65">container</a>.  Mainly, it lacks iterators.)
00587    *
00588    *  The template argument, @a Nb, may be any non-negative number,
00589    *  specifying the number of bits (e.g., "0", "12", "1024*1024").
00590    *
00591    *  In the general unoptimized case, storage is allocated in word-sized
00592    *  blocks.  Let B be the number of bits in a word, then (Nb+(B-1))/B
00593    *  words will be used for storage.  B - Nb%B bits are unused.  (They are
00594    *  the high-order bits in the highest word.)  It is a class invariant
00595    *  that those unused bits are always zero.
00596    *
00597    *  If you think of %bitset as "a simple array of bits," be aware that
00598    *  your mental picture is reversed:  a %bitset behaves the same way as
00599    *  bits in integers do, with the bit at index 0 in the "least significant
00600    *  / right-hand" position, and the bit at index Nb-1 in the "most
00601    *  significant / left-hand" position.  Thus, unlike other containers, a
00602    *  %bitset's index "counts from right to left," to put it very loosely.
00603    *
00604    *  This behavior is preserved when translating to and from strings.  For
00605    *  example, the first line of the following program probably prints
00606    *  "b('a') is 0001100001" on a modern ASCII system.
00607    *
00608    *  @code
00609    *     #include <bitset>
00610    *     #include <iostream>
00611    *     #include <sstream>
00612    *
00613    *     using namespace std;
00614    *
00615    *     int main()
00616    *     {
00617    *         long         a = 'a';
00618    *         bitset<10>   b(a);
00619    *
00620    *         cout << "b('a') is " << b << endl;
00621    *
00622    *         ostringstream s;
00623    *         s << b;
00624    *         string  str = s.str();
00625    *         cout << "index 3 in the string is " << str[3] << " but\n"
00626    *              << "index 3 in the bitset is " << b[3] << endl;
00627    *     }
00628    *  @endcode
00629    *
00630    *  Also see http://gcc.gnu.org/onlinedocs/libstdc++/ext/sgiexts.html#ch23
00631    *  for a description of extensions.
00632    *
00633    *  @if maint
00634    *  Most of the actual code isn't contained in %bitset<> itself, but in the
00635    *  base class _Base_bitset.  The base class works with whole words, not with
00636    *  individual bits.  This allows us to specialize _Base_bitset for the
00637    *  important special case where the %bitset is only a single word.
00638    *
00639    *  Extra confusion can result due to the fact that the storage for
00640    *  _Base_bitset @e is a regular array, and is indexed as such.  This is
00641    *  carefully encapsulated.
00642    *  @endif
00643   */
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:
00660       /**
00661        *  This encapsulates the concept of a single bit.  An instance of this
00662        *  class is a proxy for an actual bit; this way the individual bit
00663        *  operations are done as faster word-size bitwise instructions.
00664        *
00665        *  Most users will never need to use this class directly; conversions
00666        *  to and from bool are automatic and should be transparent.  Overloaded
00667        *  operators help to preserve the illusion.
00668        *
00669        *  (On a typical system, this "bit %reference" is 64 times the size of
00670        *  an actual bit.  Ha.)
00671        */
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:
00734       /// All bits set to zero.
00735       bitset()
00736       { }
00737 
00738       /// Initial bits bitwise-copied from a single word (others set to zero).
00739       bitset(unsigned long __val)
00740       : _Base(__val)
00741       { _M_do_sanitize(); }
00742 
00743       /**
00744        *  @brief  Use a subset of a string.
00745        *  @param  s  A string of '0' and '1' characters.
00746        *  @param  position  Index of the first character in @a s to use;
00747        *                    defaults to zero.
00748        *  @throw  std::out_of_range  If @a pos is bigger the size of @a s.
00749        *  @throw  std::invalid_argument  If a character appears in the string
00750        *                                 which is neither '0' nor '1'.
00751        */
00752       template<class _CharT, class _Traits, class _Alloc>
00753     explicit
00754     bitset(const 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                   basic_string<_CharT, _Traits, _Alloc>::npos);
00763     }
00764 
00765       /**
00766        *  @brief  Use a subset of a string.
00767        *  @param  s  A string of '0' and '1' characters.
00768        *  @param  position  Index of the first character in @a s to use.
00769        *  @param  n    The number of characters to copy.
00770        *  @throw  std::out_of_range  If @a pos is bigger the size of @a s.
00771        *  @throw  std::invalid_argument  If a character appears in the string
00772        *                                 which is neither '0' nor '1'.
00773        */
00774       template<class _CharT, class _Traits, class _Alloc>
00775     bitset(const 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:
00786       //@{
00787       /**
00788        *  @brief  Operations on bitsets.
00789        *  @param  rhs  A same-sized bitset.
00790        *
00791        *  These should be self-explanatory.
00792        */
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       }
00813       //@}
00814       
00815       //@{
00816       /**
00817        *  @brief  Operations on bitsets.
00818        *  @param  position  The number of places to shift.
00819        *
00820        *  These should be self-explanatory.
00821        */
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       }
00847       //@}
00848       
00849       //@{
00850       /**
00851        *  These versions of single-bit set, reset, flip, and test are
00852        *  extensions from the SGI version.  They do no range checking.
00853        *  @ingroup SGIextensions
00854        */
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)); }
00890       //@}
00891       
00892       // Set, reset, and flip.
00893       /**
00894        *  @brief Sets every bit to true.
00895        */
00896       bitset<_Nb>&
00897       set()
00898       {
00899     this->_M_do_set();
00900     this->_M_do_sanitize();
00901     return *this;
00902       }
00903 
00904       /**
00905        *  @brief Sets a given bit to a particular value.
00906        *  @param  position  The index of the bit.
00907        *  @param  val  Either true or false, defaults to true.
00908        *  @throw  std::out_of_range  If @a pos is bigger the size of the %set.
00909        */
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 
00918       /**
00919        *  @brief Sets every bit to false.
00920        */
00921       bitset<_Nb>&
00922       reset()
00923       {
00924     this->_M_do_reset();
00925     return *this;
00926       }
00927 
00928       /**
00929        *  @brief Sets a given bit to false.
00930        *  @param  position  The index of the bit.
00931        *  @throw  std::out_of_range  If @a pos is bigger the size of the %set.
00932        *
00933        *  Same as writing @c set(pos,false).
00934        */
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       
00943       /**
00944        *  @brief Toggles every bit to its opposite value.
00945        */
00946       bitset<_Nb>&
00947       flip()
00948       {
00949     this->_M_do_flip();
00950     this->_M_do_sanitize();
00951     return *this;
00952       }
00953 
00954       /**
00955        *  @brief Toggles a given bit to its opposite value.
00956        *  @param  position  The index of the bit.
00957        *  @throw  std::out_of_range  If @a pos is bigger the size of the %set.
00958        */
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       
00967       /// See the no-argument flip().
00968       bitset<_Nb>
00969       operator~() const
00970       { return bitset<_Nb>(*this).flip(); }
00971 
00972       //@{
00973       /**
00974        *  @brief  Array-indexing support.
00975        *  @param  position  Index into the %bitset.
00976        *  @return  A bool for a 'const %bitset'.  For non-const bitsets, an
00977        *           instance of the reference proxy class.
00978        *  @note  These operators do no range checking and throw no exceptions,
00979        *         as required by DR 11 to the standard.
00980        *
00981        *  @if maint
00982        *  _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already
00983        *  resolves DR 11 (items 1 and 2), but does not do the range-checking
00984        *  required by that DR's resolution.  -pme
00985        *  The DR has since been changed:  range-checking is a precondition
00986        *  (users' responsibility), and these functions must not throw.  -pme
00987        *  @endif
00988        */
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); }
00996       //@}
00997       
00998       /**
00999        *  @brief Retuns a numerical interpretation of the %bitset.
01000        *  @return  The integral equivalent of the bits.
01001        *  @throw  std::overflow_error  If there are too many bits to be
01002        *                               represented in an @c unsigned @c long.
01003        */
01004       unsigned long
01005       to_ulong() const
01006       { return this->_M_do_to_ulong(); }
01007 
01008       /**
01009        *  @brief Retuns a character interpretation of the %bitset.
01010        *  @return  The string equivalent of the bits.
01011        *
01012        *  Note the ordering of the bits:  decreasing character positions
01013        *  correspond to increasing bit positions (see the main class notes for
01014        *  an example).
01015        */
01016       template<class _CharT, class _Traits, class _Alloc>
01017     basic_string<_CharT, _Traits, _Alloc>
01018     to_string() const
01019     {
01020       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     basic_string<_CharT, _Traits, allocator<_CharT> >
01029     to_string() const
01030     { return to_string<_CharT, _Traits, allocator<_CharT> >(); }
01031 
01032       template<class _CharT>
01033     basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
01034     to_string() const
01035     { return to_string<_CharT, char_traits<_CharT>, allocator<_CharT> >(); }
01036 
01037       basic_string<char, char_traits<char>, allocator<char> >
01038       to_string() const
01039       { return to_string<char, char_traits<char>, allocator<char> >(); }
01040 
01041       // Helper functions for string operations.
01042       template<class _CharT, class _Traits, class _Alloc>
01043     void
01044     _M_copy_from_string(const basic_string<_CharT, _Traits, _Alloc>& __s,
01045                 size_t, size_t);
01046 
01047       template<class _CharT, class _Traits, class _Alloc>
01048     void
01049     _M_copy_to_string(basic_string<_CharT, _Traits, _Alloc>&) const;
01050 
01051       /// Returns the number of bits which are set.
01052       size_t
01053       count() const
01054       { return this->_M_do_count(); }
01055 
01056       /// Returns the total number of bits.
01057       size_t
01058       size() const
01059       { return _Nb; }
01060 
01061       //@{
01062       /// These comparisons for equality/inequality are, well, @e bitwise.
01063       bool
01064       operator==(const bitset<_Nb>& __rhs) const
01065       { return this->_M_is_equal(__rhs); }
01066 
01067       bool
01068       operator!=(const bitset<_Nb>& __rhs) const
01069       { return !this->_M_is_equal(__rhs); }
01070       //@}
01071       
01072       /**
01073        *  @brief Tests the value of a bit.
01074        *  @param  position  The index of a bit.
01075        *  @return  The value at @a pos.
01076        *  @throw  std::out_of_range  If @a pos is bigger the size of the %set.
01077        */
01078       bool
01079       test(size_t __position) const
01080       {
01081     if (__position >= _Nb)
01082       __throw_out_of_range(__N("bitset::test"));
01083     return _Unchecked_test(__position);
01084       }
01085       
01086       /**
01087        *  @brief Tests whether any of the bits are on.
01088        *  @return  True if at least one bit is set.
01089        */
01090       bool
01091       any() const
01092       { return this->_M_is_any(); }
01093 
01094       /**
01095        *  @brief Tests whether any of the bits are on.
01096        *  @return  True if none of the bits are set.
01097        */
01098       bool
01099       none() const
01100       { return !this->_M_is_any(); }
01101 
01102       //@{
01103       /// Self-explanatory.
01104       bitset<_Nb>
01105       operator<<(size_t __position) const
01106       { return bitset<_Nb>(*this) <<= __position; }
01107 
01108       bitset<_Nb>
01109       operator>>(size_t __position) const
01110       { return bitset<_Nb>(*this) >>= __position; }
01111       //@}
01112       
01113       /**
01114        *  @brief  Finds the index of the first "on" bit.
01115        *  @return  The index of the first bit set, or size() if not found.
01116        *  @ingroup SGIextensions
01117        *  @sa  _Find_next
01118        */
01119       size_t
01120       _Find_first() const
01121       { return this->_M_do_find_first(_Nb); }
01122 
01123       /**
01124        *  @brief  Finds the index of the next "on" bit after prev.
01125        *  @return  The index of the next bit set, or size() if not found.
01126        *  @param  prev  Where to start searching.
01127        *  @ingroup SGIextensions
01128        *  @sa  _Find_first
01129        */
01130       size_t
01131       _Find_next(size_t __prev ) const
01132       { return this->_M_do_find_next(__prev, _Nb); }
01133     };
01134 
01135   // Definitions of non-inline member functions.
01136   template<size_t _Nb>
01137     template<class _CharT, class _Traits, class _Alloc>
01138       void
01139       bitset<_Nb>::_M_copy_from_string(const basic_string<_CharT, _Traits,
01140                        _Alloc>& __s, size_t __pos, size_t __n)
01141       {
01142     reset();
01143     const size_t __nbits = std::min(_Nb, std::min(__n, __s.size() - __pos));
01144     for (size_t __i = 0; __i < __nbits; ++__i)
01145       {
01146         switch(__s[__pos + __nbits - __i - 1])
01147           {
01148           case '0':
01149         break;
01150           case '1':
01151         set(__i);
01152         break;
01153           default:
01154         __throw_invalid_argument(__N("bitset::_M_copy_from_string"));
01155           }
01156       }
01157       }
01158 
01159   template<size_t _Nb>
01160     template<class _CharT, class _Traits, class _Alloc>
01161       void
01162       bitset<_Nb>::_M_copy_to_string(basic_string<_CharT, _Traits,
01163                      _Alloc>& __s) const
01164       {
01165     __s.assign(_Nb, '0');
01166     for (size_t __i = 0; __i < _Nb; ++__i)
01167       if (_Unchecked_test(__i))
01168         __s[_Nb - 1 - __i] = '1';
01169       }
01170 
01171   // 23.3.5.3 bitset operations:
01172   //@{
01173   /**
01174    *  @brief  Global bitwise operations on bitsets.
01175    *  @param  x  A bitset.
01176    *  @param  y  A bitset of the same size as @a x.
01177    *  @return  A new bitset.
01178    *
01179    *  These should be self-explanatory.
01180   */
01181   template<size_t _Nb>
01182     inline bitset<_Nb>
01183     operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01184     {
01185       bitset<_Nb> __result(__x);
01186       __result &= __y;
01187       return __result;
01188     }
01189 
01190   template<size_t _Nb>
01191     inline bitset<_Nb>
01192     operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01193     {
01194       bitset<_Nb> __result(__x);
01195       __result |= __y;
01196       return __result;
01197     }
01198 
01199   template <size_t _Nb>
01200     inline bitset<_Nb>
01201     operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
01202     {
01203       bitset<_Nb> __result(__x);
01204       __result ^= __y;
01205       return __result;
01206     }
01207   //@}
01208 
01209   //@{
01210   /**
01211    *  @brief Global I/O operators for bitsets.
01212    *
01213    *  Direct I/O between streams and bitsets is supported.  Output is
01214    *  straightforward.  Input will skip whitespace, only accept '0' and '1'
01215    *  characters, and will only extract as many digits as the %bitset will
01216    *  hold.
01217   */
01218   template<class _CharT, class _Traits, size_t _Nb>
01219     basic_istream<_CharT, _Traits>&
01220     operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
01221     {
01222       typedef typename _Traits::char_type char_type;
01223       basic_string<_CharT, _Traits> __tmp;
01224       __tmp.reserve(_Nb);
01225 
01226       ios_base::iostate __state = ios_base::goodbit;
01227       typename basic_istream<_CharT, _Traits>::sentry __sentry(__is);
01228       if (__sentry)
01229     {
01230       try
01231         {
01232           basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
01233           // _GLIBCXX_RESOLVE_LIB_DEFECTS
01234           // 303. Bitset input operator underspecified
01235           const char_type __zero = __is.widen('0');
01236           const char_type __one = __is.widen('1');
01237           for (size_t __i = 0; __i < _Nb; ++__i)
01238         {
01239           static typename _Traits::int_type __eof = _Traits::eof();
01240           
01241           typename _Traits::int_type __c1 = __buf->sbumpc();
01242           if (_Traits::eq_int_type(__c1, __eof))
01243             {
01244               __state |= ios_base::eofbit;
01245               break;
01246             }
01247           else
01248             {
01249               const char_type __c2 = _Traits::to_char_type(__c1);
01250               if (__c2 == __zero)
01251             __tmp.push_back('0');
01252               else if (__c2 == __one)
01253             __tmp.push_back('1');
01254               else if (_Traits::eq_int_type(__buf->sputbackc(__c2),
01255                             __eof))
01256             {
01257               __state |= ios_base::failbit;
01258               break;
01259             }
01260             }
01261         }
01262         }
01263       catch(...)
01264         { __is._M_setstate(ios_base::badbit); }
01265     }
01266 
01267       if (__tmp.empty() && _Nb)
01268     __state |= ios_base::failbit;
01269       else
01270     __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb);
01271       if (__state)
01272     __is.setstate(__state);
01273       return __is;
01274     }
01275 
01276   template <class _CharT, class _Traits, size_t _Nb>
01277     basic_ostream<_CharT, _Traits>&
01278     operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x)
01279     {
01280       basic_string<_CharT, _Traits> __tmp;
01281       __x._M_copy_to_string(__tmp);
01282       return __os << __tmp;
01283     }
01284   //@}
01285 } // namespace std
01286 
01287 #undef _GLIBCXX_BITSET_WORDS
01288 #undef _GLIBCXX_BITSET_BITS_PER_WORD
01289 
01290 #ifdef _GLIBCXX_DEBUG
01291 # include <debug/bitset>
01292 #endif
01293 
01294 #endif /* _GLIBCXX_BITSET */

Generated on Wed Apr 27 18:35:10 2005 for libstdc++ source by  doxygen 1.4.2