// Debugging vector implementation -*- C++ -*-

// Copyright (C) 2003-2016 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/vector
 *  This file is a GNU debug extension to the Standard C++ Library.
 */

#ifndef _GLIBCXX_DEBUG_VECTOR
#define _GLIBCXX_DEBUG_VECTOR 1

#include <vector>
#include <utility>
#include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h>

namespace __gnu_debug
{
  /** @brief Base class for Debug Mode vector.
   *
   * Adds information about the guaranteed capacity, which is useful for
   * detecting code which relies on non-portable implementation details of
   * the libstdc++ reallocation policy.
   */
  template<typename _SafeSequence,
	   typename _BaseSequence>
    class _Safe_vector
    {
      typedef typename _BaseSequence::size_type size_type;

      const _SafeSequence&
      _M_seq() const { return *static_cast<const _SafeSequence*>(this); }

    protected:
      _Safe_vector() _GLIBCXX_NOEXCEPT
	: _M_guaranteed_capacity(0)
      { _M_update_guaranteed_capacity(); }

      _Safe_vector(const _Safe_vector&) _GLIBCXX_NOEXCEPT
	: _M_guaranteed_capacity(0)
      { _M_update_guaranteed_capacity(); }

      _Safe_vector(size_type __n) _GLIBCXX_NOEXCEPT
	: _M_guaranteed_capacity(__n)
      { }

#if __cplusplus >= 201103L
      _Safe_vector(_Safe_vector&& __x) noexcept
	: _Safe_vector()
      { __x._M_guaranteed_capacity = 0; }

      _Safe_vector&
      operator=(const _Safe_vector&) noexcept
      {
	_M_update_guaranteed_capacity();
	return *this;
      }

      _Safe_vector&
      operator=(_Safe_vector&& __x) noexcept
      {
	_M_update_guaranteed_capacity();
	__x._M_guaranteed_capacity = 0;
	return *this;
      }
#endif

      size_type _M_guaranteed_capacity;

      bool
      _M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT
      { return __elements > _M_seq().capacity(); }

      void
      _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT
      {
	if (_M_seq().size() > _M_guaranteed_capacity)
	  _M_guaranteed_capacity = _M_seq().size();
      }
    };
}

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __debug
{
  /// Class std::vector with safety/checking/debug instrumentation.
  template<typename _Tp,
	   typename _Allocator = std::allocator<_Tp> >
    class vector
    : public __gnu_debug::_Safe_container<
	vector<_Tp, _Allocator>, _Allocator, __gnu_debug::_Safe_sequence>,
      public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
      public __gnu_debug::_Safe_vector<
	vector<_Tp, _Allocator>,
	_GLIBCXX_STD_C::vector<_Tp, _Allocator> >
    {
      typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator>		_Base;
      typedef __gnu_debug::_Safe_container<
	vector, _Allocator, __gnu_debug::_Safe_sequence>	_Safe;
      typedef __gnu_debug::_Safe_vector<vector, _Base>		_Safe_vector;

      typedef typename _Base::iterator		_Base_iterator;
      typedef typename _Base::const_iterator	_Base_const_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, vector>				iterator;
      typedef __gnu_debug::_Safe_iterator<
	_Base_const_iterator, vector>			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.4.1 construct/copy/destroy:

#if __cplusplus < 201103L
      vector() _GLIBCXX_NOEXCEPT
      : _Base() { }
#else
      vector() = default;
#endif

      explicit
      vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
      : _Base(__a) { }

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

      vector(size_type __n, const _Tp& __value,
	     const _Allocator& __a = _Allocator())
      : _Base(__n, __value, __a) { }
#else
      explicit
      vector(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
	vector(_InputIterator __first, _InputIterator __last,
	       const _Allocator& __a = _Allocator())
	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
								     __last)),
		__gnu_debug::__base(__last), __a) { }

#if __cplusplus < 201103L
      vector(const vector& __x)
      : _Base(__x) { }

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

      vector(const vector& __x, const allocator_type& __a)
      : _Base(__x, __a) { }

      vector(vector&& __x, const allocator_type& __a)
      : _Safe(std::move(__x._M_safe()), __a),
	_Base(std::move(__x._M_base()), __a),
	_Safe_vector(std::move(__x)) { }

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

      ~vector() = default;
#endif

      /// Construction from a normal-mode vector
      vector(const _Base& __x)
      : _Base(__x) { }

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

      vector&
      operator=(vector&&) = default;

      vector&
      operator=(initializer_list<value_type> __l)
      {
	_M_base() = __l;
	this->_M_invalidate_all();
	this->_M_update_guaranteed_capacity();
	return *this;
      }
#endif

#if __cplusplus >= 201103L
      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
#else
      template<typename _InputIterator>
#endif
	void
	assign(_InputIterator __first, _InputIterator __last)
	{
	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
	  __glibcxx_check_valid_range2(__first, __last, __dist);

	  if (__dist.second >= __gnu_debug::__dp_sign)
	    _Base::assign(__gnu_debug::__unsafe(__first),
			  __gnu_debug::__unsafe(__last));
	  else
	    _Base::assign(__first, __last);

	  this->_M_invalidate_all();
	  this->_M_update_guaranteed_capacity();
	}

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

#if __cplusplus >= 201103L
      void
      assign(initializer_list<value_type> __l)
      {
	_Base::assign(__l);
	this->_M_invalidate_all();
	this->_M_update_guaranteed_capacity();
      }
#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

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

#if __cplusplus >= 201103L
      void
      resize(size_type __sz)
      {
	bool __realloc = this->_M_requires_reallocation(__sz);
	if (__sz < this->size())
	  this->_M_invalidate_after_nth(__sz);
	_Base::resize(__sz);
	if (__realloc)
	  this->_M_invalidate_all();
	this->_M_update_guaranteed_capacity();
      }

      void
      resize(size_type __sz, const _Tp& __c)
      {
	bool __realloc = this->_M_requires_reallocation(__sz);
	if (__sz < this->size())
	  this->_M_invalidate_after_nth(__sz);
	_Base::resize(__sz, __c);
	if (__realloc)
	  this->_M_invalidate_all();
	this->_M_update_guaranteed_capacity();
      }
#else
      void
      resize(size_type __sz, _Tp __c = _Tp())
      {
	bool __realloc = this->_M_requires_reallocation(__sz);
	if (__sz < this->size())
	  this->_M_invalidate_after_nth(__sz);
	_Base::resize(__sz, __c);
	if (__realloc)
	  this->_M_invalidate_all();
	this->_M_update_guaranteed_capacity();
      }
#endif

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

      size_type
      capacity() const _GLIBCXX_NOEXCEPT
      {
#ifdef _GLIBCXX_DEBUG_PEDANTIC
	return this->_M_guaranteed_capacity;
#else
	return _Base::capacity();
#endif
      }

      using _Base::empty;

      void
      reserve(size_type __n)
      {
	bool __realloc = this->_M_requires_reallocation(__n);
	_Base::reserve(__n);
	if (__n > this->_M_guaranteed_capacity)
	  this->_M_guaranteed_capacity = __n;
	if (__realloc)
	  this->_M_invalidate_all();
      }

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

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // DR 464. Suggestion for new member functions in standard containers.
      using _Base::data;

      // 23.2.4.3 modifiers:
      void
      push_back(const _Tp& __x)
      {
	bool __realloc = this->_M_requires_reallocation(this->size() + 1);
	_Base::push_back(__x);
	if (__realloc)
	  this->_M_invalidate_all();
	this->_M_update_guaranteed_capacity();
      }

#if __cplusplus >= 201103L
      template<typename _Up = _Tp>
	typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
					void>::__type
	push_back(_Tp&& __x)
	{ emplace_back(std::move(__x)); }

      template<typename... _Args>
	void
	emplace_back(_Args&&... __args)
	{
	  bool __realloc = this->_M_requires_reallocation(this->size() + 1);
	  _Base::emplace_back(std::forward<_Args>(__args)...);
	  if (__realloc)
	    this->_M_invalidate_all();
	  this->_M_update_guaranteed_capacity();
	}
#endif

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

#if __cplusplus >= 201103L
      template<typename... _Args>
	iterator
	emplace(const_iterator __position, _Args&&... __args)
	{
	  __glibcxx_check_insert(__position);
	  bool __realloc = this->_M_requires_reallocation(this->size() + 1);
	  difference_type __offset = __position.base() - _Base::begin();
	  _Base_iterator __res = _Base::emplace(__position.base(),
						std::forward<_Args>(__args)...);
	  if (__realloc)
	    this->_M_invalidate_all();
	  else
	    this->_M_invalidate_after_nth(__offset);
	  this->_M_update_guaranteed_capacity();
	  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);
	bool __realloc = this->_M_requires_reallocation(this->size() + 1);
	difference_type __offset = __position.base() - _Base::begin();
	_Base_iterator __res = _Base::insert(__position.base(), __x);
	if (__realloc)
	  this->_M_invalidate_all();
	else
	  this->_M_invalidate_after_nth(__offset);
	this->_M_update_guaranteed_capacity();
	return iterator(__res, this);
      }

#if __cplusplus >= 201103L
      template<typename _Up = _Tp>
	typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
					iterator>::__type
	insert(const_iterator __position, _Tp&& __x)
	{ return emplace(__position, std::move(__x)); }

      iterator
      insert(const_iterator __position, initializer_list<value_type> __l)
      { return this->insert(__position, __l.begin(), __l.end()); }
#endif

#if __cplusplus >= 201103L
      iterator
      insert(const_iterator __position, size_type __n, const _Tp& __x)
      {
	__glibcxx_check_insert(__position);
	bool __realloc = this->_M_requires_reallocation(this->size() + __n);
	difference_type __offset = __position.base() - _Base::cbegin();
	_Base_iterator __res = _Base::insert(__position.base(), __n, __x);
	if (__realloc)
	  this->_M_invalidate_all();
	else
	  this->_M_invalidate_after_nth(__offset);
	this->_M_update_guaranteed_capacity();
	return iterator(__res, this);
      }
#else
      void
      insert(iterator __position, size_type __n, const _Tp& __x)
      {
	__glibcxx_check_insert(__position);
	bool __realloc = this->_M_requires_reallocation(this->size() + __n);
	difference_type __offset = __position.base() - _Base::begin();
	_Base::insert(__position.base(), __n, __x);
	if (__realloc)
	  this->_M_invalidate_all();
	else
	  this->_M_invalidate_after_nth(__offset);
	this->_M_update_guaranteed_capacity();
      }
#endif

#if __cplusplus >= 201103L
      template<class _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
	iterator
	insert(const_iterator __position,
	       _InputIterator __first, _InputIterator __last)
	{
	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
	  __glibcxx_check_insert_range(__position, __first, __last, __dist);

	  /* Hard to guess if invalidation will occur, because __last
	     - __first can't be calculated in all cases, so we just
	     punt here by checking if it did occur. */
	  _Base_iterator __old_begin = _M_base().begin();
	  difference_type __offset = __position.base() - _Base::cbegin();
	  _Base_iterator __res;
	  if (__dist.second >= __gnu_debug::__dp_sign)
	    __res = _Base::insert(__position.base(),
				  __gnu_debug::__unsafe(__first),
				  __gnu_debug::__unsafe(__last));
	  else
	    __res = _Base::insert(__position.base(), __first, __last);

	  if (_M_base().begin() != __old_begin)
	    this->_M_invalidate_all();
	  else
	    this->_M_invalidate_after_nth(__offset);
	  this->_M_update_guaranteed_capacity();
	  return iterator(__res, this);
	}
#else
      template<class _InputIterator>
	void
	insert(iterator __position,
	       _InputIterator __first, _InputIterator __last)
	{
	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
	  __glibcxx_check_insert_range(__position, __first, __last, __dist);

	  /* Hard to guess if invalidation will occur, because __last
	     - __first can't be calculated in all cases, so we just
	     punt here by checking if it did occur. */
	  _Base_iterator __old_begin = _M_base().begin();
	  difference_type __offset = __position.base() - _Base::begin();
	  if (__dist.second >= __gnu_debug::__dp_sign)
	    _Base::insert(__position.base(), __gnu_debug::__unsafe(__first),
					     __gnu_debug::__unsafe(__last));
	  else
	    _Base::insert(__position.base(), __first, __last);

	  if (_M_base().begin() != __old_begin)
	    this->_M_invalidate_all();
	  else
	    this->_M_invalidate_after_nth(__offset);
	  this->_M_update_guaranteed_capacity();
	}
#endif

      iterator
#if __cplusplus >= 201103L
      erase(const_iterator __position)
#else
      erase(iterator __position)
#endif
      {
	__glibcxx_check_erase(__position);
	difference_type __offset = __position.base() - _Base::begin();
	_Base_iterator __res = _Base::erase(__position.base());
	this->_M_invalidate_after_nth(__offset);
	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())
	  {
	    difference_type __offset = __first.base() - _Base::begin();
	    _Base_iterator __res = _Base::erase(__first.base(),
						__last.base());
	    this->_M_invalidate_after_nth(__offset);
	    return iterator(__res, this);
	  }
	else
#if __cplusplus >= 201103L
	  return begin() + (__first.base() - cbegin().base());
#else
	  return __first;
#endif
      }

      void
      swap(vector& __x)
      _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
      {
	_Safe::_M_swap(__x);
	_Base::swap(__x);
	std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
      }

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

    private:
      void
      _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT
      {
	typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
	this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
      }
    };

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

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

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

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

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

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

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

} // namespace __debug

#if __cplusplus >= 201103L
  // DR 1182.
  /// std::hash specialization for vector<bool>.
  template<typename _Alloc>
    struct hash<__debug::vector<bool, _Alloc>>
    : public __hash_base<size_t, __debug::vector<bool, _Alloc>>
    {
      size_t
      operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept
      { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b); }
    };
#endif

} // namespace std

namespace __gnu_debug
{
  template<typename _Tp, typename _Alloc>
    struct _Is_contiguous_sequence<std::__debug::vector<_Tp, _Alloc> >
    : std::__true_type
    { };

  template<typename _Alloc>
    struct _Is_contiguous_sequence<std::__debug::vector<bool, _Alloc> >
    : std::__false_type
    { };
}

#endif
