// Debugging deque implementation -*- C++ -*-

// Copyright (C) 2003-2014 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 _GLIBCXX_VISIBILITY(default)
{
namespace __debug
{
  /// Class std::deque with safety/checking/debug instrumentation.
  template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
    class deque
    : public _GLIBCXX_STD_C::deque<_Tp, _Allocator>,
      public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
    {
      typedef  _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base;

      typedef typename _Base::const_iterator _Base_const_iterator;
      typedef typename _Base::iterator _Base_iterator;
      typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
    public:
      typedef typename _Base::reference             reference;
      typedef typename _Base::const_reference       const_reference;

      typedef __gnu_debug::_Safe_iterator<_Base_iterator,deque>
						    iterator;
      typedef __gnu_debug::_Safe_iterator<_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:

      deque() : _Base() { }

      explicit
      deque(const _Allocator& __a)
      : _Base(__a) { }

#if __cplusplus >= 201103L
      explicit
      deque(size_type __n)
      : _Base(__n) { }

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

#if __cplusplus >= 201103L
      template<class _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
#else
      template<class _InputIterator>
#endif
        deque(_InputIterator __first, _InputIterator __last,
	      const _Allocator& __a = _Allocator())
	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
								     __last)),
		__gnu_debug::__base(__last), __a)
        { }

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

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

#if __cplusplus >= 201103L
      deque(deque&& __x)
      : _Base(std::move(__x))
      { this->_M_swap(__x); }

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

      ~deque() _GLIBCXX_NOEXCEPT { }

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

#if __cplusplus >= 201103L
      deque&
      operator=(deque&& __x) noexcept
      {
	// NB: DR 1204.
	// NB: DR 675.
	__glibcxx_check_self_move_assign(__x);
	clear();
	swap(__x);
	return *this;
      }

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

#if __cplusplus >= 201103L
      template<class _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
#else
      template<class _InputIterator>
#endif
        void
        assign(_InputIterator __first, _InputIterator __last)
        {
	  __glibcxx_check_valid_range(__first, __last);
	  _Base::assign(__gnu_debug::__base(__first),
			__gnu_debug::__base(__last));
	  this->_M_invalidate_all();
	}

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

#if __cplusplus >= 201103L
      void
      assign(initializer_list<value_type> __l)
      {
	_Base::assign(__l);
	this->_M_invalidate_all();
      }
#endif

      using _Base::get_allocator;

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

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

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

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

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

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

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

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

#if __cplusplus >= 201103L
      const_iterator
      cbegin() const noexcept
      { return const_iterator(_Base::begin(), this); }

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

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

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

    private:
      void
      _M_invalidate_after_nth(difference_type __n)
      {
	typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
	this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
      }
      
    public:
      // 23.2.1.2 capacity:
      using _Base::size;
      using _Base::max_size;

#if __cplusplus >= 201103L
      void
      resize(size_type __sz)
      {
	bool __invalidate_all = __sz > this->size();
	if (__sz < this->size())
	  this->_M_invalidate_after_nth(__sz);

	_Base::resize(__sz);

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

      void
      resize(size_type __sz, const _Tp& __c)
      {
	bool __invalidate_all = __sz > this->size();
	if (__sz < this->size())
	  this->_M_invalidate_after_nth(__sz);

	_Base::resize(__sz, __c);

	if (__invalidate_all)
	  this->_M_invalidate_all();
      }
#else
      void
      resize(size_type __sz, _Tp __c = _Tp())
      {
	bool __invalidate_all = __sz > this->size();
	if (__sz < this->size())
	  this->_M_invalidate_after_nth(__sz);

	_Base::resize(__sz, __c);

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

#if __cplusplus >= 201103L
      void
      shrink_to_fit() noexcept
      {
	if (_Base::_M_shrink_to_fit())
	  this->_M_invalidate_all();
      }
#endif

      using _Base::empty;

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

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

      using _Base::at;

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

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

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

      const_reference
      back() const _GLIBCXX_NOEXCEPT
      {
	__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();
      }

#if __cplusplus >= 201103L
      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(const_iterator __position, _Args&&... __args)
	{
	  __glibcxx_check_insert(__position);
	  _Base_iterator __res = _Base::emplace(__position.base(),
						std::forward<_Args>(__args)...);
	  this->_M_invalidate_all();
	  return iterator(__res, this);
	}
#endif

      iterator
#if __cplusplus >= 201103L
      insert(const_iterator __position, const _Tp& __x)
#else
      insert(iterator __position, const _Tp& __x)
#endif
      {
	__glibcxx_check_insert(__position);
	_Base_iterator __res = _Base::insert(__position.base(), __x);
	this->_M_invalidate_all();
	return iterator(__res, this);
      }

#if __cplusplus >= 201103L
      iterator
      insert(const_iterator __position, _Tp&& __x)
      { return emplace(__position, std::move(__x)); }

      iterator
      insert(const_iterator __position, initializer_list<value_type> __l)
      {
	__glibcxx_check_insert(__position);
	_Base_iterator __res = _Base::insert(__position.base(), __l);
	this->_M_invalidate_all();
	return iterator(__res, this);
      }
#endif

#if __cplusplus >= 201103L
      iterator
      insert(const_iterator __position, size_type __n, const _Tp& __x)
      {
	__glibcxx_check_insert(__position);
	_Base_iterator __res = _Base::insert(__position.base(), __n, __x);
	this->_M_invalidate_all();
	return iterator(__res, this);
      }
#else
      void
      insert(iterator __position, size_type __n, const _Tp& __x)
      {
	__glibcxx_check_insert(__position);
	_Base::insert(__position.base(), __n, __x);
	this->_M_invalidate_all();
      }
#endif

#if __cplusplus >= 201103L
      template<class _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
	iterator
        insert(const_iterator __position,
	       _InputIterator __first, _InputIterator __last)
        {
	  __glibcxx_check_insert_range(__position, __first, __last);
	  _Base_iterator __res = _Base::insert(__position.base(),
					       __gnu_debug::__base(__first),
					       __gnu_debug::__base(__last));
	  this->_M_invalidate_all();
	  return iterator(__res, this);
	}
#else
      template<class _InputIterator>
        void
        insert(iterator __position,
	       _InputIterator __first, _InputIterator __last)
        {
	  __glibcxx_check_insert_range(__position, __first, __last);
	  _Base::insert(__position.base(), __gnu_debug::__base(__first),
					   __gnu_debug::__base(__last));
	  this->_M_invalidate_all();
	}
#endif

      void
      pop_front() _GLIBCXX_NOEXCEPT
      {
	__glibcxx_check_nonempty();
	this->_M_invalidate_if(_Equal(_Base::begin()));
	_Base::pop_front();
      }

      void
      pop_back() _GLIBCXX_NOEXCEPT
      {
	__glibcxx_check_nonempty();
	this->_M_invalidate_if(_Equal(--_Base::end()));
	_Base::pop_back();
      }

      iterator
#if __cplusplus >= 201103L
      erase(const_iterator __position)
#else
      erase(iterator __position)	
#endif
      {
	__glibcxx_check_erase(__position);
#if __cplusplus >= 201103L
	_Base_const_iterator __victim = __position.base();
#else
	_Base_iterator __victim = __position.base();
#endif
	if (__victim == _Base::begin() || __victim == _Base::end() - 1)
	  {
	    this->_M_invalidate_if(_Equal(__victim));
	    return iterator(_Base::erase(__victim), this);
	  }
	else
	  {
	    _Base_iterator __res = _Base::erase(__victim);
	    this->_M_invalidate_all();
	    return iterator(__res, this);
	  }
      }

      iterator
#if __cplusplus >= 201103L
      erase(const_iterator __first, const_iterator __last)
#else
      erase(iterator __first, iterator __last)
#endif
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 151. can't currently clear() empty container
	__glibcxx_check_erase_range(__first, __last);

	if (__first.base() == __last.base())
#if __cplusplus >= 201103L
	  return iterator(__first.base()._M_const_cast(), this);
#else
	  return __first;
#endif
        else if (__first.base() == _Base::begin()
		 || __last.base() == _Base::end())
	  {
	    this->_M_detach_singular();
	    for (_Base_const_iterator __position = __first.base();
		 __position != __last.base(); ++__position)
	      {
		this->_M_invalidate_if(_Equal(__position));
	      }
	    __try
	      {
		return iterator(_Base::erase(__first.base(), __last.base()),
				this);
	      }
	    __catch(...)
	      {
		this->_M_revalidate_singular();
		__throw_exception_again;
	      }
	  }
	else
	  {
	    _Base_iterator __res = _Base::erase(__first.base(),
						__last.base());
	    this->_M_invalidate_all();
	    return iterator(__res, this);
	  }
      }

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

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

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

      const _Base&
      _M_base() const _GLIBCXX_NOEXCEPT { 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
