// 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;

	if _GLIBCXX17_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;
	      }
	  }
      }

      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)
      {
	static_cast<_Base&>(*this) = static_cast<_Base&&>(__b);
	_M_Nb = __b._M_Nb;
	if _GLIBCXX17_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;
      }

      /**
       *  @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 */
