// Debugging bitset implementation -*- C++ -*-

// Copyright (C) 2003-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 debug/bitset
 *  This file is a GNU debug extension to the Standard C++ Library.
 */

#ifndef _GLIBCXX_DEBUG_BITSET
#define _GLIBCXX_DEBUG_BITSET

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <bitset>
#include <debug/safe_sequence.h>
#include <debug/safe_iterator.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __debug
{
  /// Class std::bitset with additional safety/checking/debug instrumentation.
  template<size_t _Nb>
    class bitset
    : public _GLIBCXX_STD_C::bitset<_Nb>
#if __cplusplus < 201103L
    , public __gnu_debug::_Safe_sequence_base
#endif
    {
      typedef _GLIBCXX_STD_C::bitset<_Nb> _Base;

    public:
      // In C++11 we rely on normal reference type to preserve the property
      // of bitset to be use as a literal.
      // TODO: Find another solution.
#if __cplusplus >= 201103L
      typedef typename _Base::reference reference;
#else
      // bit reference:
      class reference
      : private _Base::reference
        , public __gnu_debug::_Safe_iterator_base
      {
	typedef typename _Base::reference _Base_ref;

	friend class bitset;
	reference();

	reference(const _Base_ref& __base, bitset* __seq) _GLIBCXX_NOEXCEPT
	: _Base_ref(__base)
	, _Safe_iterator_base(__seq, false)
	{ }

      public:
	reference(const reference& __x) _GLIBCXX_NOEXCEPT
	: _Base_ref(__x)
	, _Safe_iterator_base(__x, false)
	{ }

	reference&
	operator=(bool __x) _GLIBCXX_NOEXCEPT
	{
	  _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
			      _M_message(__gnu_debug::__msg_bad_bitset_write)
				._M_iterator(*this));
	  *static_cast<_Base_ref*>(this) = __x;
	  return *this;
	}

	reference&
	operator=(const reference& __x) _GLIBCXX_NOEXCEPT
	{
	  _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
			       _M_message(__gnu_debug::__msg_bad_bitset_read)
				._M_iterator(__x));
	  _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
			      _M_message(__gnu_debug::__msg_bad_bitset_write)
				._M_iterator(*this));
	  *static_cast<_Base_ref*>(this) = __x;
	  return *this;
	}

	bool
	operator~() const _GLIBCXX_NOEXCEPT
	{
	  _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
			       _M_message(__gnu_debug::__msg_bad_bitset_read)
				._M_iterator(*this));
	  return ~(*static_cast<const _Base_ref*>(this));
	}

	operator bool() const _GLIBCXX_NOEXCEPT
	{
	  _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
			      _M_message(__gnu_debug::__msg_bad_bitset_read)
				._M_iterator(*this));
	  return *static_cast<const _Base_ref*>(this);
	}

	reference&
	flip() _GLIBCXX_NOEXCEPT
	{
	  _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
			      _M_message(__gnu_debug::__msg_bad_bitset_flip)
				._M_iterator(*this));
	  _Base_ref::flip();
	  return *this;
	}
      };
#endif

      // 23.3.5.1 constructors:
      _GLIBCXX_CONSTEXPR bitset() _GLIBCXX_NOEXCEPT
      : _Base() { }

#if __cplusplus >= 201103L
      constexpr bitset(unsigned long long __val) noexcept
#else
      bitset(unsigned long __val)
#endif
      : _Base(__val) { }

      template<typename _CharT, typename _Traits, typename _Alloc>
	_GLIBCXX23_CONSTEXPR
        explicit
        bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
	       typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
	       __pos = 0,
	       typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
	       __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
	: _Base(__str, __pos, __n) { }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 396. what are characters zero and one.
      template<class _CharT, class _Traits, class _Alloc>
	_GLIBCXX23_CONSTEXPR
	bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
	       typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
	       __pos,
	       typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
	       __n,
	       _CharT __zero, _CharT __one = _CharT('1'))
	: _Base(__str, __pos, __n, __zero, __one) { }

      _GLIBCXX23_CONSTEXPR
      bitset(const _Base& __x) : _Base(__x) { }

#if __cplusplus >= 201103L
      template<typename _CharT>
	_GLIBCXX23_CONSTEXPR
        explicit
        bitset(const _CharT* __str,
	       typename std::basic_string<_CharT>::size_type __n
	       = std::basic_string<_CharT>::npos,
	       _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'))
	: _Base(__str, __n, __zero, __one) { }
#endif

      // 23.3.5.2 bitset operations:
      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
      {
	_M_base() &= __rhs;
	return *this;
      }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
      {
	_M_base() |= __rhs;
	return *this;
      }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
      {
	_M_base() ^= __rhs;
	return *this;
      }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      operator<<=(size_t __pos) _GLIBCXX_NOEXCEPT
      {
	_M_base() <<= __pos;
	return *this;
      }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      operator>>=(size_t __pos) _GLIBCXX_NOEXCEPT
      {
	_M_base() >>= __pos;
	return *this;
      }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      set() _GLIBCXX_NOEXCEPT
      {
	_Base::set();
	return *this;
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 186. bitset::set() second parameter should be bool
      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      set(size_t __pos, bool __val = true)
      {
	_Base::set(__pos, __val);
	return *this;
      }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      reset() _GLIBCXX_NOEXCEPT
      {
	_Base::reset();
	return *this;
      }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      reset(size_t __pos)
      {
	_Base::reset(__pos);
	return *this;
      }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>
      operator~() const _GLIBCXX_NOEXCEPT
      { return bitset(~_M_base()); }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      flip() _GLIBCXX_NOEXCEPT
      {
	_Base::flip();
	return *this;
      }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>&
      flip(size_t __pos)
      {
	_Base::flip(__pos);
	return *this;
      }

      // element access:
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 11. Bitset minor problems
      _GLIBCXX23_CONSTEXPR
      reference
      operator[](size_t __pos)
      {
	__glibcxx_check_subscript(__pos);
#if __cplusplus >= 201103L
	return _M_base()[__pos];
#else
	return reference(_M_base()[__pos], this);
#endif
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 11. Bitset minor problems
      _GLIBCXX_CONSTEXPR bool
      operator[](size_t __pos) const
      {
#if __cplusplus < 201103L
	// TODO: Check in debug-mode too.
	__glibcxx_check_subscript(__pos);
#endif
	return _Base::operator[](__pos);
      }

      using _Base::to_ulong;
#if __cplusplus >= 201103L
      using _Base::to_ullong;
#endif

      template <typename _CharT, typename _Traits, typename _Alloc>
	_GLIBCXX23_CONSTEXPR
        std::basic_string<_CharT, _Traits, _Alloc>
        to_string() const
        { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 396. what are characters zero and one.
      template<class _CharT, class _Traits, class _Alloc>
	_GLIBCXX23_CONSTEXPR
	std::basic_string<_CharT, _Traits, _Alloc>
	to_string(_CharT __zero, _CharT __one = _CharT('1')) const
	{
	  return _M_base().template
	    to_string<_CharT, _Traits, _Alloc>(__zero, __one);
	}

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 434. bitset::to_string() hard to use.
      template<typename _CharT, typename _Traits>
	_GLIBCXX23_CONSTEXPR
        std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
        to_string() const
        { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 853. to_string needs updating with zero and one.
      template<class _CharT, class _Traits>
	_GLIBCXX23_CONSTEXPR
	std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
	to_string(_CharT __zero, _CharT __one = _CharT('1')) const
	{ return to_string<_CharT, _Traits,
	                   std::allocator<_CharT> >(__zero, __one); }

      template<typename _CharT>
	_GLIBCXX23_CONSTEXPR
        std::basic_string<_CharT, std::char_traits<_CharT>,
                          std::allocator<_CharT> >
        to_string() const
        {
          return to_string<_CharT, std::char_traits<_CharT>,
                           std::allocator<_CharT> >();
        }

      template<class _CharT>
	_GLIBCXX23_CONSTEXPR
	std::basic_string<_CharT, std::char_traits<_CharT>,
	                  std::allocator<_CharT> >
	to_string(_CharT __zero, _CharT __one = _CharT('1')) const
	{
	  return to_string<_CharT, std::char_traits<_CharT>,
	                   std::allocator<_CharT> >(__zero, __one);
	}

      _GLIBCXX23_CONSTEXPR
      std::basic_string<char, std::char_traits<char>, std::allocator<char> >
      to_string() const
      {
	return to_string<char,std::char_traits<char>,std::allocator<char> >();
      }

      _GLIBCXX23_CONSTEXPR
      std::basic_string<char, std::char_traits<char>, std::allocator<char> >
      to_string(char __zero, char __one = '1') const
      {
	return to_string<char, std::char_traits<char>,
	                 std::allocator<char> >(__zero, __one);
      }

      using _Base::count;
      using _Base::size;

      _GLIBCXX23_CONSTEXPR
      bool
      operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
      { return _M_base() == __rhs._M_base(); }

#if __cpp_impl_three_way_comparison < 201907L
      bool
      operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
      { return _M_base() != __rhs._M_base(); }
#endif

      using _Base::test;
      using _Base::all;
      using _Base::any;
      using _Base::none;

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>
      operator<<(size_t __pos) const _GLIBCXX_NOEXCEPT
      { return bitset<_Nb>(_M_base() << __pos); }

      _GLIBCXX23_CONSTEXPR
      bitset<_Nb>
      operator>>(size_t __pos) const _GLIBCXX_NOEXCEPT
      { return bitset<_Nb>(_M_base() >> __pos); }

      _GLIBCXX23_CONSTEXPR
      _Base& 
      _M_base() _GLIBCXX_NOEXCEPT
      { return *this; }

      _GLIBCXX23_CONSTEXPR
      const _Base&
      _M_base() const _GLIBCXX_NOEXCEPT
      { return *this; }
    };

  template<size_t _Nb>
    _GLIBCXX23_CONSTEXPR
    inline bitset<_Nb>
    operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
    { return bitset<_Nb>(__x) &= __y; }

  template<size_t _Nb>
    _GLIBCXX23_CONSTEXPR
    inline bitset<_Nb>
    operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
    { return bitset<_Nb>(__x) |= __y; }

  template<size_t _Nb>
    _GLIBCXX23_CONSTEXPR
    inline bitset<_Nb>
    operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
    { return bitset<_Nb>(__x) ^= __y; }

  template<typename _CharT, typename _Traits, size_t _Nb>
    inline std::basic_istream<_CharT, _Traits>&
    operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
    { return __is >> __x._M_base(); }

  template<typename _CharT, typename _Traits, size_t _Nb>
    inline std::basic_ostream<_CharT, _Traits>&
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
	       const bitset<_Nb>& __x)
    { return __os << __x._M_base(); }

} // namespace __debug

#if __cplusplus >= 201103L
  // DR 1182.
  /// std::hash specialization for bitset.
  template<size_t _Nb>
    struct hash<__debug::bitset<_Nb>>
    : public __hash_base<size_t, __debug::bitset<_Nb>>
    {
      size_t
      operator()(const __debug::bitset<_Nb>& __b) const noexcept
      { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); }
    };
#endif

} // namespace std

#endif
