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