// Profiling vector implementation -*- C++ -*-

// Copyright (C) 2009-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 along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.

/** @file profile/vector
 *  This file is a GNU profile extension to the Standard C++ Library.
 */

#ifndef _GLIBCXX_PROFILE_VECTOR
#define _GLIBCXX_PROFILE_VECTOR 1

#include <vector>
#include <utility>
#include <profile/base.h>
#include <profile/iterator_tracker.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __profile
{
  template<typename _Vector>
    class _Vector_profile_pre
    {
      _Vector&
      _M_conjure()
      { return *static_cast<_Vector*>(this); }

    public:
#if __cplusplus >= 201103L
      _Vector_profile_pre() = default;
      _Vector_profile_pre(const _Vector_profile_pre&) = default;
      _Vector_profile_pre(_Vector_profile_pre&&) = default;

      _Vector_profile_pre&
      operator=(const _Vector_profile_pre&)
      { _M_conjure()._M_profile_destruct(); }

      _Vector_profile_pre&
      operator=(_Vector_profile_pre&&) noexcept
      { _M_conjure()._M_profile_destruct(); }
#endif
    };

  template<typename _Vector>
    class _Vector_profile_post
    {
      _Vector&
      _M_conjure()
      { return *static_cast<_Vector*>(this); }

    protected:
      __gnu_profile::__container_size_info* _M_size_info;
      __gnu_profile::__vector2list_info* _M_vect2list_info;

      _Vector_profile_post() _GLIBCXX_NOEXCEPT
      { _M_profile_construct(); }

#if __cplusplus >= 201103L
      _Vector_profile_post(const _Vector_profile_post&) noexcept
      : _Vector_profile_post() { }
      _Vector_profile_post(_Vector_profile_post&& __other) noexcept
      : _Vector_profile_post()
      { _M_swap(__other); }

      _Vector_profile_post&
      operator=(const _Vector_profile_post&) noexcept
      { _M_profile_construct(); }

      _Vector_profile_post&
      operator=(_Vector_profile_post&& __other) noexcept
      {
	_M_swap(__other);
	__other._M_profile_construct();
      }
#endif

      ~_Vector_profile_post()
      { _M_conjure()._M_profile_destruct(); }

    public:
      void
      _M_profile_construct() _GLIBCXX_NOEXCEPT
      {
	_M_size_info =
	  __profcxx_vector_size_construct(_M_conjure().capacity());
	_M_vect2list_info = __profcxx_vector2list_construct();	
      }

      void
      _M_profile_destruct() _GLIBCXX_NOEXCEPT
      {
	__profcxx_vector2list_destruct(_M_vect2list_info);
	_M_vect2list_info = 0;
	__profcxx_vector_size_destruct(_M_size_info,
				       _M_conjure().capacity(),
				       _M_conjure().size());
	_M_size_info = 0;
      }

      void
      _M_swap(_Vector_profile_post& __other) _GLIBCXX_NOEXCEPT
      {
	std::swap(_M_size_info, __other._M_size_info);
	std::swap(_M_vect2list_info, __other._M_vect2list_info);
      }
    };

  template<typename _Tp,
	   typename _Allocator = std::allocator<_Tp> >
    class vector
    : public _Vector_profile_pre<vector<_Tp, _Allocator> >,
      public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
      public _Vector_profile_post<vector<_Tp, _Allocator> >
    {
      typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator>	_Base;

      typedef typename _Base::iterator			_Base_iterator;
      typedef typename _Base::const_iterator		_Base_const_iterator;

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

      typedef __iterator_tracker<_Base_iterator, vector>
							iterator;
      typedef __iterator_tracker<_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;

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

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

      // 23.2.4.1 construct/copy/destroy:

#if __cplusplus < 201103L
      vector()
      { }

      vector(const vector& __x)
      : _Base(__x) { }
#else
      vector() = default;
      vector(const vector&) = default;
      vector(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) { }

      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<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
#else
      template<typename _InputIterator>
#endif
	vector(_InputIterator __first, _InputIterator __last,
	       const _Allocator& __a = _Allocator())
	: _Base(__first, __last, __a) { }

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

#if __cplusplus >= 201103L
      vector(const _Base& __x, const _Allocator& __a)
      : _Base(__x, __a) { }

      vector(vector&& __x, const _Allocator& __a)
      : _Base(std::move(__x), __a) { }

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

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

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

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

      // 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:

#if __cplusplus >= 201103L
      void
      resize(size_type __sz)
      {
	__profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
	_M_profile_resize(this->capacity(), __sz);
	_Base::resize(__sz);
      }

      void
      resize(size_type __sz, const _Tp& __c)
      {
	__profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
	_M_profile_resize(this->capacity(), __sz);
	_Base::resize(__sz, __c);
      }
#else
      void
      resize(size_type __sz, _Tp __c = _Tp())
      {
	__profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
	_M_profile_resize(this->capacity(), __sz);
	_Base::resize(__sz, __c);
      }
#endif

      // element access:
      reference
      operator[](size_type __n) _GLIBCXX_NOEXCEPT
      {
	__profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
	return _M_base()[__n];
      }
      const_reference
      operator[](size_type __n) const _GLIBCXX_NOEXCEPT
      {
	__profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
	return _M_base()[__n];
      }

      // 23.2.4.3 modifiers:
      void
      push_back(const _Tp& __x)
      {
	size_type __old_size = this->capacity();
	_Base::push_back(__x);
	_M_profile_resize(__old_size, this->capacity());
      }

#if __cplusplus >= 201103L
      void
      push_back(_Tp&& __x)
      {
	size_type __old_size = this->capacity();
	_Base::push_back(std::move(__x));
	_M_profile_resize(__old_size, this->capacity());
      }

#endif

      iterator
#if __cplusplus >= 201103L
      insert(const_iterator __pos, const _Tp& __x)
#else
      insert(iterator __pos, const _Tp& __x)
#endif
      {
	__profcxx_vector2list_insert(this->_M_vect2list_info,
				     __pos.base() - _Base::begin(),
				     this->size());
	size_type __old_size = this->capacity();
	_Base_iterator __res = _Base::insert(__pos.base(), __x);
	_M_profile_resize(__old_size, this->capacity());
	return iterator(__res, this);
      }

#if __cplusplus >= 201103L
      iterator
      insert(const_iterator __pos, _Tp&& __x)
      {
	__profcxx_vector2list_insert(this->_M_vect2list_info,
				     __pos.base() - _Base::cbegin(),
				     this->size());
	size_type __old_size = this->capacity();
	_Base_iterator __res = _Base::insert(__pos.base(), __x);
	_M_profile_resize(__old_size, this->capacity());
	return iterator(__res, this);
      }

      template<typename... _Args>
	iterator
	emplace(const_iterator __pos, _Args&&... __args)
	{
	  _Base_iterator __res = _Base::emplace(__pos.base(),
						std::forward<_Args>(__args)...);
	  return iterator(__res, this);
	}

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

      void
      swap(vector& __x)
#if __cplusplus >= 201103L
	noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif
      {
	_Base::swap(__x);
	this->_M_swap(__x);
      }

#if __cplusplus >= 201103L
      iterator
      insert(const_iterator __pos, size_type __n, const _Tp& __x)
      {
	__profcxx_vector2list_insert(this->_M_vect2list_info,
				     __pos.base() - _Base::cbegin(),
				     this->size());
	size_type __old_size = this->capacity();
	_Base_iterator __res = _Base::insert(__pos, __n, __x);
	_M_profile_resize(__old_size, this->capacity());
	return iterator(__res, this);
      }
#else
      void
      insert(iterator __pos, size_type __n, const _Tp& __x)
      {
	__profcxx_vector2list_insert(this->_M_vect2list_info,
				     __pos.base() - _Base::begin(),
				     this->size());
	size_type __old_size = this->capacity();
	_Base::insert(__pos, __n, __x);
	_M_profile_resize(__old_size, this->capacity());
      }
#endif

#if __cplusplus >= 201103L
      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
	iterator
	insert(const_iterator __pos,
	       _InputIterator __first, _InputIterator __last)
	{
	  __profcxx_vector2list_insert(this->_M_vect2list_info,
				       __pos.base() - _Base::cbegin(),
				       this->size());
	  size_type __old_size = this->capacity();
	  _Base_iterator __res = _Base::insert(__pos, __first, __last);
	  _M_profile_resize(__old_size, this->capacity());
	  return iterator(__res, this);
	}
#else
      template<typename _InputIterator>
	void
	insert(iterator __pos,
	       _InputIterator __first, _InputIterator __last)
	{
	  __profcxx_vector2list_insert(this->_M_vect2list_info,
				       __pos.base() - _Base::begin(),
				       this->size());
	  size_type __old_size = this->capacity();
	  _Base::insert(__pos, __first, __last);
	  _M_profile_resize(__old_size, this->capacity());
	}
#endif

      iterator
#if __cplusplus >= 201103L
      erase(const_iterator __pos)
#else
      erase(iterator __pos)	
#endif
      { return iterator(_Base::erase(__pos.base()), this); }

      iterator
#if __cplusplus >= 201103L
      erase(const_iterator __first, const_iterator __last)
#else
      erase(iterator __first, iterator __last)
#endif
      { return iterator(_Base::erase(__first.base(), __last.base()), this); }

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

      inline void
      _M_profile_iterate(int __rewind = 0) const
      { __profcxx_vector2list_iterate(this->_M_vect2list_info, __rewind); }

    private:
      void _M_profile_resize(size_type __old_size, size_type __new_size)
      {
	if (__old_size < __new_size)
	  {
	    __profcxx_vector_size_resize(this->_M_size_info,
					 this->size(), __new_size);
	    __profcxx_vector2list_resize(this->_M_vect2list_info,
					 this->size(), __new_size);
	  }
      }
    };

  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 __profile

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

} // namespace std

#endif
