xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/tr2/dynamic_bitset (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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