|
libstdc++
|
00001 // TR2 <dynamic_bitset> -*- C++ -*- 00002 00003 // Copyright (C) 2009-2019 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file tr2/dynamic_bitset 00026 * This is a TR2 C++ Library header. 00027 */ 00028 00029 #ifndef _GLIBCXX_TR2_DYNAMIC_BITSET 00030 #define _GLIBCXX_TR2_DYNAMIC_BITSET 1 00031 00032 #pragma GCC system_header 00033 00034 #include <limits> 00035 #include <vector> 00036 #include <string> 00037 #include <istream> 00038 #include <bits/functexcept.h> 00039 #include <bits/stl_algo.h> // For fill 00040 #include <bits/cxxabi_forced.h> 00041 00042 namespace std _GLIBCXX_VISIBILITY(default) 00043 { 00044 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00045 00046 namespace tr2 00047 { 00048 /** 00049 * @defgroup dynamic_bitset Dynamic Bitset. 00050 * @ingroup extensions 00051 * 00052 * @{ 00053 */ 00054 00055 /** 00056 * Base class, general case. 00057 * 00058 * See documentation for dynamic_bitset. 00059 */ 00060 template<typename _WordT = unsigned long long, 00061 typename _Alloc = std::allocator<_WordT>> 00062 struct __dynamic_bitset_base 00063 { 00064 static_assert(std::is_unsigned<_WordT>::value, "template argument " 00065 "_WordT not an unsigned integral type"); 00066 00067 typedef _WordT block_type; 00068 typedef _Alloc allocator_type; 00069 typedef size_t size_type; 00070 00071 static const size_type _S_bits_per_block = __CHAR_BIT__ * sizeof(block_type); 00072 static const size_type npos = static_cast<size_type>(-1); 00073 00074 /// 0 is the least significant word. 00075 std::vector<block_type, allocator_type> _M_w; 00076 00077 explicit 00078 __dynamic_bitset_base(const allocator_type& __alloc) 00079 : _M_w(__alloc) 00080 { } 00081 00082 __dynamic_bitset_base() = default; 00083 __dynamic_bitset_base(const __dynamic_bitset_base&) = default; 00084 __dynamic_bitset_base(__dynamic_bitset_base&& __b) = default; 00085 __dynamic_bitset_base& operator=(const __dynamic_bitset_base&) = default; 00086 __dynamic_bitset_base& operator=(__dynamic_bitset_base&&) = default; 00087 ~__dynamic_bitset_base() = default; 00088 00089 explicit 00090 __dynamic_bitset_base(size_type __nbits, unsigned long long __val = 0ULL, 00091 const allocator_type& __alloc = allocator_type()) 00092 : _M_w(__nbits / _S_bits_per_block + (__nbits % _S_bits_per_block > 0), 00093 block_type(0), __alloc) 00094 { 00095 if (__nbits < std::numeric_limits<decltype(__val)>::digits) 00096 __val &= ~(-1ULL << __nbits); 00097 if (__val == 0) 00098 return; 00099 00100 if _GLIBCXX17_CONSTEXPR (sizeof(__val) == sizeof(block_type)) 00101 _M_w[0] = __val; 00102 else 00103 { 00104 const size_t __n 00105 = std::min(_M_w.size(), sizeof(__val) / sizeof(block_type)); 00106 for (size_t __i = 0; __val && __i < __n; ++__i) 00107 { 00108 _M_w[__i] = static_cast<block_type>(__val); 00109 __val >>= _S_bits_per_block; 00110 } 00111 } 00112 } 00113 00114 void 00115 _M_swap(__dynamic_bitset_base& __b) noexcept 00116 { this->_M_w.swap(__b._M_w); } 00117 00118 void 00119 _M_clear() noexcept 00120 { this->_M_w.clear(); } 00121 00122 void 00123 _M_resize(size_t __nbits, bool __value) 00124 { 00125 size_t __sz = __nbits / _S_bits_per_block; 00126 if (__nbits % _S_bits_per_block > 0) 00127 ++__sz; 00128 if (__sz != this->_M_w.size()) 00129 { 00130 block_type __val = 0; 00131 if (__value) 00132 __val = std::numeric_limits<block_type>::max(); 00133 this->_M_w.resize(__sz, __val); 00134 } 00135 } 00136 00137 allocator_type 00138 _M_get_allocator() const noexcept 00139 { return this->_M_w.get_allocator(); } 00140 00141 static size_type 00142 _S_whichword(size_type __pos) noexcept 00143 { return __pos / _S_bits_per_block; } 00144 00145 static size_type 00146 _S_whichbyte(size_type __pos) noexcept 00147 { return (__pos % _S_bits_per_block) / __CHAR_BIT__; } 00148 00149 static size_type 00150 _S_whichbit(size_type __pos) noexcept 00151 { return __pos % _S_bits_per_block; } 00152 00153 static block_type 00154 _S_maskbit(size_type __pos) noexcept 00155 { return (static_cast<block_type>(1)) << _S_whichbit(__pos); } 00156 00157 block_type& 00158 _M_getword(size_type __pos) noexcept 00159 { return this->_M_w[_S_whichword(__pos)]; } 00160 00161 block_type 00162 _M_getword(size_type __pos) const noexcept 00163 { return this->_M_w[_S_whichword(__pos)]; } 00164 00165 block_type& 00166 _M_hiword() noexcept 00167 { return this->_M_w[_M_w.size() - 1]; } 00168 00169 block_type 00170 _M_hiword() const noexcept 00171 { return this->_M_w[_M_w.size() - 1]; } 00172 00173 void 00174 _M_do_and(const __dynamic_bitset_base& __x) noexcept 00175 { 00176 if (__x._M_w.size() == this->_M_w.size()) 00177 for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 00178 this->_M_w[__i] &= __x._M_w[__i]; 00179 else 00180 return; 00181 } 00182 00183 void 00184 _M_do_or(const __dynamic_bitset_base& __x) noexcept 00185 { 00186 if (__x._M_w.size() == this->_M_w.size()) 00187 for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 00188 this->_M_w[__i] |= __x._M_w[__i]; 00189 else 00190 return; 00191 } 00192 00193 void 00194 _M_do_xor(const __dynamic_bitset_base& __x) noexcept 00195 { 00196 if (__x._M_w.size() == this->_M_w.size()) 00197 for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 00198 this->_M_w[__i] ^= __x._M_w[__i]; 00199 else 00200 return; 00201 } 00202 00203 void 00204 _M_do_dif(const __dynamic_bitset_base& __x) noexcept 00205 { 00206 if (__x._M_w.size() == this->_M_w.size()) 00207 for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 00208 this->_M_w[__i] &= ~__x._M_w[__i]; 00209 else 00210 return; 00211 } 00212 00213 void 00214 _M_do_left_shift(size_t __shift); 00215 00216 void 00217 _M_do_right_shift(size_t __shift); 00218 00219 void 00220 _M_do_flip() noexcept 00221 { 00222 for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 00223 this->_M_w[__i] = ~this->_M_w[__i]; 00224 } 00225 00226 void 00227 _M_do_set() noexcept 00228 { 00229 for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 00230 this->_M_w[__i] = static_cast<block_type>(-1); 00231 } 00232 00233 void 00234 _M_do_reset() noexcept 00235 { 00236 std::fill(_M_w.begin(), _M_w.end(), static_cast<block_type>(0)); 00237 } 00238 00239 bool 00240 _M_is_equal(const __dynamic_bitset_base& __x) const noexcept 00241 { 00242 if (__x._M_w.size() == this->_M_w.size()) 00243 { 00244 for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 00245 if (this->_M_w[__i] != __x._M_w[__i]) 00246 return false; 00247 return true; 00248 } 00249 else 00250 return false; 00251 } 00252 00253 bool 00254 _M_is_less(const __dynamic_bitset_base& __x) const noexcept 00255 { 00256 if (__x._M_w.size() == this->_M_w.size()) 00257 { 00258 for (size_t __i = this->_M_w.size(); __i > 0; --__i) 00259 { 00260 if (this->_M_w[__i-1] < __x._M_w[__i-1]) 00261 return true; 00262 else if (this->_M_w[__i-1] > __x._M_w[__i-1]) 00263 return false; 00264 } 00265 return false; 00266 } 00267 else 00268 return false; 00269 } 00270 00271 size_t 00272 _M_are_all_aux() const noexcept 00273 { 00274 for (size_t __i = 0; __i < this->_M_w.size() - 1; ++__i) 00275 if (_M_w[__i] != static_cast<block_type>(-1)) 00276 return 0; 00277 return ((this->_M_w.size() - 1) * _S_bits_per_block 00278 + __builtin_popcountll(this->_M_hiword())); 00279 } 00280 00281 bool 00282 _M_is_any() const noexcept 00283 { 00284 for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 00285 if (this->_M_w[__i] != static_cast<block_type>(0)) 00286 return true; 00287 return false; 00288 } 00289 00290 bool 00291 _M_is_subset_of(const __dynamic_bitset_base& __b) noexcept 00292 { 00293 if (__b._M_w.size() == this->_M_w.size()) 00294 { 00295 for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 00296 if (this->_M_w[__i] != (this->_M_w[__i] | __b._M_w[__i])) 00297 return false; 00298 return true; 00299 } 00300 else 00301 return false; 00302 } 00303 00304 bool 00305 _M_is_proper_subset_of(const __dynamic_bitset_base& __b) const noexcept 00306 { 00307 if (this->is_subset_of(__b)) 00308 { 00309 if (*this == __b) 00310 return false; 00311 else 00312 return true; 00313 } 00314 else 00315 return false; 00316 } 00317 00318 size_t 00319 _M_do_count() const noexcept 00320 { 00321 size_t __result = 0; 00322 for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 00323 __result += __builtin_popcountll(this->_M_w[__i]); 00324 return __result; 00325 } 00326 00327 size_type 00328 _M_size() const noexcept 00329 { return this->_M_w.size(); } 00330 00331 unsigned long 00332 _M_do_to_ulong() const; 00333 00334 unsigned long long 00335 _M_do_to_ullong() const; 00336 00337 // find first "on" bit 00338 size_type 00339 _M_do_find_first(size_t __not_found) const; 00340 00341 // find the next "on" bit that follows "prev" 00342 size_type 00343 _M_do_find_next(size_t __prev, size_t __not_found) const; 00344 00345 // do append of block 00346 void 00347 _M_do_append_block(block_type __block, size_type __pos) 00348 { 00349 size_t __offset = __pos % _S_bits_per_block; 00350 if (__offset == 0) 00351 this->_M_w.push_back(__block); 00352 else 00353 { 00354 this->_M_hiword() |= (__block << __offset); 00355 this->_M_w.push_back(__block >> (_S_bits_per_block - __offset)); 00356 } 00357 } 00358 }; 00359 00360 /** 00361 * @brief The %dynamic_bitset class represents a sequence of bits. 00362 * 00363 * See N2050, 00364 * Proposal to Add a Dynamically Sizeable Bitset to the Standard Library. 00365 * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2050.pdf 00366 * 00367 * In the general unoptimized case, storage is allocated in 00368 * word-sized blocks. Let B be the number of bits in a word, then 00369 * (Nb+(B-1))/B words will be used for storage. B - Nb%B bits are 00370 * unused. (They are the high-order bits in the highest word.) It 00371 * is a class invariant that those unused bits are always zero. 00372 * 00373 * If you think of %dynamic_bitset as "a simple array of bits," be 00374 * aware that your mental picture is reversed: a %dynamic_bitset 00375 * behaves the same way as bits in integers do, with the bit at 00376 * index 0 in the "least significant / right-hand" position, and 00377 * the bit at index Nb-1 in the "most significant / left-hand" 00378 * position. Thus, unlike other containers, a %dynamic_bitset's 00379 * index "counts from right to left," to put it very loosely. 00380 * 00381 * This behavior is preserved when translating to and from strings. 00382 * For example, the first line of the following program probably 00383 * prints "b('a') is 0001100001" on a modern ASCII system. 00384 * 00385 * @code 00386 * #include <dynamic_bitset> 00387 * #include <iostream> 00388 * #include <sstream> 00389 * 00390 * using namespace std; 00391 * 00392 * int main() 00393 * { 00394 * long a = 'a'; 00395 * dynamic_bitset<> b(a); 00396 * 00397 * cout << "b('a') is " << b << endl; 00398 * 00399 * ostringstream s; 00400 * s << b; 00401 * string str = s.str(); 00402 * cout << "index 3 in the string is " << str[3] << " but\n" 00403 * << "index 3 in the bitset is " << b[3] << endl; 00404 * } 00405 * @endcode 00406 * 00407 * Most of the actual code isn't contained in %dynamic_bitset<> 00408 * itself, but in the base class __dynamic_bitset_base. The base 00409 * class works with whole words, not with individual bits. This 00410 * allows us to specialize __dynamic_bitset_base for the important 00411 * special case where the %dynamic_bitset is only a single word. 00412 * 00413 * Extra confusion can result due to the fact that the storage for 00414 * __dynamic_bitset_base @e is a vector, and is indexed as such. This is 00415 * carefully encapsulated. 00416 */ 00417 template<typename _WordT = unsigned long long, 00418 typename _Alloc = std::allocator<_WordT>> 00419 class dynamic_bitset 00420 : private __dynamic_bitset_base<_WordT, _Alloc> 00421 { 00422 static_assert(std::is_unsigned<_WordT>::value, "template argument " 00423 "_WordT not an unsigned integral type"); 00424 00425 public: 00426 00427 typedef __dynamic_bitset_base<_WordT, _Alloc> _Base; 00428 typedef _WordT block_type; 00429 typedef _Alloc allocator_type; 00430 typedef size_t size_type; 00431 00432 static const size_type bits_per_block = __CHAR_BIT__ * sizeof(block_type); 00433 // Use this: constexpr size_type std::numeric_limits<size_type>::max(). 00434 static const size_type npos = static_cast<size_type>(-1); 00435 00436 private: 00437 00438 // Clear the unused bits in the uppermost word. 00439 void 00440 _M_do_sanitize() 00441 { 00442 size_type __shift = this->_M_Nb % bits_per_block; 00443 if (__shift > 0) 00444 this->_M_hiword() &= block_type(~(block_type(-1) << __shift)); 00445 } 00446 00447 // Set the unused bits in the uppermost word. 00448 void 00449 _M_do_fill() 00450 { 00451 size_type __shift = this->_M_Nb % bits_per_block; 00452 if (__shift > 0) 00453 this->_M_hiword() |= block_type(block_type(-1) << __shift); 00454 } 00455 00456 /** 00457 * These versions of single-bit set, reset, flip, and test 00458 * do no range checking. 00459 */ 00460 dynamic_bitset& 00461 _M_unchecked_set(size_type __pos) noexcept 00462 { 00463 this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); 00464 return *this; 00465 } 00466 00467 dynamic_bitset& 00468 _M_unchecked_set(size_type __pos, int __val) noexcept 00469 { 00470 if (__val) 00471 this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); 00472 else 00473 this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); 00474 return *this; 00475 } 00476 00477 dynamic_bitset& 00478 _M_unchecked_reset(size_type __pos) noexcept 00479 { 00480 this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); 00481 return *this; 00482 } 00483 00484 dynamic_bitset& 00485 _M_unchecked_flip(size_type __pos) noexcept 00486 { 00487 this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); 00488 return *this; 00489 } 00490 00491 bool 00492 _M_unchecked_test(size_type __pos) const noexcept 00493 { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) 00494 != static_cast<_WordT>(0)); } 00495 00496 size_type _M_Nb = 0; 00497 00498 public: 00499 /** 00500 * This encapsulates the concept of a single bit. An instance 00501 * of this class is a proxy for an actual bit; this way the 00502 * individual bit operations are done as faster word-size 00503 * bitwise instructions. 00504 * 00505 * Most users will never need to use this class directly; 00506 * conversions to and from bool are automatic and should be 00507 * transparent. Overloaded operators help to preserve the 00508 * illusion. 00509 * 00510 * (On a typical system, this "bit %reference" is 64 times the 00511 * size of an actual bit. Ha.) 00512 */ 00513 class reference 00514 { 00515 friend class dynamic_bitset; 00516 00517 block_type *_M_wp; 00518 size_type _M_bpos; 00519 00520 public: 00521 reference(dynamic_bitset& __b, size_type __pos) noexcept 00522 { 00523 this->_M_wp = &__b._M_getword(__pos); 00524 this->_M_bpos = _Base::_S_whichbit(__pos); 00525 } 00526 00527 // For b[i] = __x; 00528 reference& 00529 operator=(bool __x) noexcept 00530 { 00531 if (__x) 00532 *this->_M_wp |= _Base::_S_maskbit(this->_M_bpos); 00533 else 00534 *this->_M_wp &= ~_Base::_S_maskbit(this->_M_bpos); 00535 return *this; 00536 } 00537 00538 // For b[i] = b[__j]; 00539 reference& 00540 operator=(const reference& __j) noexcept 00541 { 00542 if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos))) 00543 *this->_M_wp |= _Base::_S_maskbit(this->_M_bpos); 00544 else 00545 *this->_M_wp &= ~_Base::_S_maskbit(this->_M_bpos); 00546 return *this; 00547 } 00548 00549 // Flips the bit 00550 bool 00551 operator~() const noexcept 00552 { return (*(_M_wp) & _Base::_S_maskbit(this->_M_bpos)) == 0; } 00553 00554 // For __x = b[i]; 00555 operator bool() const noexcept 00556 { return (*(this->_M_wp) & _Base::_S_maskbit(this->_M_bpos)) != 0; } 00557 00558 // For b[i].flip(); 00559 reference& 00560 flip() noexcept 00561 { 00562 *this->_M_wp ^= _Base::_S_maskbit(this->_M_bpos); 00563 return *this; 00564 } 00565 }; 00566 00567 friend class reference; 00568 00569 typedef bool const_reference; 00570 00571 // 23.3.5.1 constructors: 00572 00573 /// All bits set to zero. 00574 dynamic_bitset() = default; 00575 00576 /// All bits set to zero. 00577 explicit 00578 dynamic_bitset(const allocator_type& __alloc) 00579 : _Base(__alloc) 00580 { } 00581 00582 /// Initial bits bitwise-copied from a single word (others set to zero). 00583 explicit 00584 dynamic_bitset(size_type __nbits, unsigned long long __val = 0ULL, 00585 const allocator_type& __alloc = allocator_type()) 00586 : _Base(__nbits, __val, __alloc), 00587 _M_Nb(__nbits) 00588 { } 00589 00590 dynamic_bitset(initializer_list<block_type> __il, 00591 const allocator_type& __alloc = allocator_type()) 00592 : _Base(__alloc) 00593 { this->append(__il); } 00594 00595 /** 00596 * @brief Use a subset of a string. 00597 * @param __str A string of '0' and '1' characters. 00598 * @param __pos Index of the first character in @p __str to use. 00599 * @param __n The number of characters to copy. 00600 * @param __zero The character to use for unset bits. 00601 * @param __one The character to use for set bits. 00602 * @param __alloc An allocator. 00603 * @throw std::out_of_range If @p __pos is bigger the size of @p __str. 00604 * @throw std::invalid_argument If a character appears in the string 00605 * which is neither '0' nor '1'. 00606 */ 00607 template<typename _CharT, typename _Traits, typename _Alloc1> 00608 explicit 00609 dynamic_bitset(const std::basic_string<_CharT, _Traits, _Alloc1>& __str, 00610 typename basic_string<_CharT,_Traits,_Alloc1>::size_type 00611 __pos = 0, 00612 typename basic_string<_CharT,_Traits,_Alloc1>::size_type 00613 __n = std::basic_string<_CharT, _Traits, _Alloc1>::npos, 00614 _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'), 00615 const allocator_type& __alloc = allocator_type()) 00616 : _Base(__alloc) 00617 { 00618 if (__pos > __str.size()) 00619 __throw_out_of_range(__N("dynamic_bitset::bitset initial position " 00620 "not valid")); 00621 00622 // Watch for npos. 00623 this->_M_Nb = (__n > __str.size() ? __str.size() - __pos : __n); 00624 this->resize(this->_M_Nb); 00625 this->_M_copy_from_string(__str, __pos, __n); 00626 } 00627 00628 /** 00629 * @brief Construct from a string. 00630 * @param __str A string of '0' and '1' characters. 00631 * @param __alloc An allocator. 00632 * @throw std::invalid_argument If a character appears in the string 00633 * which is neither '0' nor '1'. 00634 */ 00635 explicit 00636 dynamic_bitset(const char* __str, 00637 const allocator_type& __alloc = allocator_type()) 00638 : _Base(__builtin_strlen(__str), 0ULL, __alloc), 00639 _M_Nb(__builtin_strlen(__str)) 00640 { 00641 this->_M_copy_from_ptr(__str, _M_Nb, 0, _M_Nb); 00642 } 00643 00644 /// Copy constructor. 00645 dynamic_bitset(const dynamic_bitset&) = default; 00646 00647 /// Move constructor. 00648 dynamic_bitset(dynamic_bitset&& __b) noexcept 00649 : _Base(std::move(__b)), _M_Nb(__b._M_Nb) 00650 { __b.clear(); } 00651 00652 /// Swap with another bitset. 00653 void 00654 swap(dynamic_bitset& __b) noexcept 00655 { 00656 this->_M_swap(__b); 00657 std::swap(this->_M_Nb, __b._M_Nb); 00658 } 00659 00660 /// Copy assignment operator. 00661 dynamic_bitset& operator=(const dynamic_bitset&) = default; 00662 00663 /// Move assignment operator. 00664 dynamic_bitset& 00665 operator=(dynamic_bitset&& __b) 00666 noexcept(std::is_nothrow_move_assignable<_Base>::value) 00667 { 00668 static_cast<_Base&>(*this) = static_cast<_Base&&>(__b); 00669 _M_Nb = __b._M_Nb; 00670 if _GLIBCXX17_CONSTEXPR (std::is_nothrow_move_assignable<_Base>::value) 00671 __b._M_Nb = 0; 00672 else if (get_allocator() == __b.get_allocator()) 00673 __b._M_Nb = 0; 00674 return *this; 00675 } 00676 00677 /** 00678 * @brief Return the allocator for the bitset. 00679 */ 00680 allocator_type 00681 get_allocator() const noexcept 00682 { return this->_M_get_allocator(); } 00683 00684 /** 00685 * @brief Resize the bitset. 00686 */ 00687 void 00688 resize(size_type __nbits, bool __value = false) 00689 { 00690 if (__value) 00691 this->_M_do_fill(); 00692 this->_M_resize(__nbits, __value); 00693 this->_M_Nb = __nbits; 00694 this->_M_do_sanitize(); 00695 } 00696 00697 /** 00698 * @brief Clear the bitset. 00699 */ 00700 void 00701 clear() 00702 { 00703 this->_M_clear(); 00704 this->_M_Nb = 0; 00705 } 00706 00707 /** 00708 * @brief Push a bit onto the high end of the bitset. 00709 */ 00710 void 00711 push_back(bool __bit) 00712 { 00713 if (this->size() % bits_per_block == 0) 00714 this->_M_do_append_block(block_type(__bit), this->_M_Nb); 00715 else 00716 this->_M_unchecked_set(this->_M_Nb, __bit); 00717 ++this->_M_Nb; 00718 } 00719 00720 // XXX why is there no pop_back() member in the proposal? 00721 00722 /** 00723 * @brief Append a block. 00724 */ 00725 void 00726 append(block_type __block) 00727 { 00728 this->_M_do_append_block(__block, this->_M_Nb); 00729 this->_M_Nb += bits_per_block; 00730 } 00731 00732 /** 00733 * @brief 00734 */ 00735 void 00736 append(initializer_list<block_type> __il) 00737 { this->append(__il.begin(), __il.end()); } 00738 00739 /** 00740 * @brief Append an iterator range of blocks. 00741 */ 00742 template <typename _BlockInputIterator> 00743 void 00744 append(_BlockInputIterator __first, _BlockInputIterator __last) 00745 { 00746 for (; __first != __last; ++__first) 00747 this->append(*__first); 00748 } 00749 00750 // 23.3.5.2 dynamic_bitset operations: 00751 //@{ 00752 /** 00753 * @brief Operations on dynamic_bitsets. 00754 * @param __rhs A same-sized dynamic_bitset. 00755 * 00756 * These should be self-explanatory. 00757 */ 00758 dynamic_bitset& 00759 operator&=(const dynamic_bitset& __rhs) 00760 { 00761 this->_M_do_and(__rhs); 00762 return *this; 00763 } 00764 00765 dynamic_bitset& 00766 operator&=(dynamic_bitset&& __rhs) 00767 { 00768 this->_M_do_and(std::move(__rhs)); 00769 return *this; 00770 } 00771 00772 dynamic_bitset& 00773 operator|=(const dynamic_bitset& __rhs) 00774 { 00775 this->_M_do_or(__rhs); 00776 return *this; 00777 } 00778 00779 dynamic_bitset& 00780 operator^=(const dynamic_bitset& __rhs) 00781 { 00782 this->_M_do_xor(__rhs); 00783 return *this; 00784 } 00785 00786 dynamic_bitset& 00787 operator-=(const dynamic_bitset& __rhs) 00788 { 00789 this->_M_do_dif(__rhs); 00790 return *this; 00791 } 00792 //@} 00793 00794 //@{ 00795 /** 00796 * @brief Operations on dynamic_bitsets. 00797 * @param __pos The number of places to shift. 00798 * 00799 * These should be self-explanatory. 00800 */ 00801 dynamic_bitset& 00802 operator<<=(size_type __pos) 00803 { 00804 if (__builtin_expect(__pos < this->_M_Nb, 1)) 00805 { 00806 this->_M_do_left_shift(__pos); 00807 this->_M_do_sanitize(); 00808 } 00809 else 00810 this->_M_do_reset(); 00811 return *this; 00812 } 00813 00814 dynamic_bitset& 00815 operator>>=(size_type __pos) 00816 { 00817 if (__builtin_expect(__pos < this->_M_Nb, 1)) 00818 { 00819 this->_M_do_right_shift(__pos); 00820 this->_M_do_sanitize(); 00821 } 00822 else 00823 this->_M_do_reset(); 00824 return *this; 00825 } 00826 //@} 00827 00828 // Set, reset, and flip. 00829 /** 00830 * @brief Sets every bit to true. 00831 */ 00832 dynamic_bitset& 00833 set() 00834 { 00835 this->_M_do_set(); 00836 this->_M_do_sanitize(); 00837 return *this; 00838 } 00839 00840 /** 00841 * @brief Sets a given bit to a particular value. 00842 * @param __pos The index of the bit. 00843 * @param __val Either true or false, defaults to true. 00844 * @throw std::out_of_range If @a __pos is bigger the size of the %set. 00845 */ 00846 dynamic_bitset& 00847 set(size_type __pos, bool __val = true) 00848 { 00849 if (__pos >= _M_Nb) 00850 __throw_out_of_range(__N("dynamic_bitset::set")); 00851 return this->_M_unchecked_set(__pos, __val); 00852 } 00853 00854 /** 00855 * @brief Sets every bit to false. 00856 */ 00857 dynamic_bitset& 00858 reset() 00859 { 00860 this->_M_do_reset(); 00861 return *this; 00862 } 00863 00864 /** 00865 * @brief Sets a given bit to false. 00866 * @param __pos The index of the bit. 00867 * @throw std::out_of_range If @a __pos is bigger the size of the %set. 00868 * 00869 * Same as writing @c set(__pos, false). 00870 */ 00871 dynamic_bitset& 00872 reset(size_type __pos) 00873 { 00874 if (__pos >= _M_Nb) 00875 __throw_out_of_range(__N("dynamic_bitset::reset")); 00876 return this->_M_unchecked_reset(__pos); 00877 } 00878 00879 /** 00880 * @brief Toggles every bit to its opposite value. 00881 */ 00882 dynamic_bitset& 00883 flip() 00884 { 00885 this->_M_do_flip(); 00886 this->_M_do_sanitize(); 00887 return *this; 00888 } 00889 00890 /** 00891 * @brief Toggles a given bit to its opposite value. 00892 * @param __pos The index of the bit. 00893 * @throw std::out_of_range If @a __pos is bigger the size of the %set. 00894 */ 00895 dynamic_bitset& 00896 flip(size_type __pos) 00897 { 00898 if (__pos >= _M_Nb) 00899 __throw_out_of_range(__N("dynamic_bitset::flip")); 00900 return this->_M_unchecked_flip(__pos); 00901 } 00902 00903 /// See the no-argument flip(). 00904 dynamic_bitset 00905 operator~() const 00906 { return dynamic_bitset<_WordT, _Alloc>(*this).flip(); } 00907 00908 //@{ 00909 /** 00910 * @brief Array-indexing support. 00911 * @param __pos Index into the %dynamic_bitset. 00912 * @return A bool for a 'const %dynamic_bitset'. For non-const 00913 * bitsets, an instance of the reference proxy class. 00914 * @note These operators do no range checking and throw no 00915 * exceptions, as required by DR 11 to the standard. 00916 */ 00917 reference 00918 operator[](size_type __pos) 00919 { return reference(*this,__pos); } 00920 00921 const_reference 00922 operator[](size_type __pos) const 00923 { return _M_unchecked_test(__pos); } 00924 //@} 00925 00926 /** 00927 * @brief Returns a numerical interpretation of the %dynamic_bitset. 00928 * @return The integral equivalent of the bits. 00929 * @throw std::overflow_error If there are too many bits to be 00930 * represented in an @c unsigned @c long. 00931 */ 00932 unsigned long 00933 to_ulong() const 00934 { return this->_M_do_to_ulong(); } 00935 00936 /** 00937 * @brief Returns a numerical interpretation of the %dynamic_bitset. 00938 * @return The integral equivalent of the bits. 00939 * @throw std::overflow_error If there are too many bits to be 00940 * represented in an @c unsigned @c long. 00941 */ 00942 unsigned long long 00943 to_ullong() const 00944 { return this->_M_do_to_ullong(); } 00945 00946 /** 00947 * @brief Returns a character interpretation of the %dynamic_bitset. 00948 * @return The string equivalent of the bits. 00949 * 00950 * Note the ordering of the bits: decreasing character positions 00951 * correspond to increasing bit positions (see the main class notes for 00952 * an example). 00953 */ 00954 template<typename _CharT = char, 00955 typename _Traits = std::char_traits<_CharT>, 00956 typename _Alloc1 = std::allocator<_CharT>> 00957 std::basic_string<_CharT, _Traits, _Alloc1> 00958 to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const 00959 { 00960 std::basic_string<_CharT, _Traits, _Alloc1> __result; 00961 _M_copy_to_string(__result, __zero, __one); 00962 return __result; 00963 } 00964 00965 // Helper functions for string operations. 00966 template<typename _Traits = std::char_traits<char>, 00967 typename _CharT = typename _Traits::char_type> 00968 void 00969 _M_copy_from_ptr(const _CharT*, size_t, size_t, size_t, 00970 _CharT __zero = _CharT('0'), 00971 _CharT __one = _CharT('1')); 00972 00973 template<typename _CharT, typename _Traits, typename _Alloc1> 00974 void 00975 _M_copy_from_string(const basic_string<_CharT, _Traits, _Alloc1>& __str, 00976 size_t __pos, size_t __n, 00977 _CharT __zero = _CharT('0'), 00978 _CharT __one = _CharT('1')) 00979 { 00980 _M_copy_from_ptr<_Traits>(__str.data(), __str.size(), __pos, __n, 00981 __zero, __one); 00982 } 00983 00984 template<typename _CharT, typename _Traits, typename _Alloc1> 00985 void 00986 _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str, 00987 _CharT __zero = _CharT('0'), 00988 _CharT __one = _CharT('1')) const; 00989 00990 /// Returns the number of bits which are set. 00991 size_type 00992 count() const noexcept 00993 { return this->_M_do_count(); } 00994 00995 /// Returns the total number of bits. 00996 size_type 00997 size() const noexcept 00998 { return this->_M_Nb; } 00999 01000 /// Returns the total number of blocks. 01001 size_type 01002 num_blocks() const noexcept 01003 { return this->_M_size(); } 01004 01005 /// Returns true if the dynamic_bitset is empty. 01006 _GLIBCXX_NODISCARD bool 01007 empty() const noexcept 01008 { return (this->_M_Nb == 0); } 01009 01010 /// Returns the maximum size of a dynamic_bitset object having the same 01011 /// type as *this. 01012 /// The real answer is max() * bits_per_block but is likely to overflow. 01013 constexpr size_type 01014 max_size() noexcept 01015 { return std::numeric_limits<block_type>::max(); } 01016 01017 /** 01018 * @brief Tests the value of a bit. 01019 * @param __pos The index of a bit. 01020 * @return The value at @a __pos. 01021 * @throw std::out_of_range If @a __pos is bigger the size of the %set. 01022 */ 01023 bool 01024 test(size_type __pos) const 01025 { 01026 if (__pos >= _M_Nb) 01027 __throw_out_of_range(__N("dynamic_bitset::test")); 01028 return _M_unchecked_test(__pos); 01029 } 01030 01031 /** 01032 * @brief Tests whether all the bits are on. 01033 * @return True if all the bits are set. 01034 */ 01035 bool 01036 all() const 01037 { return this->_M_are_all_aux() == _M_Nb; } 01038 01039 /** 01040 * @brief Tests whether any of the bits are on. 01041 * @return True if at least one bit is set. 01042 */ 01043 bool 01044 any() const 01045 { return this->_M_is_any(); } 01046 01047 /** 01048 * @brief Tests whether any of the bits are on. 01049 * @return True if none of the bits are set. 01050 */ 01051 bool 01052 none() const 01053 { return !this->_M_is_any(); } 01054 01055 //@{ 01056 /// Self-explanatory. 01057 dynamic_bitset 01058 operator<<(size_type __pos) const 01059 { return dynamic_bitset(*this) <<= __pos; } 01060 01061 dynamic_bitset 01062 operator>>(size_type __pos) const 01063 { return dynamic_bitset(*this) >>= __pos; } 01064 //@} 01065 01066 /** 01067 * @brief Finds the index of the first "on" bit. 01068 * @return The index of the first bit set, or size() if not found. 01069 * @sa find_next 01070 */ 01071 size_type 01072 find_first() const 01073 { return this->_M_do_find_first(this->_M_Nb); } 01074 01075 /** 01076 * @brief Finds the index of the next "on" bit after prev. 01077 * @return The index of the next bit set, or size() if not found. 01078 * @param __prev Where to start searching. 01079 * @sa find_first 01080 */ 01081 size_type 01082 find_next(size_t __prev) const 01083 { return this->_M_do_find_next(__prev, this->_M_Nb); } 01084 01085 bool 01086 is_subset_of(const dynamic_bitset& __b) const 01087 { return this->_M_is_subset_of(__b); } 01088 01089 bool 01090 is_proper_subset_of(const dynamic_bitset& __b) const 01091 { return this->_M_is_proper_subset_of(__b); } 01092 01093 friend bool 01094 operator==(const dynamic_bitset& __lhs, 01095 const dynamic_bitset& __rhs) noexcept 01096 { return __lhs._M_Nb == __rhs._M_Nb && __lhs._M_is_equal(__rhs); } 01097 01098 friend bool 01099 operator<(const dynamic_bitset& __lhs, 01100 const dynamic_bitset& __rhs) noexcept 01101 { return __lhs._M_is_less(__rhs) || __lhs._M_Nb < __rhs._M_Nb; } 01102 }; 01103 01104 template<typename _WordT, typename _Alloc> 01105 template<typename _CharT, typename _Traits, typename _Alloc1> 01106 inline void 01107 dynamic_bitset<_WordT, _Alloc>:: 01108 _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str, 01109 _CharT __zero, _CharT __one) const 01110 { 01111 __str.assign(_M_Nb, __zero); 01112 for (size_t __i = _M_Nb; __i > 0; --__i) 01113 if (_M_unchecked_test(__i - 1)) 01114 _Traits::assign(__str[_M_Nb - __i], __one); 01115 } 01116 01117 01118 //@{ 01119 /// These comparisons for equality/inequality are, well, @e bitwise. 01120 01121 template<typename _WordT, typename _Alloc> 01122 inline bool 01123 operator!=(const dynamic_bitset<_WordT, _Alloc>& __lhs, 01124 const dynamic_bitset<_WordT, _Alloc>& __rhs) 01125 { return !(__lhs == __rhs); } 01126 01127 template<typename _WordT, typename _Alloc> 01128 inline bool 01129 operator<=(const dynamic_bitset<_WordT, _Alloc>& __lhs, 01130 const dynamic_bitset<_WordT, _Alloc>& __rhs) 01131 { return !(__lhs > __rhs); } 01132 01133 template<typename _WordT, typename _Alloc> 01134 inline bool 01135 operator>(const dynamic_bitset<_WordT, _Alloc>& __lhs, 01136 const dynamic_bitset<_WordT, _Alloc>& __rhs) 01137 { return __rhs < __lhs; } 01138 01139 template<typename _WordT, typename _Alloc> 01140 inline bool 01141 operator>=(const dynamic_bitset<_WordT, _Alloc>& __lhs, 01142 const dynamic_bitset<_WordT, _Alloc>& __rhs) 01143 { return !(__lhs < __rhs); } 01144 //@} 01145 01146 // 23.3.5.3 bitset operations: 01147 //@{ 01148 /** 01149 * @brief Global bitwise operations on bitsets. 01150 * @param __x A bitset. 01151 * @param __y A bitset of the same size as @a __x. 01152 * @return A new bitset. 01153 * 01154 * These should be self-explanatory. 01155 */ 01156 template<typename _WordT, typename _Alloc> 01157 inline dynamic_bitset<_WordT, _Alloc> 01158 operator&(const dynamic_bitset<_WordT, _Alloc>& __x, 01159 const dynamic_bitset<_WordT, _Alloc>& __y) 01160 { 01161 dynamic_bitset<_WordT, _Alloc> __result(__x); 01162 __result &= __y; 01163 return __result; 01164 } 01165 01166 template<typename _WordT, typename _Alloc> 01167 inline dynamic_bitset<_WordT, _Alloc> 01168 operator|(const dynamic_bitset<_WordT, _Alloc>& __x, 01169 const dynamic_bitset<_WordT, _Alloc>& __y) 01170 { 01171 dynamic_bitset<_WordT, _Alloc> __result(__x); 01172 __result |= __y; 01173 return __result; 01174 } 01175 01176 template <typename _WordT, typename _Alloc> 01177 inline dynamic_bitset<_WordT, _Alloc> 01178 operator^(const dynamic_bitset<_WordT, _Alloc>& __x, 01179 const dynamic_bitset<_WordT, _Alloc>& __y) 01180 { 01181 dynamic_bitset<_WordT, _Alloc> __result(__x); 01182 __result ^= __y; 01183 return __result; 01184 } 01185 01186 template <typename _WordT, typename _Alloc> 01187 inline dynamic_bitset<_WordT, _Alloc> 01188 operator-(const dynamic_bitset<_WordT, _Alloc>& __x, 01189 const dynamic_bitset<_WordT, _Alloc>& __y) 01190 { 01191 dynamic_bitset<_WordT, _Alloc> __result(__x); 01192 __result -= __y; 01193 return __result; 01194 } 01195 //@} 01196 01197 /// Stream output operator for dynamic_bitset. 01198 template <typename _CharT, typename _Traits, 01199 typename _WordT, typename _Alloc> 01200 inline std::basic_ostream<_CharT, _Traits>& 01201 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01202 const dynamic_bitset<_WordT, _Alloc>& __x) 01203 { 01204 std::basic_string<_CharT, _Traits> __tmp; 01205 01206 const ctype<_CharT>& __ct = use_facet<ctype<_CharT>>(__os.getloc()); 01207 __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1')); 01208 return __os << __tmp; 01209 } 01210 /** 01211 * @} 01212 */ 01213 } // tr2 01214 01215 _GLIBCXX_END_NAMESPACE_VERSION 01216 } // std 01217 01218 #include <tr2/dynamic_bitset.tcc> 01219 01220 #endif /* _GLIBCXX_TR2_DYNAMIC_BITSET */