1*38fd1498Szrj// TR2 <dynamic_bitset> -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj// Copyright (C) 2009-2018 Free Software Foundation, Inc. 4*38fd1498Szrj// 5*38fd1498Szrj// This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj// software; you can redistribute it and/or modify it under the 7*38fd1498Szrj// terms of the GNU General Public License as published by the 8*38fd1498Szrj// Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj// any later version. 10*38fd1498Szrj 11*38fd1498Szrj// This library is distributed in the hope that it will be useful, 12*38fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj// GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj// permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj// 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj// You should have received a copy of the GNU General Public License and 21*38fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj// <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj/** @file tr2/dynamic_bitset 26*38fd1498Szrj * This is a TR2 C++ Library header. 27*38fd1498Szrj */ 28*38fd1498Szrj 29*38fd1498Szrj#ifndef _GLIBCXX_TR2_DYNAMIC_BITSET 30*38fd1498Szrj#define _GLIBCXX_TR2_DYNAMIC_BITSET 1 31*38fd1498Szrj 32*38fd1498Szrj#pragma GCC system_header 33*38fd1498Szrj 34*38fd1498Szrj#include <limits> 35*38fd1498Szrj#include <vector> 36*38fd1498Szrj#include <string> 37*38fd1498Szrj#include <memory> // For std::allocator 38*38fd1498Szrj#include <bits/functexcept.h> // For invalid_argument, out_of_range, 39*38fd1498Szrj // overflow_error 40*38fd1498Szrj#include <iosfwd> 41*38fd1498Szrj#include <bits/cxxabi_forced.h> 42*38fd1498Szrj 43*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default) 44*38fd1498Szrj{ 45*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION 46*38fd1498Szrj 47*38fd1498Szrjnamespace tr2 48*38fd1498Szrj{ 49*38fd1498Szrj /** 50*38fd1498Szrj * @defgroup dynamic_bitset Dynamic Bitset. 51*38fd1498Szrj * @ingroup extensions 52*38fd1498Szrj * 53*38fd1498Szrj * @{ 54*38fd1498Szrj */ 55*38fd1498Szrj 56*38fd1498Szrj /** 57*38fd1498Szrj * Base class, general case. 58*38fd1498Szrj * 59*38fd1498Szrj * See documentation for dynamic_bitset. 60*38fd1498Szrj */ 61*38fd1498Szrj template<typename _WordT = unsigned long long, 62*38fd1498Szrj typename _Alloc = std::allocator<_WordT>> 63*38fd1498Szrj struct __dynamic_bitset_base 64*38fd1498Szrj { 65*38fd1498Szrj static_assert(std::is_unsigned<_WordT>::value, "template argument " 66*38fd1498Szrj "_WordT not an unsigned integral type"); 67*38fd1498Szrj 68*38fd1498Szrj typedef _WordT block_type; 69*38fd1498Szrj typedef _Alloc allocator_type; 70*38fd1498Szrj typedef size_t size_type; 71*38fd1498Szrj 72*38fd1498Szrj static const size_type _S_bits_per_block = __CHAR_BIT__ * sizeof(block_type); 73*38fd1498Szrj static const size_type npos = static_cast<size_type>(-1); 74*38fd1498Szrj 75*38fd1498Szrj /// 0 is the least significant word. 76*38fd1498Szrj std::vector<block_type, allocator_type> _M_w; 77*38fd1498Szrj 78*38fd1498Szrj explicit 79*38fd1498Szrj __dynamic_bitset_base(const allocator_type& __alloc = allocator_type()) 80*38fd1498Szrj : _M_w(__alloc) 81*38fd1498Szrj { } 82*38fd1498Szrj 83*38fd1498Szrj explicit 84*38fd1498Szrj __dynamic_bitset_base(__dynamic_bitset_base&& __b) 85*38fd1498Szrj { this->_M_w.swap(__b._M_w); } 86*38fd1498Szrj 87*38fd1498Szrj explicit 88*38fd1498Szrj __dynamic_bitset_base(size_type __nbits, unsigned long long __val = 0ULL, 89*38fd1498Szrj const allocator_type& __alloc = allocator_type()) 90*38fd1498Szrj : _M_w(__nbits / _S_bits_per_block 91*38fd1498Szrj + (__nbits % _S_bits_per_block > 0), 92*38fd1498Szrj __val, __alloc) 93*38fd1498Szrj { 94*38fd1498Szrj unsigned long long __mask = ~static_cast<block_type>(0); 95*38fd1498Szrj size_t __n = std::min(this->_M_w.size(), 96*38fd1498Szrj sizeof(unsigned long long) / sizeof(block_type)); 97*38fd1498Szrj for (size_t __i = 0; __i < __n; ++__i) 98*38fd1498Szrj { 99*38fd1498Szrj this->_M_w[__i] = (__val & __mask) >> (__i * _S_bits_per_block); 100*38fd1498Szrj __mask <<= _S_bits_per_block; 101*38fd1498Szrj } 102*38fd1498Szrj } 103*38fd1498Szrj 104*38fd1498Szrj void 105*38fd1498Szrj _M_assign(const __dynamic_bitset_base& __b) 106*38fd1498Szrj { this->_M_w = __b._M_w; } 107*38fd1498Szrj 108*38fd1498Szrj void 109*38fd1498Szrj _M_swap(__dynamic_bitset_base& __b) 110*38fd1498Szrj { this->_M_w.swap(__b._M_w); } 111*38fd1498Szrj 112*38fd1498Szrj void 113*38fd1498Szrj _M_clear() 114*38fd1498Szrj { this->_M_w.clear(); } 115*38fd1498Szrj 116*38fd1498Szrj void 117*38fd1498Szrj _M_resize(size_t __nbits, bool __value) 118*38fd1498Szrj { 119*38fd1498Szrj size_t __sz = __nbits / _S_bits_per_block; 120*38fd1498Szrj if (__nbits % _S_bits_per_block > 0) 121*38fd1498Szrj ++__sz; 122*38fd1498Szrj if (__sz != this->_M_w.size()) 123*38fd1498Szrj { 124*38fd1498Szrj block_type __val = 0; 125*38fd1498Szrj if (__value) 126*38fd1498Szrj __val = std::numeric_limits<block_type>::max(); 127*38fd1498Szrj this->_M_w.resize(__sz, __val); 128*38fd1498Szrj } 129*38fd1498Szrj } 130*38fd1498Szrj 131*38fd1498Szrj allocator_type 132*38fd1498Szrj _M_get_allocator() const 133*38fd1498Szrj { return this->_M_w.get_allocator(); } 134*38fd1498Szrj 135*38fd1498Szrj static size_type 136*38fd1498Szrj _S_whichword(size_type __pos) noexcept 137*38fd1498Szrj { return __pos / _S_bits_per_block; } 138*38fd1498Szrj 139*38fd1498Szrj static size_type 140*38fd1498Szrj _S_whichbyte(size_type __pos) noexcept 141*38fd1498Szrj { return (__pos % _S_bits_per_block) / __CHAR_BIT__; } 142*38fd1498Szrj 143*38fd1498Szrj static size_type 144*38fd1498Szrj _S_whichbit(size_type __pos) noexcept 145*38fd1498Szrj { return __pos % _S_bits_per_block; } 146*38fd1498Szrj 147*38fd1498Szrj static block_type 148*38fd1498Szrj _S_maskbit(size_type __pos) noexcept 149*38fd1498Szrj { return (static_cast<block_type>(1)) << _S_whichbit(__pos); } 150*38fd1498Szrj 151*38fd1498Szrj block_type& 152*38fd1498Szrj _M_getword(size_type __pos) 153*38fd1498Szrj { return this->_M_w[_S_whichword(__pos)]; } 154*38fd1498Szrj 155*38fd1498Szrj block_type 156*38fd1498Szrj _M_getword(size_type __pos) const 157*38fd1498Szrj { return this->_M_w[_S_whichword(__pos)]; } 158*38fd1498Szrj 159*38fd1498Szrj block_type& 160*38fd1498Szrj _M_hiword() 161*38fd1498Szrj { return this->_M_w[_M_w.size() - 1]; } 162*38fd1498Szrj 163*38fd1498Szrj block_type 164*38fd1498Szrj _M_hiword() const 165*38fd1498Szrj { return this->_M_w[_M_w.size() - 1]; } 166*38fd1498Szrj 167*38fd1498Szrj void 168*38fd1498Szrj _M_do_and(const __dynamic_bitset_base& __x) 169*38fd1498Szrj { 170*38fd1498Szrj if (__x._M_w.size() == this->_M_w.size()) 171*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 172*38fd1498Szrj this->_M_w[__i] &= __x._M_w[__i]; 173*38fd1498Szrj else 174*38fd1498Szrj return; 175*38fd1498Szrj } 176*38fd1498Szrj 177*38fd1498Szrj void 178*38fd1498Szrj _M_do_or(const __dynamic_bitset_base& __x) 179*38fd1498Szrj { 180*38fd1498Szrj if (__x._M_w.size() == this->_M_w.size()) 181*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 182*38fd1498Szrj this->_M_w[__i] |= __x._M_w[__i]; 183*38fd1498Szrj else 184*38fd1498Szrj return; 185*38fd1498Szrj } 186*38fd1498Szrj 187*38fd1498Szrj void 188*38fd1498Szrj _M_do_xor(const __dynamic_bitset_base& __x) 189*38fd1498Szrj { 190*38fd1498Szrj if (__x._M_w.size() == this->_M_w.size()) 191*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 192*38fd1498Szrj this->_M_w[__i] ^= __x._M_w[__i]; 193*38fd1498Szrj else 194*38fd1498Szrj return; 195*38fd1498Szrj } 196*38fd1498Szrj 197*38fd1498Szrj void 198*38fd1498Szrj _M_do_dif(const __dynamic_bitset_base& __x) 199*38fd1498Szrj { 200*38fd1498Szrj if (__x._M_w.size() == this->_M_w.size()) 201*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 202*38fd1498Szrj this->_M_w[__i] &= ~__x._M_w[__i]; 203*38fd1498Szrj else 204*38fd1498Szrj return; 205*38fd1498Szrj } 206*38fd1498Szrj 207*38fd1498Szrj void 208*38fd1498Szrj _M_do_left_shift(size_t __shift); 209*38fd1498Szrj 210*38fd1498Szrj void 211*38fd1498Szrj _M_do_right_shift(size_t __shift); 212*38fd1498Szrj 213*38fd1498Szrj void 214*38fd1498Szrj _M_do_flip() 215*38fd1498Szrj { 216*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 217*38fd1498Szrj this->_M_w[__i] = ~this->_M_w[__i]; 218*38fd1498Szrj } 219*38fd1498Szrj 220*38fd1498Szrj void 221*38fd1498Szrj _M_do_set() 222*38fd1498Szrj { 223*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 224*38fd1498Szrj this->_M_w[__i] = ~static_cast<block_type>(0); 225*38fd1498Szrj } 226*38fd1498Szrj 227*38fd1498Szrj void 228*38fd1498Szrj _M_do_reset() 229*38fd1498Szrj { 230*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 231*38fd1498Szrj this->_M_w[__i] = static_cast<block_type>(0); 232*38fd1498Szrj } 233*38fd1498Szrj 234*38fd1498Szrj bool 235*38fd1498Szrj _M_is_equal(const __dynamic_bitset_base& __x) const 236*38fd1498Szrj { 237*38fd1498Szrj if (__x._M_w.size() == this->_M_w.size()) 238*38fd1498Szrj { 239*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 240*38fd1498Szrj if (this->_M_w[__i] != __x._M_w[__i]) 241*38fd1498Szrj return false; 242*38fd1498Szrj return true; 243*38fd1498Szrj } 244*38fd1498Szrj else 245*38fd1498Szrj return false; 246*38fd1498Szrj } 247*38fd1498Szrj 248*38fd1498Szrj bool 249*38fd1498Szrj _M_is_less(const __dynamic_bitset_base& __x) const 250*38fd1498Szrj { 251*38fd1498Szrj if (__x._M_w.size() == this->_M_w.size()) 252*38fd1498Szrj { 253*38fd1498Szrj for (size_t __i = this->_M_w.size(); __i > 0; --__i) 254*38fd1498Szrj { 255*38fd1498Szrj if (this->_M_w[__i-1] < __x._M_w[__i-1]) 256*38fd1498Szrj return true; 257*38fd1498Szrj else if (this->_M_w[__i-1] > __x._M_w[__i-1]) 258*38fd1498Szrj return false; 259*38fd1498Szrj } 260*38fd1498Szrj return false; 261*38fd1498Szrj } 262*38fd1498Szrj else 263*38fd1498Szrj return false; 264*38fd1498Szrj } 265*38fd1498Szrj 266*38fd1498Szrj size_t 267*38fd1498Szrj _M_are_all_aux() const 268*38fd1498Szrj { 269*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size() - 1; ++__i) 270*38fd1498Szrj if (_M_w[__i] != ~static_cast<block_type>(0)) 271*38fd1498Szrj return 0; 272*38fd1498Szrj return ((this->_M_w.size() - 1) * _S_bits_per_block 273*38fd1498Szrj + __builtin_popcountll(this->_M_hiword())); 274*38fd1498Szrj } 275*38fd1498Szrj 276*38fd1498Szrj bool 277*38fd1498Szrj _M_is_any() const 278*38fd1498Szrj { 279*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 280*38fd1498Szrj if (this->_M_w[__i] != static_cast<block_type>(0)) 281*38fd1498Szrj return true; 282*38fd1498Szrj return false; 283*38fd1498Szrj } 284*38fd1498Szrj 285*38fd1498Szrj bool 286*38fd1498Szrj _M_is_subset_of(const __dynamic_bitset_base& __b) 287*38fd1498Szrj { 288*38fd1498Szrj if (__b._M_w.size() == this->_M_w.size()) 289*38fd1498Szrj { 290*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 291*38fd1498Szrj if (this->_M_w[__i] != (this->_M_w[__i] | __b._M_w[__i])) 292*38fd1498Szrj return false; 293*38fd1498Szrj return true; 294*38fd1498Szrj } 295*38fd1498Szrj else 296*38fd1498Szrj return false; 297*38fd1498Szrj } 298*38fd1498Szrj 299*38fd1498Szrj bool 300*38fd1498Szrj _M_is_proper_subset_of(const __dynamic_bitset_base& __b) const 301*38fd1498Szrj { 302*38fd1498Szrj if (this->is_subset_of(__b)) 303*38fd1498Szrj { 304*38fd1498Szrj if (*this == __b) 305*38fd1498Szrj return false; 306*38fd1498Szrj else 307*38fd1498Szrj return true; 308*38fd1498Szrj } 309*38fd1498Szrj else 310*38fd1498Szrj return false; 311*38fd1498Szrj } 312*38fd1498Szrj 313*38fd1498Szrj size_t 314*38fd1498Szrj _M_do_count() const 315*38fd1498Szrj { 316*38fd1498Szrj size_t __result = 0; 317*38fd1498Szrj for (size_t __i = 0; __i < this->_M_w.size(); ++__i) 318*38fd1498Szrj __result += __builtin_popcountll(this->_M_w[__i]); 319*38fd1498Szrj return __result; 320*38fd1498Szrj } 321*38fd1498Szrj 322*38fd1498Szrj size_type 323*38fd1498Szrj _M_size() const noexcept 324*38fd1498Szrj { return this->_M_w.size(); } 325*38fd1498Szrj 326*38fd1498Szrj unsigned long 327*38fd1498Szrj _M_do_to_ulong() const; 328*38fd1498Szrj 329*38fd1498Szrj unsigned long long 330*38fd1498Szrj _M_do_to_ullong() const; 331*38fd1498Szrj 332*38fd1498Szrj // find first "on" bit 333*38fd1498Szrj size_type 334*38fd1498Szrj _M_do_find_first(size_t __not_found) const; 335*38fd1498Szrj 336*38fd1498Szrj // find the next "on" bit that follows "prev" 337*38fd1498Szrj size_type 338*38fd1498Szrj _M_do_find_next(size_t __prev, size_t __not_found) const; 339*38fd1498Szrj 340*38fd1498Szrj // do append of block 341*38fd1498Szrj void 342*38fd1498Szrj _M_do_append_block(block_type __block, size_type __pos) 343*38fd1498Szrj { 344*38fd1498Szrj size_t __offset = __pos % _S_bits_per_block; 345*38fd1498Szrj if (__offset == 0) 346*38fd1498Szrj this->_M_w.push_back(__block); 347*38fd1498Szrj else 348*38fd1498Szrj { 349*38fd1498Szrj this->_M_hiword() |= (__block << __offset); 350*38fd1498Szrj this->_M_w.push_back(__block >> (_S_bits_per_block - __offset)); 351*38fd1498Szrj } 352*38fd1498Szrj } 353*38fd1498Szrj }; 354*38fd1498Szrj 355*38fd1498Szrj /** 356*38fd1498Szrj * @brief The %dynamic_bitset class represents a sequence of bits. 357*38fd1498Szrj * 358*38fd1498Szrj * See N2050, 359*38fd1498Szrj * Proposal to Add a Dynamically Sizeable Bitset to the Standard Library. 360*38fd1498Szrj * 361*38fd1498Szrj * In the general unoptimized case, storage is allocated in 362*38fd1498Szrj * word-sized blocks. Let B be the number of bits in a word, then 363*38fd1498Szrj * (Nb+(B-1))/B words will be used for storage. B - Nb%B bits are 364*38fd1498Szrj * unused. (They are the high-order bits in the highest word.) It 365*38fd1498Szrj * is a class invariant that those unused bits are always zero. 366*38fd1498Szrj * 367*38fd1498Szrj * If you think of %dynamic_bitset as "a simple array of bits," be 368*38fd1498Szrj * aware that your mental picture is reversed: a %dynamic_bitset 369*38fd1498Szrj * behaves the same way as bits in integers do, with the bit at 370*38fd1498Szrj * index 0 in the "least significant / right-hand" position, and 371*38fd1498Szrj * the bit at index Nb-1 in the "most significant / left-hand" 372*38fd1498Szrj * position. Thus, unlike other containers, a %dynamic_bitset's 373*38fd1498Szrj * index "counts from right to left," to put it very loosely. 374*38fd1498Szrj * 375*38fd1498Szrj * This behavior is preserved when translating to and from strings. 376*38fd1498Szrj * For example, the first line of the following program probably 377*38fd1498Szrj * prints "b('a') is 0001100001" on a modern ASCII system. 378*38fd1498Szrj * 379*38fd1498Szrj * @code 380*38fd1498Szrj * #include <dynamic_bitset> 381*38fd1498Szrj * #include <iostream> 382*38fd1498Szrj * #include <sstream> 383*38fd1498Szrj * 384*38fd1498Szrj * using namespace std; 385*38fd1498Szrj * 386*38fd1498Szrj * int main() 387*38fd1498Szrj * { 388*38fd1498Szrj * long a = 'a'; 389*38fd1498Szrj * dynamic_bitset<> b(a); 390*38fd1498Szrj * 391*38fd1498Szrj * cout << "b('a') is " << b << endl; 392*38fd1498Szrj * 393*38fd1498Szrj * ostringstream s; 394*38fd1498Szrj * s << b; 395*38fd1498Szrj * string str = s.str(); 396*38fd1498Szrj * cout << "index 3 in the string is " << str[3] << " but\n" 397*38fd1498Szrj * << "index 3 in the bitset is " << b[3] << endl; 398*38fd1498Szrj * } 399*38fd1498Szrj * @endcode 400*38fd1498Szrj * 401*38fd1498Szrj * Most of the actual code isn't contained in %dynamic_bitset<> 402*38fd1498Szrj * itself, but in the base class __dynamic_bitset_base. The base 403*38fd1498Szrj * class works with whole words, not with individual bits. This 404*38fd1498Szrj * allows us to specialize __dynamic_bitset_base for the important 405*38fd1498Szrj * special case where the %dynamic_bitset is only a single word. 406*38fd1498Szrj * 407*38fd1498Szrj * Extra confusion can result due to the fact that the storage for 408*38fd1498Szrj * __dynamic_bitset_base @e is a vector, and is indexed as such. This is 409*38fd1498Szrj * carefully encapsulated. 410*38fd1498Szrj */ 411*38fd1498Szrj template<typename _WordT = unsigned long long, 412*38fd1498Szrj typename _Alloc = std::allocator<_WordT>> 413*38fd1498Szrj class dynamic_bitset 414*38fd1498Szrj : private __dynamic_bitset_base<_WordT, _Alloc> 415*38fd1498Szrj { 416*38fd1498Szrj static_assert(std::is_unsigned<_WordT>::value, "template argument " 417*38fd1498Szrj "_WordT not an unsigned integral type"); 418*38fd1498Szrj 419*38fd1498Szrj public: 420*38fd1498Szrj 421*38fd1498Szrj typedef __dynamic_bitset_base<_WordT, _Alloc> _Base; 422*38fd1498Szrj typedef _WordT block_type; 423*38fd1498Szrj typedef _Alloc allocator_type; 424*38fd1498Szrj typedef size_t size_type; 425*38fd1498Szrj 426*38fd1498Szrj static const size_type bits_per_block = __CHAR_BIT__ * sizeof(block_type); 427*38fd1498Szrj // Use this: constexpr size_type std::numeric_limits<size_type>::max(). 428*38fd1498Szrj static const size_type npos = static_cast<size_type>(-1); 429*38fd1498Szrj 430*38fd1498Szrj private: 431*38fd1498Szrj 432*38fd1498Szrj // Clear the unused bits in the uppermost word. 433*38fd1498Szrj void 434*38fd1498Szrj _M_do_sanitize() 435*38fd1498Szrj { 436*38fd1498Szrj size_type __shift = this->_M_Nb % bits_per_block; 437*38fd1498Szrj if (__shift > 0) 438*38fd1498Szrj this->_M_hiword() &= ~((~static_cast<block_type>(0)) << __shift); 439*38fd1498Szrj } 440*38fd1498Szrj 441*38fd1498Szrj // Set the unused bits in the uppermost word. 442*38fd1498Szrj void 443*38fd1498Szrj _M_do_fill() 444*38fd1498Szrj { 445*38fd1498Szrj size_type __shift = this->_M_Nb % bits_per_block; 446*38fd1498Szrj if (__shift > 0) 447*38fd1498Szrj this->_M_hiword() |= ((~static_cast<block_type>(0)) << __shift); 448*38fd1498Szrj } 449*38fd1498Szrj 450*38fd1498Szrj /** 451*38fd1498Szrj * These versions of single-bit set, reset, flip, and test 452*38fd1498Szrj * do no range checking. 453*38fd1498Szrj */ 454*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 455*38fd1498Szrj _M_unchecked_set(size_type __pos) 456*38fd1498Szrj { 457*38fd1498Szrj this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); 458*38fd1498Szrj return *this; 459*38fd1498Szrj } 460*38fd1498Szrj 461*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 462*38fd1498Szrj _M_unchecked_set(size_type __pos, int __val) 463*38fd1498Szrj { 464*38fd1498Szrj if (__val) 465*38fd1498Szrj this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); 466*38fd1498Szrj else 467*38fd1498Szrj this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); 468*38fd1498Szrj return *this; 469*38fd1498Szrj } 470*38fd1498Szrj 471*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 472*38fd1498Szrj _M_unchecked_reset(size_type __pos) 473*38fd1498Szrj { 474*38fd1498Szrj this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); 475*38fd1498Szrj return *this; 476*38fd1498Szrj } 477*38fd1498Szrj 478*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 479*38fd1498Szrj _M_unchecked_flip(size_type __pos) 480*38fd1498Szrj { 481*38fd1498Szrj this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); 482*38fd1498Szrj return *this; 483*38fd1498Szrj } 484*38fd1498Szrj 485*38fd1498Szrj bool 486*38fd1498Szrj _M_unchecked_test(size_type __pos) const 487*38fd1498Szrj { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) 488*38fd1498Szrj != static_cast<_WordT>(0)); } 489*38fd1498Szrj 490*38fd1498Szrj size_type _M_Nb; 491*38fd1498Szrj 492*38fd1498Szrj public: 493*38fd1498Szrj /** 494*38fd1498Szrj * This encapsulates the concept of a single bit. An instance 495*38fd1498Szrj * of this class is a proxy for an actual bit; this way the 496*38fd1498Szrj * individual bit operations are done as faster word-size 497*38fd1498Szrj * bitwise instructions. 498*38fd1498Szrj * 499*38fd1498Szrj * Most users will never need to use this class directly; 500*38fd1498Szrj * conversions to and from bool are automatic and should be 501*38fd1498Szrj * transparent. Overloaded operators help to preserve the 502*38fd1498Szrj * illusion. 503*38fd1498Szrj * 504*38fd1498Szrj * (On a typical system, this "bit %reference" is 64 times the 505*38fd1498Szrj * size of an actual bit. Ha.) 506*38fd1498Szrj */ 507*38fd1498Szrj class reference 508*38fd1498Szrj { 509*38fd1498Szrj friend class dynamic_bitset; 510*38fd1498Szrj 511*38fd1498Szrj block_type *_M_wp; 512*38fd1498Szrj size_type _M_bpos; 513*38fd1498Szrj 514*38fd1498Szrj // left undefined 515*38fd1498Szrj reference(); 516*38fd1498Szrj 517*38fd1498Szrj public: 518*38fd1498Szrj reference(dynamic_bitset& __b, size_type __pos) 519*38fd1498Szrj { 520*38fd1498Szrj this->_M_wp = &__b._M_getword(__pos); 521*38fd1498Szrj this->_M_bpos = _Base::_S_whichbit(__pos); 522*38fd1498Szrj } 523*38fd1498Szrj 524*38fd1498Szrj ~reference() 525*38fd1498Szrj { } 526*38fd1498Szrj 527*38fd1498Szrj // For b[i] = __x; 528*38fd1498Szrj reference& 529*38fd1498Szrj operator=(bool __x) 530*38fd1498Szrj { 531*38fd1498Szrj if (__x) 532*38fd1498Szrj *this->_M_wp |= _Base::_S_maskbit(this->_M_bpos); 533*38fd1498Szrj else 534*38fd1498Szrj *this->_M_wp &= ~_Base::_S_maskbit(this->_M_bpos); 535*38fd1498Szrj return *this; 536*38fd1498Szrj } 537*38fd1498Szrj 538*38fd1498Szrj // For b[i] = b[__j]; 539*38fd1498Szrj reference& 540*38fd1498Szrj operator=(const reference& __j) 541*38fd1498Szrj { 542*38fd1498Szrj if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos))) 543*38fd1498Szrj *this->_M_wp |= _Base::_S_maskbit(this->_M_bpos); 544*38fd1498Szrj else 545*38fd1498Szrj *this->_M_wp &= ~_Base::_S_maskbit(this->_M_bpos); 546*38fd1498Szrj return *this; 547*38fd1498Szrj } 548*38fd1498Szrj 549*38fd1498Szrj // Flips the bit 550*38fd1498Szrj bool 551*38fd1498Szrj operator~() const 552*38fd1498Szrj { return (*(_M_wp) & _Base::_S_maskbit(this->_M_bpos)) == 0; } 553*38fd1498Szrj 554*38fd1498Szrj // For __x = b[i]; 555*38fd1498Szrj operator bool() const 556*38fd1498Szrj { return (*(this->_M_wp) & _Base::_S_maskbit(this->_M_bpos)) != 0; } 557*38fd1498Szrj 558*38fd1498Szrj // For b[i].flip(); 559*38fd1498Szrj reference& 560*38fd1498Szrj flip() 561*38fd1498Szrj { 562*38fd1498Szrj *this->_M_wp ^= _Base::_S_maskbit(this->_M_bpos); 563*38fd1498Szrj return *this; 564*38fd1498Szrj } 565*38fd1498Szrj }; 566*38fd1498Szrj 567*38fd1498Szrj friend class reference; 568*38fd1498Szrj 569*38fd1498Szrj typedef bool const_reference; 570*38fd1498Szrj 571*38fd1498Szrj // 23.3.5.1 constructors: 572*38fd1498Szrj /// All bits set to zero. 573*38fd1498Szrj explicit 574*38fd1498Szrj dynamic_bitset(const allocator_type& __alloc = allocator_type()) 575*38fd1498Szrj : _Base(__alloc), _M_Nb(0) 576*38fd1498Szrj { } 577*38fd1498Szrj 578*38fd1498Szrj /// Initial bits bitwise-copied from a single word (others set to zero). 579*38fd1498Szrj explicit 580*38fd1498Szrj dynamic_bitset(size_type __nbits, unsigned long long __val = 0ULL, 581*38fd1498Szrj const allocator_type& __alloc = allocator_type()) 582*38fd1498Szrj : _Base(__nbits, __val, __alloc), 583*38fd1498Szrj _M_Nb(__nbits) 584*38fd1498Szrj { } 585*38fd1498Szrj 586*38fd1498Szrj dynamic_bitset(initializer_list<block_type> __il, 587*38fd1498Szrj const allocator_type& __alloc = allocator_type()) 588*38fd1498Szrj : _Base(__alloc), _M_Nb(0) 589*38fd1498Szrj { this->append(__il); } 590*38fd1498Szrj 591*38fd1498Szrj /** 592*38fd1498Szrj * @brief Use a subset of a string. 593*38fd1498Szrj * @param __str A string of '0' and '1' characters. 594*38fd1498Szrj * @param __pos Index of the first character in @p __str to use. 595*38fd1498Szrj * @param __n The number of characters to copy. 596*38fd1498Szrj * @param __zero The character to use for unset bits. 597*38fd1498Szrj * @param __one The character to use for set bits. 598*38fd1498Szrj * @param __alloc An allocator. 599*38fd1498Szrj * @throw std::out_of_range If @p __pos is bigger the size of @p __str. 600*38fd1498Szrj * @throw std::invalid_argument If a character appears in the string 601*38fd1498Szrj * which is neither '0' nor '1'. 602*38fd1498Szrj */ 603*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc1> 604*38fd1498Szrj explicit 605*38fd1498Szrj dynamic_bitset(const std::basic_string<_CharT, _Traits, _Alloc1>& __str, 606*38fd1498Szrj typename basic_string<_CharT,_Traits,_Alloc1>::size_type 607*38fd1498Szrj __pos = 0, 608*38fd1498Szrj typename basic_string<_CharT,_Traits,_Alloc1>::size_type 609*38fd1498Szrj __n = std::basic_string<_CharT, _Traits, _Alloc1>::npos, 610*38fd1498Szrj _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'), 611*38fd1498Szrj const allocator_type& __alloc = allocator_type()) 612*38fd1498Szrj : _Base(__alloc), 613*38fd1498Szrj _M_Nb(0) // Watch for npos. 614*38fd1498Szrj { 615*38fd1498Szrj if (__pos > __str.size()) 616*38fd1498Szrj __throw_out_of_range(__N("dynamic_bitset::bitset initial position " 617*38fd1498Szrj "not valid")); 618*38fd1498Szrj 619*38fd1498Szrj // Watch for npos. 620*38fd1498Szrj this->_M_Nb = (__n > __str.size() ? __str.size() - __pos : __n); 621*38fd1498Szrj this->resize(this->_M_Nb); 622*38fd1498Szrj this->_M_copy_from_string(__str, __pos, __n, 623*38fd1498Szrj _CharT('0'), _CharT('1')); 624*38fd1498Szrj } 625*38fd1498Szrj 626*38fd1498Szrj /** 627*38fd1498Szrj * @brief Construct from a string. 628*38fd1498Szrj * @param __str A string of '0' and '1' characters. 629*38fd1498Szrj * @param __alloc An allocator. 630*38fd1498Szrj * @throw std::invalid_argument If a character appears in the string 631*38fd1498Szrj * which is neither '0' nor '1'. 632*38fd1498Szrj */ 633*38fd1498Szrj explicit 634*38fd1498Szrj dynamic_bitset(const char* __str, 635*38fd1498Szrj const allocator_type& __alloc = allocator_type()) 636*38fd1498Szrj : _Base(__alloc) 637*38fd1498Szrj { 638*38fd1498Szrj size_t __len = 0; 639*38fd1498Szrj if (__str) 640*38fd1498Szrj while (__str[__len] != '\0') 641*38fd1498Szrj ++__len; 642*38fd1498Szrj this->resize(__len); 643*38fd1498Szrj this->_M_copy_from_ptr<char,std::char_traits<char>> 644*38fd1498Szrj (__str, __len, 0, __len, '0', '1'); 645*38fd1498Szrj } 646*38fd1498Szrj 647*38fd1498Szrj /** 648*38fd1498Szrj * @brief Copy constructor. 649*38fd1498Szrj */ 650*38fd1498Szrj dynamic_bitset(const dynamic_bitset& __b) 651*38fd1498Szrj : _Base(__b), _M_Nb(__b.size()) 652*38fd1498Szrj { } 653*38fd1498Szrj 654*38fd1498Szrj /** 655*38fd1498Szrj * @brief Move constructor. 656*38fd1498Szrj */ 657*38fd1498Szrj dynamic_bitset(dynamic_bitset&& __b) 658*38fd1498Szrj : _Base(std::forward<_Base>(__b)), _M_Nb(__b.size()) 659*38fd1498Szrj { } 660*38fd1498Szrj 661*38fd1498Szrj /** 662*38fd1498Szrj * @brief Swap with another bitset. 663*38fd1498Szrj */ 664*38fd1498Szrj void 665*38fd1498Szrj swap(dynamic_bitset& __b) 666*38fd1498Szrj { 667*38fd1498Szrj this->_M_swap(__b); 668*38fd1498Szrj std::swap(this->_M_Nb, __b._M_Nb); 669*38fd1498Szrj } 670*38fd1498Szrj 671*38fd1498Szrj /** 672*38fd1498Szrj * @brief Assignment. 673*38fd1498Szrj */ 674*38fd1498Szrj dynamic_bitset& 675*38fd1498Szrj operator=(const dynamic_bitset& __b) 676*38fd1498Szrj { 677*38fd1498Szrj if (&__b != this) 678*38fd1498Szrj { 679*38fd1498Szrj this->_M_assign(__b); 680*38fd1498Szrj this->_M_Nb = __b._M_Nb; 681*38fd1498Szrj } 682*38fd1498Szrj } 683*38fd1498Szrj 684*38fd1498Szrj /** 685*38fd1498Szrj * @brief Move assignment. 686*38fd1498Szrj */ 687*38fd1498Szrj dynamic_bitset& 688*38fd1498Szrj operator=(dynamic_bitset&& __b) 689*38fd1498Szrj { 690*38fd1498Szrj this->swap(__b); 691*38fd1498Szrj return *this; 692*38fd1498Szrj } 693*38fd1498Szrj 694*38fd1498Szrj /** 695*38fd1498Szrj * @brief Return the allocator for the bitset. 696*38fd1498Szrj */ 697*38fd1498Szrj allocator_type 698*38fd1498Szrj get_allocator() const 699*38fd1498Szrj { return this->_M_get_allocator(); } 700*38fd1498Szrj 701*38fd1498Szrj /** 702*38fd1498Szrj * @brief Resize the bitset. 703*38fd1498Szrj */ 704*38fd1498Szrj void 705*38fd1498Szrj resize(size_type __nbits, bool __value = false) 706*38fd1498Szrj { 707*38fd1498Szrj if (__value) 708*38fd1498Szrj this->_M_do_fill(); 709*38fd1498Szrj this->_M_resize(__nbits, __value); 710*38fd1498Szrj this->_M_Nb = __nbits; 711*38fd1498Szrj this->_M_do_sanitize(); 712*38fd1498Szrj } 713*38fd1498Szrj 714*38fd1498Szrj /** 715*38fd1498Szrj * @brief Clear the bitset. 716*38fd1498Szrj */ 717*38fd1498Szrj void 718*38fd1498Szrj clear() 719*38fd1498Szrj { 720*38fd1498Szrj this->_M_clear(); 721*38fd1498Szrj this->_M_Nb = 0; 722*38fd1498Szrj } 723*38fd1498Szrj 724*38fd1498Szrj /** 725*38fd1498Szrj * @brief Push a bit onto the high end of the bitset. 726*38fd1498Szrj */ 727*38fd1498Szrj void 728*38fd1498Szrj push_back(bool __bit) 729*38fd1498Szrj { 730*38fd1498Szrj if (size_t __offset = this->size() % bits_per_block == 0) 731*38fd1498Szrj this->_M_do_append_block(block_type(0), this->_M_Nb); 732*38fd1498Szrj ++this->_M_Nb; 733*38fd1498Szrj this->_M_unchecked_set(this->_M_Nb, __bit); 734*38fd1498Szrj } 735*38fd1498Szrj 736*38fd1498Szrj /** 737*38fd1498Szrj * @brief Append a block. 738*38fd1498Szrj */ 739*38fd1498Szrj void 740*38fd1498Szrj append(block_type __block) 741*38fd1498Szrj { 742*38fd1498Szrj this->_M_do_append_block(__block, this->_M_Nb); 743*38fd1498Szrj this->_M_Nb += bits_per_block; 744*38fd1498Szrj } 745*38fd1498Szrj 746*38fd1498Szrj /** 747*38fd1498Szrj * @brief 748*38fd1498Szrj */ 749*38fd1498Szrj void 750*38fd1498Szrj append(initializer_list<block_type> __il) 751*38fd1498Szrj { this->append(__il.begin(), __il.end()); } 752*38fd1498Szrj 753*38fd1498Szrj /** 754*38fd1498Szrj * @brief Append an iterator range of blocks. 755*38fd1498Szrj */ 756*38fd1498Szrj template <typename _BlockInputIterator> 757*38fd1498Szrj void 758*38fd1498Szrj append(_BlockInputIterator __first, _BlockInputIterator __last) 759*38fd1498Szrj { 760*38fd1498Szrj for (; __first != __last; ++__first) 761*38fd1498Szrj this->append(*__first); 762*38fd1498Szrj } 763*38fd1498Szrj 764*38fd1498Szrj // 23.3.5.2 dynamic_bitset operations: 765*38fd1498Szrj //@{ 766*38fd1498Szrj /** 767*38fd1498Szrj * @brief Operations on dynamic_bitsets. 768*38fd1498Szrj * @param __rhs A same-sized dynamic_bitset. 769*38fd1498Szrj * 770*38fd1498Szrj * These should be self-explanatory. 771*38fd1498Szrj */ 772*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 773*38fd1498Szrj operator&=(const dynamic_bitset<_WordT, _Alloc>& __rhs) 774*38fd1498Szrj { 775*38fd1498Szrj this->_M_do_and(__rhs); 776*38fd1498Szrj return *this; 777*38fd1498Szrj } 778*38fd1498Szrj 779*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 780*38fd1498Szrj operator&=(dynamic_bitset<_WordT, _Alloc>&& __rhs) 781*38fd1498Szrj { 782*38fd1498Szrj this->_M_do_and(std::move(__rhs)); 783*38fd1498Szrj return *this; 784*38fd1498Szrj } 785*38fd1498Szrj 786*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 787*38fd1498Szrj operator|=(const dynamic_bitset<_WordT, _Alloc>& __rhs) 788*38fd1498Szrj { 789*38fd1498Szrj this->_M_do_or(__rhs); 790*38fd1498Szrj return *this; 791*38fd1498Szrj } 792*38fd1498Szrj 793*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 794*38fd1498Szrj operator^=(const dynamic_bitset<_WordT, _Alloc>& __rhs) 795*38fd1498Szrj { 796*38fd1498Szrj this->_M_do_xor(__rhs); 797*38fd1498Szrj return *this; 798*38fd1498Szrj } 799*38fd1498Szrj 800*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 801*38fd1498Szrj operator-=(const dynamic_bitset<_WordT, _Alloc>& __rhs) 802*38fd1498Szrj { 803*38fd1498Szrj this->_M_do_dif(__rhs); 804*38fd1498Szrj return *this; 805*38fd1498Szrj } 806*38fd1498Szrj //@} 807*38fd1498Szrj 808*38fd1498Szrj //@{ 809*38fd1498Szrj /** 810*38fd1498Szrj * @brief Operations on dynamic_bitsets. 811*38fd1498Szrj * @param __pos The number of places to shift. 812*38fd1498Szrj * 813*38fd1498Szrj * These should be self-explanatory. 814*38fd1498Szrj */ 815*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 816*38fd1498Szrj operator<<=(size_type __pos) 817*38fd1498Szrj { 818*38fd1498Szrj if (__builtin_expect(__pos < this->_M_Nb, 1)) 819*38fd1498Szrj { 820*38fd1498Szrj this->_M_do_left_shift(__pos); 821*38fd1498Szrj this->_M_do_sanitize(); 822*38fd1498Szrj } 823*38fd1498Szrj else 824*38fd1498Szrj this->_M_do_reset(); 825*38fd1498Szrj return *this; 826*38fd1498Szrj } 827*38fd1498Szrj 828*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 829*38fd1498Szrj operator>>=(size_type __pos) 830*38fd1498Szrj { 831*38fd1498Szrj if (__builtin_expect(__pos < this->_M_Nb, 1)) 832*38fd1498Szrj { 833*38fd1498Szrj this->_M_do_right_shift(__pos); 834*38fd1498Szrj this->_M_do_sanitize(); 835*38fd1498Szrj } 836*38fd1498Szrj else 837*38fd1498Szrj this->_M_do_reset(); 838*38fd1498Szrj return *this; 839*38fd1498Szrj } 840*38fd1498Szrj //@} 841*38fd1498Szrj 842*38fd1498Szrj // Set, reset, and flip. 843*38fd1498Szrj /** 844*38fd1498Szrj * @brief Sets every bit to true. 845*38fd1498Szrj */ 846*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 847*38fd1498Szrj set() 848*38fd1498Szrj { 849*38fd1498Szrj this->_M_do_set(); 850*38fd1498Szrj this->_M_do_sanitize(); 851*38fd1498Szrj return *this; 852*38fd1498Szrj } 853*38fd1498Szrj 854*38fd1498Szrj /** 855*38fd1498Szrj * @brief Sets a given bit to a particular value. 856*38fd1498Szrj * @param __pos The index of the bit. 857*38fd1498Szrj * @param __val Either true or false, defaults to true. 858*38fd1498Szrj * @throw std::out_of_range If @a __pos is bigger the size of the %set. 859*38fd1498Szrj */ 860*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 861*38fd1498Szrj set(size_type __pos, bool __val = true) 862*38fd1498Szrj { 863*38fd1498Szrj if (__pos >= _M_Nb) 864*38fd1498Szrj __throw_out_of_range(__N("dynamic_bitset::set")); 865*38fd1498Szrj return this->_M_unchecked_set(__pos, __val); 866*38fd1498Szrj } 867*38fd1498Szrj 868*38fd1498Szrj /** 869*38fd1498Szrj * @brief Sets every bit to false. 870*38fd1498Szrj */ 871*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 872*38fd1498Szrj reset() 873*38fd1498Szrj { 874*38fd1498Szrj this->_M_do_reset(); 875*38fd1498Szrj return *this; 876*38fd1498Szrj } 877*38fd1498Szrj 878*38fd1498Szrj /** 879*38fd1498Szrj * @brief Sets a given bit to false. 880*38fd1498Szrj * @param __pos The index of the bit. 881*38fd1498Szrj * @throw std::out_of_range If @a __pos is bigger the size of the %set. 882*38fd1498Szrj * 883*38fd1498Szrj * Same as writing @c set(__pos, false). 884*38fd1498Szrj */ 885*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 886*38fd1498Szrj reset(size_type __pos) 887*38fd1498Szrj { 888*38fd1498Szrj if (__pos >= _M_Nb) 889*38fd1498Szrj __throw_out_of_range(__N("dynamic_bitset::reset")); 890*38fd1498Szrj return this->_M_unchecked_reset(__pos); 891*38fd1498Szrj } 892*38fd1498Szrj 893*38fd1498Szrj /** 894*38fd1498Szrj * @brief Toggles every bit to its opposite value. 895*38fd1498Szrj */ 896*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 897*38fd1498Szrj flip() 898*38fd1498Szrj { 899*38fd1498Szrj this->_M_do_flip(); 900*38fd1498Szrj this->_M_do_sanitize(); 901*38fd1498Szrj return *this; 902*38fd1498Szrj } 903*38fd1498Szrj 904*38fd1498Szrj /** 905*38fd1498Szrj * @brief Toggles a given bit to its opposite value. 906*38fd1498Szrj * @param __pos The index of the bit. 907*38fd1498Szrj * @throw std::out_of_range If @a __pos is bigger the size of the %set. 908*38fd1498Szrj */ 909*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>& 910*38fd1498Szrj flip(size_type __pos) 911*38fd1498Szrj { 912*38fd1498Szrj if (__pos >= _M_Nb) 913*38fd1498Szrj __throw_out_of_range(__N("dynamic_bitset::flip")); 914*38fd1498Szrj return this->_M_unchecked_flip(__pos); 915*38fd1498Szrj } 916*38fd1498Szrj 917*38fd1498Szrj /// See the no-argument flip(). 918*38fd1498Szrj dynamic_bitset<_WordT, _Alloc> 919*38fd1498Szrj operator~() const 920*38fd1498Szrj { return dynamic_bitset<_WordT, _Alloc>(*this).flip(); } 921*38fd1498Szrj 922*38fd1498Szrj //@{ 923*38fd1498Szrj /** 924*38fd1498Szrj * @brief Array-indexing support. 925*38fd1498Szrj * @param __pos Index into the %dynamic_bitset. 926*38fd1498Szrj * @return A bool for a 'const %dynamic_bitset'. For non-const 927*38fd1498Szrj * bitsets, an instance of the reference proxy class. 928*38fd1498Szrj * @note These operators do no range checking and throw no 929*38fd1498Szrj * exceptions, as required by DR 11 to the standard. 930*38fd1498Szrj */ 931*38fd1498Szrj reference 932*38fd1498Szrj operator[](size_type __pos) 933*38fd1498Szrj { return reference(*this,__pos); } 934*38fd1498Szrj 935*38fd1498Szrj const_reference 936*38fd1498Szrj operator[](size_type __pos) const 937*38fd1498Szrj { return _M_unchecked_test(__pos); } 938*38fd1498Szrj //@} 939*38fd1498Szrj 940*38fd1498Szrj /** 941*38fd1498Szrj * @brief Returns a numerical interpretation of the %dynamic_bitset. 942*38fd1498Szrj * @return The integral equivalent of the bits. 943*38fd1498Szrj * @throw std::overflow_error If there are too many bits to be 944*38fd1498Szrj * represented in an @c unsigned @c long. 945*38fd1498Szrj */ 946*38fd1498Szrj unsigned long 947*38fd1498Szrj to_ulong() const 948*38fd1498Szrj { return this->_M_do_to_ulong(); } 949*38fd1498Szrj 950*38fd1498Szrj /** 951*38fd1498Szrj * @brief Returns a numerical interpretation of the %dynamic_bitset. 952*38fd1498Szrj * @return The integral equivalent of the bits. 953*38fd1498Szrj * @throw std::overflow_error If there are too many bits to be 954*38fd1498Szrj * represented in an @c unsigned @c long. 955*38fd1498Szrj */ 956*38fd1498Szrj unsigned long long 957*38fd1498Szrj to_ullong() const 958*38fd1498Szrj { return this->_M_do_to_ullong(); } 959*38fd1498Szrj 960*38fd1498Szrj /** 961*38fd1498Szrj * @brief Returns a character interpretation of the %dynamic_bitset. 962*38fd1498Szrj * @return The string equivalent of the bits. 963*38fd1498Szrj * 964*38fd1498Szrj * Note the ordering of the bits: decreasing character positions 965*38fd1498Szrj * correspond to increasing bit positions (see the main class notes for 966*38fd1498Szrj * an example). 967*38fd1498Szrj */ 968*38fd1498Szrj template<typename _CharT = char, 969*38fd1498Szrj typename _Traits = std::char_traits<_CharT>, 970*38fd1498Szrj typename _Alloc1 = std::allocator<_CharT>> 971*38fd1498Szrj std::basic_string<_CharT, _Traits, _Alloc1> 972*38fd1498Szrj to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const 973*38fd1498Szrj { 974*38fd1498Szrj std::basic_string<_CharT, _Traits, _Alloc1> __result; 975*38fd1498Szrj _M_copy_to_string(__result, __zero, __one); 976*38fd1498Szrj return __result; 977*38fd1498Szrj } 978*38fd1498Szrj 979*38fd1498Szrj // Helper functions for string operations. 980*38fd1498Szrj template<typename _CharT, typename _Traits> 981*38fd1498Szrj void 982*38fd1498Szrj _M_copy_from_ptr(const _CharT*, size_t, size_t, size_t, 983*38fd1498Szrj _CharT, _CharT); 984*38fd1498Szrj 985*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc1> 986*38fd1498Szrj void 987*38fd1498Szrj _M_copy_from_string(const std::basic_string<_CharT, 988*38fd1498Szrj _Traits, _Alloc1>& __str, size_t __pos, size_t __n, 989*38fd1498Szrj _CharT __zero = _CharT('0'), 990*38fd1498Szrj _CharT __one = _CharT('1')) 991*38fd1498Szrj { _M_copy_from_ptr<_CharT, _Traits>(__str.data(), __str.size(), 992*38fd1498Szrj __pos, __n, __zero, __one); } 993*38fd1498Szrj 994*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc1> 995*38fd1498Szrj void 996*38fd1498Szrj _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str, 997*38fd1498Szrj _CharT __zero = _CharT('0'), 998*38fd1498Szrj _CharT __one = _CharT('1')) const; 999*38fd1498Szrj 1000*38fd1498Szrj /// Returns the number of bits which are set. 1001*38fd1498Szrj size_type 1002*38fd1498Szrj count() const noexcept 1003*38fd1498Szrj { return this->_M_do_count(); } 1004*38fd1498Szrj 1005*38fd1498Szrj /// Returns the total number of bits. 1006*38fd1498Szrj size_type 1007*38fd1498Szrj size() const noexcept 1008*38fd1498Szrj { return this->_M_Nb; } 1009*38fd1498Szrj 1010*38fd1498Szrj /// Returns the total number of blocks. 1011*38fd1498Szrj size_type 1012*38fd1498Szrj num_blocks() const noexcept 1013*38fd1498Szrj { return this->_M_size(); } 1014*38fd1498Szrj 1015*38fd1498Szrj /// Returns true if the dynamic_bitset is empty. 1016*38fd1498Szrj bool 1017*38fd1498Szrj empty() const noexcept 1018*38fd1498Szrj { return (this->_M_Nb == 0); } 1019*38fd1498Szrj 1020*38fd1498Szrj /// Returns the maximum size of a dynamic_bitset object having the same 1021*38fd1498Szrj /// type as *this. 1022*38fd1498Szrj /// The real answer is max() * bits_per_block but is likely to overflow. 1023*38fd1498Szrj constexpr size_type 1024*38fd1498Szrj max_size() noexcept 1025*38fd1498Szrj { return std::numeric_limits<block_type>::max(); } 1026*38fd1498Szrj 1027*38fd1498Szrj /** 1028*38fd1498Szrj * @brief Tests the value of a bit. 1029*38fd1498Szrj * @param __pos The index of a bit. 1030*38fd1498Szrj * @return The value at @a __pos. 1031*38fd1498Szrj * @throw std::out_of_range If @a __pos is bigger the size of the %set. 1032*38fd1498Szrj */ 1033*38fd1498Szrj bool 1034*38fd1498Szrj test(size_type __pos) const 1035*38fd1498Szrj { 1036*38fd1498Szrj if (__pos >= _M_Nb) 1037*38fd1498Szrj __throw_out_of_range(__N("dynamic_bitset::test")); 1038*38fd1498Szrj return _M_unchecked_test(__pos); 1039*38fd1498Szrj } 1040*38fd1498Szrj 1041*38fd1498Szrj /** 1042*38fd1498Szrj * @brief Tests whether all the bits are on. 1043*38fd1498Szrj * @return True if all the bits are set. 1044*38fd1498Szrj */ 1045*38fd1498Szrj bool 1046*38fd1498Szrj all() const 1047*38fd1498Szrj { return this->_M_are_all_aux() == _M_Nb; } 1048*38fd1498Szrj 1049*38fd1498Szrj /** 1050*38fd1498Szrj * @brief Tests whether any of the bits are on. 1051*38fd1498Szrj * @return True if at least one bit is set. 1052*38fd1498Szrj */ 1053*38fd1498Szrj bool 1054*38fd1498Szrj any() const 1055*38fd1498Szrj { return this->_M_is_any(); } 1056*38fd1498Szrj 1057*38fd1498Szrj /** 1058*38fd1498Szrj * @brief Tests whether any of the bits are on. 1059*38fd1498Szrj * @return True if none of the bits are set. 1060*38fd1498Szrj */ 1061*38fd1498Szrj bool 1062*38fd1498Szrj none() const 1063*38fd1498Szrj { return !this->_M_is_any(); } 1064*38fd1498Szrj 1065*38fd1498Szrj //@{ 1066*38fd1498Szrj /// Self-explanatory. 1067*38fd1498Szrj dynamic_bitset<_WordT, _Alloc> 1068*38fd1498Szrj operator<<(size_type __pos) const 1069*38fd1498Szrj { return dynamic_bitset<_WordT, _Alloc>(*this) <<= __pos; } 1070*38fd1498Szrj 1071*38fd1498Szrj dynamic_bitset<_WordT, _Alloc> 1072*38fd1498Szrj operator>>(size_type __pos) const 1073*38fd1498Szrj { return dynamic_bitset<_WordT, _Alloc>(*this) >>= __pos; } 1074*38fd1498Szrj //@} 1075*38fd1498Szrj 1076*38fd1498Szrj /** 1077*38fd1498Szrj * @brief Finds the index of the first "on" bit. 1078*38fd1498Szrj * @return The index of the first bit set, or size() if not found. 1079*38fd1498Szrj * @sa find_next 1080*38fd1498Szrj */ 1081*38fd1498Szrj size_type 1082*38fd1498Szrj find_first() const 1083*38fd1498Szrj { return this->_M_do_find_first(this->_M_Nb); } 1084*38fd1498Szrj 1085*38fd1498Szrj /** 1086*38fd1498Szrj * @brief Finds the index of the next "on" bit after prev. 1087*38fd1498Szrj * @return The index of the next bit set, or size() if not found. 1088*38fd1498Szrj * @param __prev Where to start searching. 1089*38fd1498Szrj * @sa find_first 1090*38fd1498Szrj */ 1091*38fd1498Szrj size_type 1092*38fd1498Szrj find_next(size_t __prev) const 1093*38fd1498Szrj { return this->_M_do_find_next(__prev, this->_M_Nb); } 1094*38fd1498Szrj 1095*38fd1498Szrj bool 1096*38fd1498Szrj is_subset_of(const dynamic_bitset& __b) const 1097*38fd1498Szrj { return this->_M_is_subset_of(__b); } 1098*38fd1498Szrj 1099*38fd1498Szrj bool 1100*38fd1498Szrj is_proper_subset_of(const dynamic_bitset& __b) const 1101*38fd1498Szrj { return this->_M_is_proper_subset_of(__b); } 1102*38fd1498Szrj 1103*38fd1498Szrj friend bool 1104*38fd1498Szrj operator==(const dynamic_bitset<_WordT, _Alloc>& __lhs, 1105*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __rhs) 1106*38fd1498Szrj { return __lhs._M_is_equal(__rhs); } 1107*38fd1498Szrj 1108*38fd1498Szrj friend bool 1109*38fd1498Szrj operator<(const dynamic_bitset<_WordT, _Alloc>& __lhs, 1110*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __rhs) 1111*38fd1498Szrj { return __lhs._M_is_less(__rhs); } 1112*38fd1498Szrj }; 1113*38fd1498Szrj 1114*38fd1498Szrj template<typename _WordT, typename _Alloc> 1115*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc1> 1116*38fd1498Szrj inline void 1117*38fd1498Szrj dynamic_bitset<_WordT, _Alloc>:: 1118*38fd1498Szrj _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str, 1119*38fd1498Szrj _CharT __zero, _CharT __one) const 1120*38fd1498Szrj { 1121*38fd1498Szrj __str.assign(_M_Nb, __zero); 1122*38fd1498Szrj for (size_t __i = _M_Nb; __i > 0; --__i) 1123*38fd1498Szrj if (_M_unchecked_test(__i - 1)) 1124*38fd1498Szrj _Traits::assign(__str[_M_Nb - __i], __one); 1125*38fd1498Szrj } 1126*38fd1498Szrj 1127*38fd1498Szrj 1128*38fd1498Szrj //@{ 1129*38fd1498Szrj /// These comparisons for equality/inequality are, well, @e bitwise. 1130*38fd1498Szrj 1131*38fd1498Szrj template<typename _WordT, typename _Alloc> 1132*38fd1498Szrj inline bool 1133*38fd1498Szrj operator!=(const dynamic_bitset<_WordT, _Alloc>& __lhs, 1134*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __rhs) 1135*38fd1498Szrj { return !(__lhs == __rhs); } 1136*38fd1498Szrj 1137*38fd1498Szrj template<typename _WordT, typename _Alloc> 1138*38fd1498Szrj inline bool 1139*38fd1498Szrj operator<=(const dynamic_bitset<_WordT, _Alloc>& __lhs, 1140*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __rhs) 1141*38fd1498Szrj { return !(__lhs > __rhs); } 1142*38fd1498Szrj 1143*38fd1498Szrj template<typename _WordT, typename _Alloc> 1144*38fd1498Szrj inline bool 1145*38fd1498Szrj operator>(const dynamic_bitset<_WordT, _Alloc>& __lhs, 1146*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __rhs) 1147*38fd1498Szrj { return __rhs < __lhs; } 1148*38fd1498Szrj 1149*38fd1498Szrj template<typename _WordT, typename _Alloc> 1150*38fd1498Szrj inline bool 1151*38fd1498Szrj operator>=(const dynamic_bitset<_WordT, _Alloc>& __lhs, 1152*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __rhs) 1153*38fd1498Szrj { return !(__lhs < __rhs); } 1154*38fd1498Szrj //@} 1155*38fd1498Szrj 1156*38fd1498Szrj // 23.3.5.3 bitset operations: 1157*38fd1498Szrj //@{ 1158*38fd1498Szrj /** 1159*38fd1498Szrj * @brief Global bitwise operations on bitsets. 1160*38fd1498Szrj * @param __x A bitset. 1161*38fd1498Szrj * @param __y A bitset of the same size as @a __x. 1162*38fd1498Szrj * @return A new bitset. 1163*38fd1498Szrj * 1164*38fd1498Szrj * These should be self-explanatory. 1165*38fd1498Szrj */ 1166*38fd1498Szrj template<typename _WordT, typename _Alloc> 1167*38fd1498Szrj inline dynamic_bitset<_WordT, _Alloc> 1168*38fd1498Szrj operator&(const dynamic_bitset<_WordT, _Alloc>& __x, 1169*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __y) 1170*38fd1498Szrj { 1171*38fd1498Szrj dynamic_bitset<_WordT, _Alloc> __result(__x); 1172*38fd1498Szrj __result &= __y; 1173*38fd1498Szrj return __result; 1174*38fd1498Szrj } 1175*38fd1498Szrj 1176*38fd1498Szrj template<typename _WordT, typename _Alloc> 1177*38fd1498Szrj inline dynamic_bitset<_WordT, _Alloc> 1178*38fd1498Szrj operator|(const dynamic_bitset<_WordT, _Alloc>& __x, 1179*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __y) 1180*38fd1498Szrj { 1181*38fd1498Szrj dynamic_bitset<_WordT, _Alloc> __result(__x); 1182*38fd1498Szrj __result |= __y; 1183*38fd1498Szrj return __result; 1184*38fd1498Szrj } 1185*38fd1498Szrj 1186*38fd1498Szrj template <typename _WordT, typename _Alloc> 1187*38fd1498Szrj inline dynamic_bitset<_WordT, _Alloc> 1188*38fd1498Szrj operator^(const dynamic_bitset<_WordT, _Alloc>& __x, 1189*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __y) 1190*38fd1498Szrj { 1191*38fd1498Szrj dynamic_bitset<_WordT, _Alloc> __result(__x); 1192*38fd1498Szrj __result ^= __y; 1193*38fd1498Szrj return __result; 1194*38fd1498Szrj } 1195*38fd1498Szrj 1196*38fd1498Szrj template <typename _WordT, typename _Alloc> 1197*38fd1498Szrj inline dynamic_bitset<_WordT, _Alloc> 1198*38fd1498Szrj operator-(const dynamic_bitset<_WordT, _Alloc>& __x, 1199*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __y) 1200*38fd1498Szrj { 1201*38fd1498Szrj dynamic_bitset<_WordT, _Alloc> __result(__x); 1202*38fd1498Szrj __result -= __y; 1203*38fd1498Szrj return __result; 1204*38fd1498Szrj } 1205*38fd1498Szrj //@} 1206*38fd1498Szrj 1207*38fd1498Szrj /// Stream output operator for dynamic_bitset. 1208*38fd1498Szrj template <typename _CharT, typename _Traits, 1209*38fd1498Szrj typename _WordT, typename _Alloc> 1210*38fd1498Szrj inline std::basic_ostream<_CharT, _Traits>& 1211*38fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1212*38fd1498Szrj const dynamic_bitset<_WordT, _Alloc>& __x) 1213*38fd1498Szrj { 1214*38fd1498Szrj std::basic_string<_CharT, _Traits> __tmp; 1215*38fd1498Szrj 1216*38fd1498Szrj const ctype<_CharT>& __ct = use_facet<ctype<_CharT>>(__os.getloc()); 1217*38fd1498Szrj __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1')); 1218*38fd1498Szrj return __os << __tmp; 1219*38fd1498Szrj } 1220*38fd1498Szrj /** 1221*38fd1498Szrj * @} 1222*38fd1498Szrj */ 1223*38fd1498Szrj} // tr2 1224*38fd1498Szrj 1225*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION 1226*38fd1498Szrj} // std 1227*38fd1498Szrj 1228*38fd1498Szrj#include <tr2/dynamic_bitset.tcc> 1229*38fd1498Szrj 1230*38fd1498Szrj#endif /* _GLIBCXX_TR2_DYNAMIC_BITSET */ 1231