// TR2 <dynamic_bitset> -*- C++ -*-

// Copyright (C) 2009-2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file tr2/dynamic_bitset
 *  This is a TR2 C++ Library header.
 */

#ifndef _GLIBCXX_TR2_DYNAMIC_BITSET
#define _GLIBCXX_TR2_DYNAMIC_BITSET 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <limits>
#include <vector>
#include <string>
#include <istream>
#include <bits/functexcept.h>
#include <bits/stl_algo.h>	// For fill
#include <bits/cxxabi_forced.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

namespace tr2
{
  /**
   *  @defgroup dynamic_bitset Dynamic Bitset.
   *  @ingroup extensions
   *
   *  @{
   */

  /**
   *  Base class, general case.
   *
   *  See documentation for dynamic_bitset.
   */
  template<typename _WordT = unsigned long long,
	   typename _Alloc = std::allocator<_WordT>>
    struct __dynamic_bitset_base
    {
      static_assert(std::is_unsigned<_WordT>::value, "template argument "
		    "_WordT not an unsigned integral type");

      typedef _WordT block_type;
      typedef _Alloc allocator_type;
      typedef size_t size_type;

      static const size_type _S_bits_per_block = __CHAR_BIT__ * sizeof(block_type);
      static const size_type npos = static_cast<size_type>(-1);

      /// 0 is the least significant word.
      std::vector<block_type, allocator_type> _M_w;

      explicit
      __dynamic_bitset_base(const allocator_type& __alloc)
      : _M_w(__alloc)
      { }

      __dynamic_bitset_base() = default;
      __dynamic_bitset_base(const __dynamic_bitset_base&) = default;
      __dynamic_bitset_base(__dynamic_bitset_base&& __b) = default;
      __dynamic_bitset_base& operator=(const __dynamic_bitset_base&) = default;
      __dynamic_bitset_base& operator=(__dynamic_bitset_base&&) = default;
      ~__dynamic_bitset_base() = default;

      explicit
      __dynamic_bitset_base(size_type __nbits, unsigned long long __val = 0ULL,
			   const allocator_type& __alloc = allocator_type())
      : _M_w(__nbits / _S_bits_per_block + (__nbits % _S_bits_per_block > 0),
	     block_type(0), __alloc)
      {
	if (__nbits < std::numeric_limits<decltype(__val)>::digits)
	  __val &= ~(-1ULL << __nbits);
	if (__val == 0)
	  return;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
	if constexpr (sizeof(__val) == sizeof(block_type))
	  _M_w[0] = __val;
	else
	  {
	    const size_t __n
	      = std::min(_M_w.size(), sizeof(__val) / sizeof(block_type));
	    for (size_t __i = 0; __val && __i < __n; ++__i)
	      {
		_M_w[__i] = static_cast<block_type>(__val);
		__val >>= _S_bits_per_block;
	      }
	  }
#pragma GCC diagnostic pop
      }

      void
      _M_swap(__dynamic_bitset_base& __b) noexcept
      { this->_M_w.swap(__b._M_w); }

      void
      _M_clear() noexcept
      { this->_M_w.clear(); }

      void
      _M_resize(size_t __nbits, bool __value)
      {
	size_t __sz = __nbits / _S_bits_per_block;
	if (__nbits % _S_bits_per_block > 0)
	  ++__sz;
	if (__sz != this->_M_w.size())
	  {
	    block_type __val = 0;
	    if (__value)
	      __val = std::numeric_limits<block_type>::max();
	    this->_M_w.resize(__sz, __val);
	  }
      }

      allocator_type
      _M_get_allocator() const noexcept
      { return this->_M_w.get_allocator(); }

      static size_type
      _S_whichword(size_type __pos) noexcept
      { return __pos / _S_bits_per_block; }

      static size_type
      _S_whichbyte(size_type __pos) noexcept
      { return (__pos % _S_bits_per_block) / __CHAR_BIT__; }

      static size_type
      _S_whichbit(size_type __pos) noexcept
      { return __pos % _S_bits_per_block; }

      static block_type
      _S_maskbit(size_type __pos) noexcept
      { return (static_cast<block_type>(1)) << _S_whichbit(__pos); }

      block_type&
      _M_getword(size_type __pos) noexcept
      { return this->_M_w[_S_whichword(__pos)]; }

      block_type
      _M_getword(size_type __pos) const noexcept
      { return this->_M_w[_S_whichword(__pos)]; }

      block_type&
      _M_hiword() noexcept
      { return this->_M_w[_M_w.size() - 1]; }

      block_type
      _M_hiword() const noexcept
      { return this->_M_w[_M_w.size() - 1]; }

      void
      _M_do_and(const __dynamic_bitset_base& __x) noexcept
      {
	if (__x._M_w.size() == this->_M_w.size())
	  for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
	    this->_M_w[__i] &= __x._M_w[__i];
	else
	  return;
      }

      void
      _M_do_or(const __dynamic_bitset_base& __x) noexcept
      {
	if (__x._M_w.size() == this->_M_w.size())
	  for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
	    this->_M_w[__i] |= __x._M_w[__i];
	else
	  return;
      }

      void
      _M_do_xor(const __dynamic_bitset_base& __x) noexcept
      {
	if (__x._M_w.size() == this->_M_w.size())
	  for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
	    this->_M_w[__i] ^= __x._M_w[__i];
	else
	  return;
      }

      void
      _M_do_dif(const __dynamic_bitset_base& __x) noexcept
      {
	if (__x._M_w.size() == this->_M_w.size())
	  for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
	    this->_M_w[__i] &= ~__x._M_w[__i];
	else
	  return;
      }

      void
      _M_do_left_shift(size_t __shift);

      void
      _M_do_right_shift(size_t __shift);

      void
      _M_do_flip() noexcept
      {
	for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
	  this->_M_w[__i] = ~this->_M_w[__i];
      }

      void
      _M_do_set() noexcept
      {
	for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
	  this->_M_w[__i] = static_cast<block_type>(-1);
      }

      void
      _M_do_reset() noexcept
      {
	std::fill(_M_w.begin(), _M_w.end(), static_cast<block_type>(0));
      }

      bool
      _M_is_equal(const __dynamic_bitset_base& __x) const noexcept
      {
	if (__x._M_w.size() == this->_M_w.size())
	  {
	    for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
	      if (this->_M_w[__i] != __x._M_w[__i])
		return false;
	    return true;
	  }
	else
	  return false;
      }

      bool
      _M_is_less(const __dynamic_bitset_base& __x) const noexcept
      {
	if (__x._M_w.size() == this->_M_w.size())
	  {
	    for (size_t __i = this->_M_w.size(); __i > 0; --__i)
	      {
		if (this->_M_w[__i-1] < __x._M_w[__i-1])
		  return true;
		else if (this->_M_w[__i-1] > __x._M_w[__i-1])
		  return false;
	      }
	    return false;
	  }
	else
	  return false;
      }

      size_t
      _M_are_all_aux() const noexcept
      {
	for (size_t __i = 0; __i < this->_M_w.size() - 1; ++__i)
	  if (_M_w[__i] != static_cast<block_type>(-1))
	    return 0;
	return ((this->_M_w.size() - 1) * _S_bits_per_block
		+ __builtin_popcountll(this->_M_hiword()));
      }

      bool
      _M_is_any() const noexcept
      {
	for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
	  if (this->_M_w[__i] != static_cast<block_type>(0))
	    return true;
	return false;
      }

      bool
      _M_is_subset_of(const __dynamic_bitset_base& __b) noexcept
      {
	if (__b._M_w.size() == this->_M_w.size())
	  {
	    for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
	      if (this->_M_w[__i] != (this->_M_w[__i] | __b._M_w[__i]))
		return false;
	    return true;
	  }
	else
	  return false;
      }

      bool
      _M_is_proper_subset_of(const __dynamic_bitset_base& __b) const noexcept
      {
	if (this->_M_is_subset_of(__b))
	  {
	    if (*this == __b)
	      return false;
	    else
	      return true;
	  }
	else
	  return false;
      }

      size_t
      _M_do_count() const noexcept
      {
	size_t __result = 0;
	for (size_t __i = 0; __i < this->_M_w.size(); ++__i)
	  __result += __builtin_popcountll(this->_M_w[__i]);
	return __result;
      }

      size_type
      _M_size() const noexcept
      { return this->_M_w.size(); }

      unsigned long
      _M_do_to_ulong() const;

      unsigned long long
      _M_do_to_ullong() const;

      // find first "on" bit
      size_type
      _M_do_find_first(size_t __not_found) const;

      // find the next "on" bit that follows "prev"
      size_type
      _M_do_find_next(size_t __prev, size_t __not_found) const;

      // do append of block
      void
      _M_do_append_block(block_type __block, size_type __pos)
      {
	size_t __offset = __pos % _S_bits_per_block;
	if (__offset == 0)
	  this->_M_w.push_back(__block);
	else
	  {
	    this->_M_hiword() |= (__block << __offset);
	    this->_M_w.push_back(__block >> (_S_bits_per_block - __offset));
	  }
      }
    };

  /**
   *  @brief  The %dynamic_bitset class represents a sequence of bits.
   *
   *  See N2050,
   *  Proposal to Add a Dynamically Sizeable Bitset to the Standard Library.
   *  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2050.pdf
   *
   *  In the general unoptimized case, storage is allocated in
   *  word-sized blocks.  Let B be the number of bits in a word, then
   *  (Nb+(B-1))/B words will be used for storage.  B - Nb%B bits are
   *  unused.  (They are the high-order bits in the highest word.)  It
   *  is a class invariant that those unused bits are always zero.
   *
   *  If you think of %dynamic_bitset as "a simple array of bits," be
   *  aware that your mental picture is reversed: a %dynamic_bitset
   *  behaves the same way as bits in integers do, with the bit at
   *  index 0 in the "least significant / right-hand" position, and
   *  the bit at index Nb-1 in the "most significant / left-hand"
   *  position.  Thus, unlike other containers, a %dynamic_bitset's
   *  index "counts from right to left," to put it very loosely.
   *
   *  This behavior is preserved when translating to and from strings.
   *  For example, the first line of the following program probably
   *  prints "b('a') is 0001100001" on a modern ASCII system.
   *
   *  @code
   *     #include <dynamic_bitset>
   *     #include <iostream>
   *     #include <sstream>
   *
   *     using namespace std;
   *
   *     int main()
   *     {
   *         long         a = 'a';
   *         dynamic_bitset<> b(a);
   *
   *         cout << "b('a') is " << b << endl;
   *
   *         ostringstream s;
   *         s << b;
   *         string  str = s.str();
   *         cout << "index 3 in the string is " << str[3] << " but\n"
   *              << "index 3 in the bitset is " << b[3] << endl;
   *     }
   *  @endcode
   *
   *  Most of the actual code isn't contained in %dynamic_bitset<>
   *  itself, but in the base class __dynamic_bitset_base.  The base
   *  class works with whole words, not with individual bits.  This
   *  allows us to specialize __dynamic_bitset_base for the important
   *  special case where the %dynamic_bitset is only a single word.
   *
   *  Extra confusion can result due to the fact that the storage for
   *  __dynamic_bitset_base @e is a vector, and is indexed as such.  This is
   *  carefully encapsulated.
   */
  template<typename _WordT = unsigned long long,
	   typename _Alloc = std::allocator<_WordT>>
    class dynamic_bitset
    : private __dynamic_bitset_base<_WordT, _Alloc>
    {
      static_assert(std::is_unsigned<_WordT>::value, "template argument "
		    "_WordT not an unsigned integral type");

    public:

      typedef __dynamic_bitset_base<_WordT, _Alloc> _Base;
      typedef _WordT block_type;
      typedef _Alloc allocator_type;
      typedef size_t size_type;

      static const size_type bits_per_block = __CHAR_BIT__ * sizeof(block_type);
      // Use this: constexpr size_type std::numeric_limits<size_type>::max().
      static const size_type npos = static_cast<size_type>(-1);

    private:

      //  Clear the unused bits in the uppermost word.
      void
      _M_do_sanitize()
      {
	size_type __shift = this->_M_Nb % bits_per_block;
	if (__shift > 0)
	  this->_M_hiword() &= block_type(~(block_type(-1) << __shift));
      }

      //  Set the unused bits in the uppermost word.
      void
      _M_do_fill()
      {
	size_type __shift = this->_M_Nb % bits_per_block;
	if (__shift > 0)
	  this->_M_hiword() |= block_type(block_type(-1) << __shift);
      }

      /**
       *  These versions of single-bit set, reset, flip, and test
       *  do no range checking.
       */
      dynamic_bitset&
      _M_unchecked_set(size_type __pos) noexcept
      {
	this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
	return *this;
      }

      dynamic_bitset&
      _M_unchecked_set(size_type __pos, int __val) noexcept
      {
	if (__val)
	  this->_M_getword(__pos) |= _Base::_S_maskbit(__pos);
	else
	  this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
	return *this;
      }

      dynamic_bitset&
      _M_unchecked_reset(size_type __pos) noexcept
      {
	this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos);
	return *this;
      }

      dynamic_bitset&
      _M_unchecked_flip(size_type __pos) noexcept
      {
	this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos);
	return *this;
      }

      bool
      _M_unchecked_test(size_type __pos) const noexcept
      { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos))
		!= static_cast<_WordT>(0)); }

      size_type _M_Nb = 0;

    public:
      /**
       *  This encapsulates the concept of a single bit.  An instance
       *  of this class is a proxy for an actual bit; this way the
       *  individual bit operations are done as faster word-size
       *  bitwise instructions.
       *
       *  Most users will never need to use this class directly;
       *  conversions to and from bool are automatic and should be
       *  transparent.  Overloaded operators help to preserve the
       *  illusion.
       *
       *  (On a typical system, this "bit %reference" is 64 times the
       *  size of an actual bit.  Ha.)
       */
      class reference
      {
	friend class dynamic_bitset;

	block_type *_M_wp;
	size_type _M_bpos;

      public:
	reference(dynamic_bitset& __b, size_type __pos) noexcept
	{
	  this->_M_wp = &__b._M_getword(__pos);
	  this->_M_bpos = _Base::_S_whichbit(__pos);
	}

	// For b[i] = __x;
	reference&
	operator=(bool __x) noexcept
	{
	  if (__x)
	    *this->_M_wp |= _Base::_S_maskbit(this->_M_bpos);
	  else
	    *this->_M_wp &= ~_Base::_S_maskbit(this->_M_bpos);
	  return *this;
	}

	// For b[i] = b[__j];
	reference&
	operator=(const reference& __j) noexcept
	{
	  if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos)))
	    *this->_M_wp |= _Base::_S_maskbit(this->_M_bpos);
	  else
	    *this->_M_wp &= ~_Base::_S_maskbit(this->_M_bpos);
	  return *this;
	}

	// Flips the bit
	bool
	operator~() const noexcept
	{ return (*(_M_wp) & _Base::_S_maskbit(this->_M_bpos)) == 0; }

	// For __x = b[i];
	operator bool() const noexcept
	{ return (*(this->_M_wp) & _Base::_S_maskbit(this->_M_bpos)) != 0; }

	// For b[i].flip();
	reference&
	flip() noexcept
	{
	  *this->_M_wp ^= _Base::_S_maskbit(this->_M_bpos);
	  return *this;
	}
      };

      friend class reference;

      typedef bool const_reference;

      // 23.3.5.1 constructors:

      /// All bits set to zero.
      dynamic_bitset() = default;

      /// All bits set to zero.
      explicit
      dynamic_bitset(const allocator_type& __alloc)
      : _Base(__alloc)
      { }

      /// Initial bits bitwise-copied from a single word (others set to zero).
      explicit
      dynamic_bitset(size_type __nbits, unsigned long long __val = 0ULL,
		     const allocator_type& __alloc = allocator_type())
      : _Base(__nbits, __val, __alloc),
	_M_Nb(__nbits)
      { }

      dynamic_bitset(initializer_list<block_type> __il,
		     const allocator_type& __alloc = allocator_type())
      : _Base(__alloc)
      { this->append(__il); }

      /**
       *  @brief  Use a subset of a string.
       *  @param  __str  A string of '0' and '1' characters.
       *  @param  __pos  Index of the first character in @p __str to use.
       *  @param  __n    The number of characters to copy.
       *  @param  __zero The character to use for unset bits.
       *  @param  __one  The character to use for set bits.
       *  @param  __alloc An allocator.
       *  @throw  std::out_of_range  If @p __pos is bigger the size of @p __str.
       *  @throw  std::invalid_argument  If a character appears in the string
       *                                 which is neither '0' nor '1'.
       */
      template<typename _CharT, typename _Traits, typename _Alloc1>
	explicit
	dynamic_bitset(const std::basic_string<_CharT, _Traits, _Alloc1>& __str,
		       typename basic_string<_CharT,_Traits,_Alloc1>::size_type
		       __pos = 0,
		       typename basic_string<_CharT,_Traits,_Alloc1>::size_type
		       __n = std::basic_string<_CharT, _Traits, _Alloc1>::npos,
		       _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'),
		       const allocator_type& __alloc = allocator_type())
	: _Base(__alloc)
	{
	  if (__pos > __str.size())
	    __throw_out_of_range(__N("dynamic_bitset::bitset initial position "
				     "not valid"));

	  // Watch for npos.
	  this->_M_Nb = (__n > __str.size() ? __str.size() - __pos : __n);
	  this->resize(this->_M_Nb);
	  this->_M_copy_from_string(__str, __pos, __n, __zero, __one);
	}

      /**
       *  @brief  Construct from a string.
       *  @param  __str  A string of '0' and '1' characters.
       *  @param  __alloc An allocator.
       *  @throw  std::invalid_argument  If a character appears in the string
       *                                 which is neither '0' nor '1'.
       */
      explicit
      dynamic_bitset(const char* __str,
		     const allocator_type& __alloc = allocator_type())
      : _Base(__builtin_strlen(__str), 0ULL, __alloc),
	_M_Nb(__builtin_strlen(__str))
      {
	this->_M_copy_from_ptr(__str, _M_Nb, 0, _M_Nb);
      }

      /// Copy constructor.
      dynamic_bitset(const dynamic_bitset&) = default;

      /// Move constructor.
      dynamic_bitset(dynamic_bitset&& __b) noexcept
      : _Base(std::move(__b)), _M_Nb(__b._M_Nb)
      { __b.clear(); }

      /// Swap with another bitset.
      void
      swap(dynamic_bitset& __b) noexcept
      {
	this->_M_swap(__b);
	std::swap(this->_M_Nb, __b._M_Nb);
      }

      /// Copy assignment operator.
      dynamic_bitset& operator=(const dynamic_bitset&) = default;

      /// Move assignment operator.
      dynamic_bitset&
      operator=(dynamic_bitset&& __b)
      noexcept(std::is_nothrow_move_assignable<_Base>::value)
      {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
	static_cast<_Base&>(*this) = static_cast<_Base&&>(__b);
	_M_Nb = __b._M_Nb;
	if constexpr (std::is_nothrow_move_assignable<_Base>::value)
	  __b._M_Nb = 0;
	else if (get_allocator() == __b.get_allocator())
	  __b._M_Nb = 0;
	return *this;
#pragma GCC diagnostic pop
      }

      /**
       *  @brief  Return the allocator for the bitset.
       */
      allocator_type
      get_allocator() const noexcept
      { return this->_M_get_allocator(); }

      /**
       *  @brief  Resize the bitset.
       */
      void
      resize(size_type __nbits, bool __value = false)
      {
	if (__value)
	  this->_M_do_fill();
	this->_M_resize(__nbits, __value);
	this->_M_Nb = __nbits;
	this->_M_do_sanitize();
      }

      /**
       *  @brief  Clear the bitset.
       */
      void
      clear()
      {
	this->_M_clear();
	this->_M_Nb = 0;
      }

      /**
       *  @brief  Push a bit onto the high end of the bitset.
       */
      void
      push_back(bool __bit)
      {
	if (this->size() % bits_per_block == 0)
	  this->_M_do_append_block(block_type(__bit), this->_M_Nb);
	else
	  this->_M_unchecked_set(this->_M_Nb, __bit);
	++this->_M_Nb;
      }

      // XXX why is there no pop_back() member in the proposal?

      /**
       *  @brief  Append a block.
       */
      void
      append(block_type __block)
      {
	this->_M_do_append_block(__block, this->_M_Nb);
	this->_M_Nb += bits_per_block;
      }

      /**
       *  @brief
       */
      void
      append(initializer_list<block_type> __il)
      { this->append(__il.begin(), __il.end()); }

      /**
       *  @brief  Append an iterator range of blocks.
       */
      template <typename _BlockInputIterator>
	void
	append(_BlockInputIterator __first, _BlockInputIterator __last)
	{
	  for (; __first != __last; ++__first)
	    this->append(*__first);
	}

      // 23.3.5.2 dynamic_bitset operations:
      ///@{
      /**
       *  @brief  Operations on dynamic_bitsets.
       *  @param  __rhs  A same-sized dynamic_bitset.
       *
       *  These should be self-explanatory.
       */
      dynamic_bitset&
      operator&=(const dynamic_bitset& __rhs)
      {
	this->_M_do_and(__rhs);
	return *this;
      }

      dynamic_bitset&
      operator&=(dynamic_bitset&& __rhs)
      {
	this->_M_do_and(std::move(__rhs));
	return *this;
      }

      dynamic_bitset&
      operator|=(const dynamic_bitset& __rhs)
      {
	this->_M_do_or(__rhs);
	return *this;
      }

      dynamic_bitset&
      operator^=(const dynamic_bitset& __rhs)
      {
	this->_M_do_xor(__rhs);
	return *this;
      }

      dynamic_bitset&
      operator-=(const dynamic_bitset& __rhs)
      {
	this->_M_do_dif(__rhs);
	return *this;
      }
      ///@}

      ///@{
      /**
       *  @brief  Operations on dynamic_bitsets.
       *  @param  __pos The number of places to shift.
       *
       *  These should be self-explanatory.
       */
      dynamic_bitset&
      operator<<=(size_type __pos)
      {
	if (__builtin_expect(__pos < this->_M_Nb, 1))
	  {
	    this->_M_do_left_shift(__pos);
	    this->_M_do_sanitize();
	  }
	else
	  this->_M_do_reset();
	return *this;
      }

      dynamic_bitset&
      operator>>=(size_type __pos)
      {
	if (__builtin_expect(__pos < this->_M_Nb, 1))
	  this->_M_do_right_shift(__pos);
	else
	  this->_M_do_reset();
	return *this;
      }
      ///@}

      // Set, reset, and flip.
      /**
       *  @brief Sets every bit to true.
       */
      dynamic_bitset&
      set()
      {
	this->_M_do_set();
	this->_M_do_sanitize();
	return *this;
      }

      /**
       *  @brief Sets a given bit to a particular value.
       *  @param  __pos  The index of the bit.
       *  @param  __val  Either true or false, defaults to true.
       *  @throw  std::out_of_range  If @a __pos is bigger the size of the %set.
       */
      dynamic_bitset&
      set(size_type __pos, bool __val = true)
      {
	if (__pos >= _M_Nb)
	  __throw_out_of_range(__N("dynamic_bitset::set"));
	return this->_M_unchecked_set(__pos, __val);
      }

      /**
       *  @brief Sets every bit to false.
       */
      dynamic_bitset&
      reset()
      {
	this->_M_do_reset();
	return *this;
      }

      /**
       *  @brief Sets a given bit to false.
       *  @param  __pos  The index of the bit.
       *  @throw  std::out_of_range  If @a __pos is bigger the size of the %set.
       *
       *  Same as writing @c set(__pos, false).
       */
      dynamic_bitset&
      reset(size_type __pos)
      {
	if (__pos >= _M_Nb)
	  __throw_out_of_range(__N("dynamic_bitset::reset"));
	return this->_M_unchecked_reset(__pos);
      }

      /**
       *  @brief Toggles every bit to its opposite value.
       */
      dynamic_bitset&
      flip()
      {
	this->_M_do_flip();
	this->_M_do_sanitize();
	return *this;
      }

      /**
       *  @brief Toggles a given bit to its opposite value.
       *  @param  __pos  The index of the bit.
       *  @throw  std::out_of_range  If @a __pos is bigger the size of the %set.
       */
      dynamic_bitset&
      flip(size_type __pos)
      {
	if (__pos >= _M_Nb)
	  __throw_out_of_range(__N("dynamic_bitset::flip"));
	return this->_M_unchecked_flip(__pos);
      }

      /// See the no-argument flip().
      dynamic_bitset
      operator~() const
      { return dynamic_bitset<_WordT, _Alloc>(*this).flip(); }

      ///@{
      /**
       *  @brief  Array-indexing support.
       *  @param  __pos  Index into the %dynamic_bitset.
       *  @return A bool for a 'const %dynamic_bitset'.  For non-const
       *           bitsets, an instance of the reference proxy class.
       *  @note These operators do no range checking and throw no
       *         exceptions, as required by DR 11 to the standard.
       */
      reference
      operator[](size_type __pos)
      { return reference(*this,__pos); }

      const_reference
      operator[](size_type __pos) const
      { return _M_unchecked_test(__pos); }
      ///@}

      /**
       *  @brief Returns a numerical interpretation of the %dynamic_bitset.
       *  @return  The integral equivalent of the bits.
       *  @throw  std::overflow_error  If there are too many bits to be
       *                               represented in an @c unsigned @c long.
       */
      unsigned long
      to_ulong() const
      { return this->_M_do_to_ulong(); }

      /**
       *  @brief Returns a numerical interpretation of the %dynamic_bitset.
       *  @return  The integral equivalent of the bits.
       *  @throw  std::overflow_error  If there are too many bits to be
       *                               represented in an @c unsigned @c long.
       */
      unsigned long long
      to_ullong() const
      { return this->_M_do_to_ullong(); }

      /**
       *  @brief Returns a character interpretation of the %dynamic_bitset.
       *  @return  The string equivalent of the bits.
       *
       *  Note the ordering of the bits:  decreasing character positions
       *  correspond to increasing bit positions (see the main class notes for
       *  an example).
       */
      template<typename _CharT = char,
	       typename _Traits = std::char_traits<_CharT>,
	       typename _Alloc1 = std::allocator<_CharT>>
	std::basic_string<_CharT, _Traits, _Alloc1>
	to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const
	{
	  std::basic_string<_CharT, _Traits, _Alloc1> __result;
	  _M_copy_to_string(__result, __zero, __one);
	  return __result;
	}

      // Helper functions for string operations.
      template<typename _Traits = std::char_traits<char>,
	       typename _CharT = typename _Traits::char_type>
	void
	_M_copy_from_ptr(const _CharT*, size_t, size_t, size_t,
			 _CharT __zero = _CharT('0'),
			 _CharT __one = _CharT('1'));

      template<typename _CharT, typename _Traits, typename _Alloc1>
	void
	_M_copy_from_string(const basic_string<_CharT, _Traits, _Alloc1>& __str,
			    size_t __pos, size_t __n,
			    _CharT __zero = _CharT('0'),
			    _CharT __one = _CharT('1'))
	{
	  _M_copy_from_ptr<_Traits>(__str.data(), __str.size(), __pos, __n,
				    __zero, __one);
	}

      template<typename _CharT, typename _Traits, typename _Alloc1>
	void
	_M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str,
			  _CharT __zero = _CharT('0'),
			  _CharT __one = _CharT('1')) const;

      /// Returns the number of bits which are set.
      size_type
      count() const noexcept
      { return this->_M_do_count(); }

      /// Returns the total number of bits.
      size_type
      size() const noexcept
      { return this->_M_Nb; }

      /// Returns the total number of blocks.
      size_type
      num_blocks() const noexcept
      { return this->_M_size(); }

      /// Returns true if the dynamic_bitset is empty.
      _GLIBCXX_NODISCARD bool
      empty() const noexcept
      { return (this->_M_Nb == 0); }

      /// Returns the maximum size of a dynamic_bitset object having the same
      /// type as *this.
      /// The real answer is max() * bits_per_block but is likely to overflow.
      constexpr size_type
      max_size() noexcept
      { return std::numeric_limits<block_type>::max(); }

      /**
       *  @brief Tests the value of a bit.
       *  @param  __pos  The index of a bit.
       *  @return  The value at @a __pos.
       *  @throw  std::out_of_range  If @a __pos is bigger the size of the %set.
       */
      bool
      test(size_type __pos) const
      {
	if (__pos >= _M_Nb)
	  __throw_out_of_range(__N("dynamic_bitset::test"));
	return _M_unchecked_test(__pos);
      }

      /**
       *  @brief Tests whether all the bits are on.
       *  @return  True if all the bits are set.
       */
      bool
      all() const
      { return this->_M_are_all_aux() == _M_Nb; }

      /**
       *  @brief Tests whether any of the bits are on.
       *  @return  True if at least one bit is set.
       */
      bool
      any() const
      { return this->_M_is_any(); }

      /**
       *  @brief Tests whether any of the bits are on.
       *  @return  True if none of the bits are set.
       */
      bool
      none() const
      { return !this->_M_is_any(); }

      ///@{
      /// Self-explanatory.
      dynamic_bitset
      operator<<(size_type __pos) const
      { return dynamic_bitset(*this) <<= __pos; }

      dynamic_bitset
      operator>>(size_type __pos) const
      { return dynamic_bitset(*this) >>= __pos; }
      ///@}

      /**
       *  @brief  Finds the index of the first "on" bit.
       *  @return  The index of the first bit set, or size() if not found.
       *  @sa  find_next
       */
      size_type
      find_first() const
      { return this->_M_do_find_first(this->_M_Nb); }

      /**
       *  @brief  Finds the index of the next "on" bit after prev.
       *  @return  The index of the next bit set, or size() if not found.
       *  @param  __prev  Where to start searching.
       *  @sa  find_first
       */
      size_type
      find_next(size_t __prev) const
      { return this->_M_do_find_next(__prev, this->_M_Nb); }

      bool
      is_subset_of(const dynamic_bitset& __b) const
      { return this->_M_is_subset_of(__b); }

      bool
      is_proper_subset_of(const dynamic_bitset& __b) const
      { return this->_M_is_proper_subset_of(__b); }

      friend bool
      operator==(const dynamic_bitset& __lhs,
		 const dynamic_bitset& __rhs) noexcept
      { return __lhs._M_Nb == __rhs._M_Nb && __lhs._M_is_equal(__rhs); }

      friend bool
      operator<(const dynamic_bitset& __lhs,
		const dynamic_bitset& __rhs) noexcept
      { return __lhs._M_is_less(__rhs) || __lhs._M_Nb < __rhs._M_Nb; }
    };

  template<typename _WordT, typename _Alloc>
    template<typename _CharT, typename _Traits, typename _Alloc1>
      inline void
      dynamic_bitset<_WordT, _Alloc>::
      _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str,
			_CharT __zero, _CharT __one) const
      {
	__str.assign(_M_Nb, __zero);
	for (size_t __i = _M_Nb; __i > 0; --__i)
	  if (_M_unchecked_test(__i - 1))
	    _Traits::assign(__str[_M_Nb - __i], __one);
      }


  ///@{
  /// These comparisons for equality/inequality are, well, @e bitwise.

  template<typename _WordT, typename _Alloc>
    inline bool
    operator!=(const dynamic_bitset<_WordT, _Alloc>& __lhs,
	       const dynamic_bitset<_WordT, _Alloc>& __rhs)
    { return !(__lhs == __rhs); }

  template<typename _WordT, typename _Alloc>
    inline bool
    operator<=(const dynamic_bitset<_WordT, _Alloc>& __lhs,
	       const dynamic_bitset<_WordT, _Alloc>& __rhs)
    { return !(__lhs > __rhs); }

  template<typename _WordT, typename _Alloc>
    inline bool
    operator>(const dynamic_bitset<_WordT, _Alloc>& __lhs,
	      const dynamic_bitset<_WordT, _Alloc>& __rhs)
    { return __rhs < __lhs; }

  template<typename _WordT, typename _Alloc>
    inline bool
    operator>=(const dynamic_bitset<_WordT, _Alloc>& __lhs,
	       const dynamic_bitset<_WordT, _Alloc>& __rhs)
    { return !(__lhs < __rhs); }
  ///@}

  // 23.3.5.3 bitset operations:
  ///@{
  /**
   *  @brief  Global bitwise operations on bitsets.
   *  @param  __x  A bitset.
   *  @param  __y  A bitset of the same size as @a __x.
   *  @return  A new bitset.
   *
   *  These should be self-explanatory.
   */
  template<typename _WordT, typename _Alloc>
    inline dynamic_bitset<_WordT, _Alloc>
    operator&(const dynamic_bitset<_WordT, _Alloc>& __x,
	      const dynamic_bitset<_WordT, _Alloc>& __y)
    {
      dynamic_bitset<_WordT, _Alloc> __result(__x);
      __result &= __y;
      return __result;
    }

  template<typename _WordT, typename _Alloc>
    inline dynamic_bitset<_WordT, _Alloc>
    operator|(const dynamic_bitset<_WordT, _Alloc>& __x,
	      const dynamic_bitset<_WordT, _Alloc>& __y)
    {
      dynamic_bitset<_WordT, _Alloc> __result(__x);
      __result |= __y;
      return __result;
    }

  template <typename _WordT, typename _Alloc>
    inline dynamic_bitset<_WordT, _Alloc>
    operator^(const dynamic_bitset<_WordT, _Alloc>& __x,
	      const dynamic_bitset<_WordT, _Alloc>& __y)
    {
      dynamic_bitset<_WordT, _Alloc> __result(__x);
      __result ^= __y;
      return __result;
    }

  template <typename _WordT, typename _Alloc>
    inline dynamic_bitset<_WordT, _Alloc>
    operator-(const dynamic_bitset<_WordT, _Alloc>& __x,
	      const dynamic_bitset<_WordT, _Alloc>& __y)
    {
      dynamic_bitset<_WordT, _Alloc> __result(__x);
      __result -= __y;
      return __result;
    }
  ///@}

  /// Stream output operator for dynamic_bitset.
  template <typename _CharT, typename _Traits,
	    typename _WordT, typename _Alloc>
    inline std::basic_ostream<_CharT, _Traits>&
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
	       const dynamic_bitset<_WordT, _Alloc>& __x)
    {
      std::basic_string<_CharT, _Traits> __tmp;

      const ctype<_CharT>& __ct = use_facet<ctype<_CharT>>(__os.getloc());
      __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1'));
      return __os << __tmp;
    }
  /**
   *  @}
   */
} // tr2

_GLIBCXX_END_NAMESPACE_VERSION
} // std

#include <tr2/dynamic_bitset.tcc>

#endif /* _GLIBCXX_TR2_DYNAMIC_BITSET */
