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

// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
// 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

#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>
#ifndef __GXX_EXPERIMENTAL_CXX0X__
    , public __gnu_debug::_Safe_sequence_base
#endif
    {
      typedef _GLIBCXX_STD_C::bitset<_Nb> _Base;

    public:
      // In C++0x we rely on normal reference type to preserve the property
      // of bitset to be use as a literal.
      // TODO: Find an other solution.
#ifdef __GXX_EXPERIMENTAL_CXX0X__
      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 __attribute__((__unused__)))
	: _Base_ref(__base)
	, _Safe_iterator_base(__seq, false)
	{ }

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

	reference&
	operator=(bool __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;
	}

	reference&
	operator=(const reference& __x)
	{
	  _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_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_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_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() : _Base() { }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      constexpr bitset(unsigned long long __val)
#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) { }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      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)
      {
	_M_base() &= __rhs;
	return *this;
      }

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

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

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

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

      bitset<_Nb>&
      set()
      {
	_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()
      {
	_Base::reset();
	return *this;
      }

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

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

      bitset<_Nb>&
      flip()
      {
	_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);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
	return _M_base()[__pos];
#else
	return reference(_M_base()[__pos], this);
#endif
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 11. Bitset minor problems
      bool
      operator[](size_t __pos) const
      {
	__glibcxx_check_subscript(__pos);
	return _M_base()[__pos];
      }

      using _Base::to_ulong;
#ifdef __GXX_EXPERIMENTAL_CXX0X__
      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
      { return _M_base() == __rhs; }

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

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

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

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

      _Base&
      _M_base() { return *this; }

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

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

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

  template<size_t _Nb>
    bitset<_Nb>
    operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
    { 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

#ifdef __GXX_EXPERIMENTAL_CXX0X__
  // 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
      { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); }
    };
#endif

} // namespace std

#endif
