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