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

// Copyright (C) 2009-2013 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 _Tp,
	   typename _Allocator = std::allocator<_Tp> >
    class vector
    : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>
    {
      typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;

#if __cplusplus >= 201103L
      typedef __gnu_cxx::__alloc_traits<_Allocator>  _Alloc_traits;
#endif

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

      typedef __iterator_tracker<typename _Base::iterator, vector>
                                                    iterator;
      typedef __iterator_tracker<typename _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:
      explicit
      vector(const _Allocator& __a = _Allocator())
      : _Base(__a)
      {
        __profcxx_vector_construct(this, this->capacity());
        __profcxx_vector_construct2(this);
      }

#if __cplusplus >= 201103L
      explicit
      vector(size_type __n, const _Allocator& __a = _Allocator())
      : _Base(__n, __a)
      {
        __profcxx_vector_construct(this, this->capacity());
        __profcxx_vector_construct2(this);
      }

      vector(size_type __n, const _Tp& __value,
	     const _Allocator& __a = _Allocator())
      :  _Base(__n, __value, __a)
      {
        __profcxx_vector_construct(this, this->capacity());
        __profcxx_vector_construct2(this);
      }
#else
      explicit
      vector(size_type __n, const _Tp& __value = _Tp(),
	     const _Allocator& __a = _Allocator())
      : _Base(__n, __value, __a)
      {
        __profcxx_vector_construct(this, this->capacity());
        __profcxx_vector_construct2(this);
      }
#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)
        {
	  __profcxx_vector_construct(this, this->capacity());
	  __profcxx_vector_construct2(this);
	}

      vector(const vector& __x)
      : _Base(__x) 
      {
        __profcxx_vector_construct(this, this->capacity());
        __profcxx_vector_construct2(this);
      }

      /// Construction from a release-mode vector
      vector(const _Base& __x)
      : _Base(__x) 
      { 
        __profcxx_vector_construct(this, this->capacity());
        __profcxx_vector_construct2(this);
      }

#if __cplusplus >= 201103L
      vector(vector&& __x) noexcept
      : _Base(std::move(__x))
      {
        __profcxx_vector_construct(this, this->capacity());
        __profcxx_vector_construct2(this);
      }

      vector(const _Base& __x, const _Allocator& __a)
      : _Base(__x, __a)
      { 
        __profcxx_vector_construct(this, this->capacity());
        __profcxx_vector_construct2(this);
      }

      vector(vector&& __x, const _Allocator& __a) noexcept
      : _Base(std::move(__x), __a)
      {
        __profcxx_vector_construct(this, this->capacity());
        __profcxx_vector_construct2(this);
      }

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

      ~vector() _GLIBCXX_NOEXCEPT
      {
        __profcxx_vector_destruct(this, this->capacity(), this->size());
        __profcxx_vector_destruct2(this);
      }

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

#if __cplusplus >= 201103L
      vector&
      operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
      {
	__profcxx_vector_destruct(this, this->capacity(), this->size());
	__profcxx_vector_destruct2(this);
	static_cast<_Base&>(*this) = std::move(__x);
	return *this;
      }

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

      using _Base::assign;
      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)
      {
        __profcxx_vector_invalid_operator(this);
        _M_profile_resize(this, this->capacity(), __sz);
        _Base::resize(__sz);
      }

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

#if __cplusplus >= 201103L
      using _Base::shrink_to_fit;
#endif

      using _Base::empty;

      // element access:
      reference
      operator[](size_type __n)
      {
        __profcxx_vector_invalid_operator(this);
        return _M_base()[__n];
      }
      const_reference
      operator[](size_type __n) const
      {
        __profcxx_vector_invalid_operator(this);
        return _M_base()[__n];
      }

      using _Base::at;

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

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

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

      const_reference
      back() const
      {
	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)
      {
        size_type __old_size = this->capacity();
	_Base::push_back(__x);
        _M_profile_resize(this, __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(this, __old_size, this->capacity());
      }

#endif

      iterator
      insert(iterator __position, const _Tp& __x)
      {
        __profcxx_vector_insert(this, __position.base() - _Base::begin(),
                                this->size());
        size_type __old_size = this->capacity();
	typename _Base::iterator __res = _Base::insert(__position.base(), __x);
        _M_profile_resize(this, __old_size, this->capacity());
	return iterator(__res, this);
      }

#if __cplusplus >= 201103L
      iterator
      insert(iterator __position, _Tp&& __x)
      {
        __profcxx_vector_insert(this, __position.base() - _Base::begin(),
                                this->size());
        size_type __old_size = this->capacity();
	typename _Base::iterator __res = _Base::insert(__position.base(), __x);
        _M_profile_resize(this, __old_size, this->capacity());
	return iterator(__res, this);
      }

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

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

#if __cplusplus >= 201103L
      void
      swap(vector&& __x)
      {
        _Base::swap(__x);
      }
#endif

      void
      swap(vector& __x)
#if __cplusplus >= 201103L
			noexcept(_Alloc_traits::_S_nothrow_swap())
#endif
      {
        _Base::swap(__x);
      }

      void
      insert(iterator __position, size_type __n, const _Tp& __x)
      {
        __profcxx_vector_insert(this, __position.base() - _Base::begin(),
                                this->size());
        size_type __old_size = this->capacity();
        _Base::insert(__position, __n, __x);
        _M_profile_resize(this, __old_size, this->capacity());
      }

#if __cplusplus >= 201103L
      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
#else
      template<typename _InputIterator>
#endif
      void
      insert(iterator __position,
             _InputIterator __first, _InputIterator __last)
      {
        __profcxx_vector_insert(this, __position.base()-_Base::begin(),
                                this->size());
        size_type __old_size = this->capacity();
        _Base::insert(__position, __first, __last);
        _M_profile_resize(this, __old_size, this->capacity());
      }


      iterator
      erase(iterator __position)
      {
	typename _Base::iterator __res = _Base::erase(__position.base());
	return iterator(__res, this);
      }

      iterator
      erase(iterator __first, iterator __last)
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 151. can't currently clear() empty container
	typename _Base::iterator __res = _Base::erase(__first.base(),
                                                      __last.base());
	return iterator(__res, this);
      }

      void
      clear() _GLIBCXX_NOEXCEPT
      {
        __profcxx_vector_destruct(this, this->capacity(), this->size());
        __profcxx_vector_destruct2(this);
        _Base::clear();
      }

      inline void _M_profile_find() const 
      { 
        __profcxx_vector_find(this, size()); 
      }

      inline void _M_profile_iterate(int __rewind = 0) const 
      { 
        __profcxx_vector_iterate(this); 
      }

    private:
      void _M_profile_resize(void* obj, size_type __old_size, 
                             size_type __new_size)
      {
        if (__old_size < __new_size) {
          __profcxx_vector_resize(this, this->size(), __new_size);
          __profcxx_vector_resize2(this, 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)
    { __lhs.swap(__rhs); }

#if __cplusplus >= 201103L
  template<typename _Tp, typename _Alloc>
    inline void
    swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
    { __lhs.swap(__rhs); }

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

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