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

// Copyright (C) 2003-2015 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_container.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 __gnu_debug::_Safe_container<
	deque<_Tp, _Allocator>, _Allocator,
	__gnu_debug::_Safe_sequence>,
      public _GLIBCXX_STD_C::deque<_Tp, _Allocator>
    {
      typedef  _GLIBCXX_STD_C::deque<_Tp, _Allocator>		_Base;
      typedef __gnu_debug::_Safe_container<
	deque, _Allocator, __gnu_debug::_Safe_sequence>	_Safe;

      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:

#if __cplusplus < 201103L
      deque()
      : _Base() { }

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

      ~deque() { }
#else
      deque() = default;
      deque(const deque&) = default;
      deque(deque&&) = default;

      deque(const deque& __d, const _Allocator& __a)
      : _Base(__d, __a) { }

      deque(deque&& __d, const _Allocator& __a)
      : _Safe(std::move(__d)), _Base(std::move(__d), __a) { }

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

      ~deque() = default;
#endif

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

#if __cplusplus >= 201103L
      explicit
      deque(size_type __n, const _Allocator& __a = _Allocator())
      : _Base(__n, __a) { }

      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 _Base& __x)
      : _Base(__x) { }

#if __cplusplus < 201103L
      deque&
      operator=(const deque& __x)
      {
	this->_M_safe() = __x;
	_M_base() = __x;
	return *this;
      }
#else
      deque&
      operator=(const deque&) = default;

      deque&
      operator=(deque&&) = default;

      deque&
      operator=(initializer_list<value_type> __l)
      {
	_M_base() = __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)
#if __cplusplus >= 201103L
	noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif
      {
	_Safe::_M_swap(__x);
	_Base::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
