// Debugging deque 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/deque
 *  This file is a GNU debug extension to the Standard C++ Library.
 */

#ifndef _GLIBCXX_DEBUG_DEQUE
#define _GLIBCXX_DEBUG_DEQUE 1

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

namespace std
{
namespace __debug
{
  /// Class std::deque with safety/checking/debug instrumentation.
  template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
    class deque
    : public _GLIBCXX_STD_D::deque<_Tp, _Allocator>,
      public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
    {
      typedef  _GLIBCXX_STD_D::deque<_Tp, _Allocator> _Base;
      typedef __gnu_debug::_Safe_sequence<deque> _Safe_base;

    public:
      typedef typename _Base::reference             reference;
      typedef typename _Base::const_reference       const_reference;

      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque>
						    iterator;
      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque>
						     const_iterator;

      typedef typename _Base::size_type             size_type;
      typedef typename _Base::difference_type       difference_type;

      typedef _Tp				    value_type;
      typedef _Allocator			    allocator_type;
      typedef typename _Base::pointer               pointer;
      typedef typename _Base::const_pointer         const_pointer;
      typedef std::reverse_iterator<iterator>       reverse_iterator;
      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

      // 23.2.1.1 construct/copy/destroy:
      explicit deque(const _Allocator& __a = _Allocator())
      : _Base(__a) { }

      explicit deque(size_type __n, const _Tp& __value = _Tp(),
		     const _Allocator& __a = _Allocator())
      : _Base(__n, __value, __a) { }

      template<class _InputIterator>
        deque(_InputIterator __first, _InputIterator __last,
	      const _Allocator& __a = _Allocator())
	: _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a)
        { }

      deque(const deque& __x)
      : _Base(__x), _Safe_base() { }

      deque(const _Base& __x)
      : _Base(__x), _Safe_base() { }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      deque(deque&& __x)
      : _Base(std::forward<deque>(__x)), _Safe_base()
      { this->_M_swap(__x); }

      deque(initializer_list<value_type> __l,
	    const allocator_type& __a = allocator_type())
      : _Base(__l, __a), _Safe_base() { }
#endif

      ~deque() { }

      deque&
      operator=(const deque& __x)
      {
	*static_cast<_Base*>(this) = __x;
	this->_M_invalidate_all();
	return *this;
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      deque&
      operator=(deque&& __x)
      {
	// NB: DR 1204.
	// NB: DR 675.
	clear();
	swap(__x);
	return *this;
      }

      deque&
      operator=(initializer_list<value_type> __l)
      {
	*static_cast<_Base*>(this) = __l;
	this->_M_invalidate_all();
	return *this;
      }
#endif

      template<class _InputIterator>
        void
        assign(_InputIterator __first, _InputIterator __last)
        {
	  __glibcxx_check_valid_range(__first, __last);
	  _Base::assign(__first, __last);
	  this->_M_invalidate_all();
	}

      void
      assign(size_type __n, const _Tp& __t)
      {
	_Base::assign(__n, __t);
	this->_M_invalidate_all();
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      void
      assign(initializer_list<value_type> __l)
      {
	_Base::assign(__l);
	this->_M_invalidate_all();
      }
#endif

      using _Base::get_allocator;

      // iterators:
      iterator
      begin()
      { return iterator(_Base::begin(), this); }

      const_iterator
      begin() const
      { return const_iterator(_Base::begin(), this); }

      iterator
      end()
      { return iterator(_Base::end(), this); }

      const_iterator
      end() const
      { return const_iterator(_Base::end(), this); }

      reverse_iterator
      rbegin()
      { return reverse_iterator(end()); }

      const_reverse_iterator
      rbegin() const
      { return const_reverse_iterator(end()); }

      reverse_iterator
      rend()
      { return reverse_iterator(begin()); }

      const_reverse_iterator
      rend() const
      { return const_reverse_iterator(begin()); }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      const_iterator
      cbegin() const
      { return const_iterator(_Base::begin(), this); }

      const_iterator
      cend() const
      { return const_iterator(_Base::end(), this); }

      const_reverse_iterator
      crbegin() const
      { return const_reverse_iterator(end()); }

      const_reverse_iterator
      crend() const
      { return const_reverse_iterator(begin()); }
#endif

      // 23.2.1.2 capacity:
      using _Base::size;
      using _Base::max_size;

      void
      resize(size_type __sz, _Tp __c = _Tp())
      {
	typedef typename _Base::const_iterator _Base_const_iterator;
	typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;

	bool __invalidate_all = __sz > this->size();
	if (__sz < this->size())
	  this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));

	_Base::resize(__sz, __c);

	if (__invalidate_all)
	  this->_M_invalidate_all();
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      using _Base::shrink_to_fit;
#endif

      using _Base::empty;

      // element access:
      reference
      operator[](size_type __n)
      {
	__glibcxx_check_subscript(__n);
	return _M_base()[__n];
      }

      const_reference
      operator[](size_type __n) const
      {
	__glibcxx_check_subscript(__n);
	return _M_base()[__n];
      }

      using _Base::at;

      reference
      front()
      {
	__glibcxx_check_nonempty();
	return _Base::front();
      }

      const_reference
      front() const
      {
	__glibcxx_check_nonempty();
	return _Base::front();
      }

      reference
      back()
      {
	__glibcxx_check_nonempty();
	return _Base::back();
      }

      const_reference
      back() const
      {
	__glibcxx_check_nonempty();
	return _Base::back();
      }

      // 23.2.1.3 modifiers:
      void
      push_front(const _Tp& __x)
      {
	_Base::push_front(__x);
	this->_M_invalidate_all();
      }

      void
      push_back(const _Tp& __x)
      {
	_Base::push_back(__x);
	this->_M_invalidate_all();
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      void
      push_front(_Tp&& __x)
      { emplace_front(std::move(__x)); }

      void
      push_back(_Tp&& __x)
      { emplace_back(std::move(__x)); }

      template<typename... _Args>
        void
        emplace_front(_Args&&... __args)
	{
	  _Base::emplace_front(std::forward<_Args>(__args)...);
	  this->_M_invalidate_all();
	}

      template<typename... _Args>
        void
        emplace_back(_Args&&... __args)
	{
	  _Base::emplace_back(std::forward<_Args>(__args)...);
	  this->_M_invalidate_all();
	}

      template<typename... _Args>
        iterator
        emplace(iterator __position, _Args&&... __args)
	{
	  __glibcxx_check_insert(__position);
	  typename _Base::iterator __res = _Base::emplace(__position.base(),
					    std::forward<_Args>(__args)...);
	  this->_M_invalidate_all();
	  return iterator(__res, this);
	}
#endif

      iterator
      insert(iterator __position, const _Tp& __x)
      {
	__glibcxx_check_insert(__position);
	typename _Base::iterator __res = _Base::insert(__position.base(), __x);
	this->_M_invalidate_all();
	return iterator(__res, this);
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      iterator
      insert(iterator __position, _Tp&& __x)
      { return emplace(__position, std::move(__x)); }

      void
      insert(iterator __p, initializer_list<value_type> __l)
      {
	_Base::insert(__p, __l);
	this->_M_invalidate_all();
      }
#endif

      void
      insert(iterator __position, size_type __n, const _Tp& __x)
      {
	__glibcxx_check_insert(__position);
	_Base::insert(__position.base(), __n, __x);
	this->_M_invalidate_all();
      }

      template<class _InputIterator>
        void
        insert(iterator __position,
	       _InputIterator __first, _InputIterator __last)
        {
	  __glibcxx_check_insert_range(__position, __first, __last);
	  _Base::insert(__position.base(), __first, __last);
	  this->_M_invalidate_all();
	}

      void
      pop_front()
      {
	__glibcxx_check_nonempty();
	iterator __victim = begin();
	__victim._M_invalidate();
	_Base::pop_front();
      }

      void
      pop_back()
      {
	__glibcxx_check_nonempty();
	iterator __victim = end();
	--__victim;
	__victim._M_invalidate();
	_Base::pop_back();
      }

      iterator
      erase(iterator __position)
      {
	__glibcxx_check_erase(__position);
	if (__position == begin() || __position == end()-1)
	  {
	    __position._M_invalidate();
	    return iterator(_Base::erase(__position.base()), this);
	  }
	else
	  {
	    typename _Base::iterator __res = _Base::erase(__position.base());
	    this->_M_invalidate_all();
	    return iterator(__res, this);
	  }
      }

      iterator
      erase(iterator __first, iterator __last)
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 151. can't currently clear() empty container
	__glibcxx_check_erase_range(__first, __last);
        if (__first == begin() || __last == end())
	  {
	    this->_M_detach_singular();
	    for (iterator __position = __first; __position != __last; )
	      {
		iterator __victim = __position++;
		__victim._M_invalidate();
	      }
	    __try
	      {
		return iterator(_Base::erase(__first.base(), __last.base()),
				this);
	      }
	    __catch(...)
	      {
		this->_M_revalidate_singular();
		__throw_exception_again;
	      }
	  }
	else
	  {
	    typename _Base::iterator __res = _Base::erase(__first.base(),
							  __last.base());
	    this->_M_invalidate_all();
	    return iterator(__res, this);
	  }
      }

      void
      swap(deque& __x)
      {
	_Base::swap(__x);
	this->_M_swap(__x);
      }

      void
      clear()
      {
	_Base::clear();
	this->_M_invalidate_all();
      }

      _Base&
      _M_base()       { return *this; }

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

  template<typename _Tp, typename _Alloc>
    inline bool
    operator==(const deque<_Tp, _Alloc>& __lhs,
	       const deque<_Tp, _Alloc>& __rhs)
    { return __lhs._M_base() == __rhs._M_base(); }

  template<typename _Tp, typename _Alloc>
    inline bool
    operator!=(const deque<_Tp, _Alloc>& __lhs,
	       const deque<_Tp, _Alloc>& __rhs)
    { return __lhs._M_base() != __rhs._M_base(); }

  template<typename _Tp, typename _Alloc>
    inline bool
    operator<(const deque<_Tp, _Alloc>& __lhs,
	      const deque<_Tp, _Alloc>& __rhs)
    { return __lhs._M_base() < __rhs._M_base(); }

  template<typename _Tp, typename _Alloc>
    inline bool
    operator<=(const deque<_Tp, _Alloc>& __lhs,
	       const deque<_Tp, _Alloc>& __rhs)
    { return __lhs._M_base() <= __rhs._M_base(); }

  template<typename _Tp, typename _Alloc>
    inline bool
    operator>=(const deque<_Tp, _Alloc>& __lhs,
	       const deque<_Tp, _Alloc>& __rhs)
    { return __lhs._M_base() >= __rhs._M_base(); }

  template<typename _Tp, typename _Alloc>
    inline bool
    operator>(const deque<_Tp, _Alloc>& __lhs,
	      const deque<_Tp, _Alloc>& __rhs)
    { return __lhs._M_base() > __rhs._M_base(); }

  template<typename _Tp, typename _Alloc>
    inline void
    swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
    { __lhs.swap(__rhs); }

} // namespace __debug
} // namespace std

#endif
