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

// Copyright (C) 2003-2021 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

#pragma GCC system_header

#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>
        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>
	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) { }

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

#if __cplusplus >= 201103L
      template<typename _CharT>
        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:
      bitset<_Nb>&
      operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
      {
	_M_base() &= __rhs;
	return *this;
      }

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

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

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

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

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

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

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

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

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

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

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

      // element access:
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 11. Bitset minor problems
      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>
        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>
	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>
        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>
	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>
        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>
	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);
	}

      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> >();
      }

      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;

      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;

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

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

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

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

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

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

  template<size_t _Nb>
    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>
    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>
    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
