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