// Profiling list implementation -*- C++ -*-

// Copyright (C) 2009, 2010 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 profile/list
 *  This file is a GNU profile extension to the Standard C++ Library.
 */

#ifndef _GLIBCXX_PROFILE_LIST
#define _GLIBCXX_PROFILE_LIST 1

#include <list>
#include <profile/base.h> 
#include <profile/iterator_tracker.h> 

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __profile
{
  /** @brief List wrapper with performance instrumentation.  */
template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
    class list
    : public _GLIBCXX_STD_C::list<_Tp, _Allocator>
    {
      typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;

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

      typedef __iterator_tracker<typename _Base::iterator, list>        
				                    iterator;
      typedef __iterator_tracker<typename _Base::const_iterator, list>  
                                                    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.2.1 construct/copy/destroy:
      explicit
      list(const _Allocator& __a = _Allocator())
      : _Base(__a) 
      { 
        __profcxx_list_construct(this); 	// list2slist
        __profcxx_list_construct2(this); 	// list2vector
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      explicit
      list(size_type __n)
      : _Base(__n) 
      { 
        __profcxx_list_construct(this); 
        __profcxx_list_construct2(this); 
      }

      list(size_type __n, const _Tp& __value,
	   const _Allocator& __a = _Allocator())
      : _Base(__n, __value, __a) 
      { 
        __profcxx_list_construct(this); 
        __profcxx_list_construct2(this); 
      }
#else
      explicit
      list(size_type __n, const _Tp& __value = _Tp(),
	   const _Allocator& __a = _Allocator())
      : _Base(__n, __value, __a) 
      { 
        __profcxx_list_construct(this); 
        __profcxx_list_construct2(this); 
      }
#endif

      template<class _InputIterator>
      list(_InputIterator __first, _InputIterator __last,
	   const _Allocator& __a = _Allocator())
      : _Base(__first, __last, __a)
      {	 
        __profcxx_list_construct(this); 
        __profcxx_list_construct2(this); 
      }

      list(const list& __x)
      : _Base(__x) 
      { 
        __profcxx_list_construct(this); 
        __profcxx_list_construct2(this); 
      }

      list(const _Base& __x)
      : _Base(__x) 
      { 	
        __profcxx_list_construct(this); 
        __profcxx_list_construct2(this); 
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      list(list&& __x)
      : _Base(std::move(__x))
      { 
        __profcxx_list_construct(this); 
        __profcxx_list_construct2(this); 
      }

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

      ~list() { 
        __profcxx_list_destruct(this); 
        __profcxx_list_destruct2(this); 
      }

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

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      list&
      operator=(list&& __x)
      {
	// NB: DR 1204.
	// NB: DR 675.
	this->clear();
	this->swap(__x);
	return *this;
      }

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

      void
      assign(initializer_list<value_type> __l)
      {	_Base::assign(__l); }
#endif

      template<class _InputIterator>
        void
        assign(_InputIterator __first, _InputIterator __last)
        { _Base::assign(__first, __last); }

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

      using _Base::get_allocator;

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

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

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

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

      reverse_iterator
      rbegin()
      {
        __profcxx_list_rewind(this);
        return reverse_iterator(end());
      }

      const_reverse_iterator
      rbegin() const
      { 
        __profcxx_list_rewind(this);
        return const_reverse_iterator(end());
      }

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

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

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      const_iterator
      cbegin() const
      { return const_iterator(_Base::begin(), this); }

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

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

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

      // 23.2.2.2 capacity:
      using _Base::empty;
      using _Base::size;
      using _Base::max_size;

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      void
      resize(size_type __sz)
      { _Base::resize(__sz); }

      void
      resize(size_type __sz, const _Tp& __c)
      { _Base::resize(__sz, __c); }
#else
      void
      resize(size_type __sz, _Tp __c = _Tp())
      { _Base::resize(__sz, __c); }
#endif

      // element access:
      reference
      front()
      { return _Base::front(); }

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

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

      const_reference
      back() const
      {
        __profcxx_list_rewind(this);
	return _Base::back();
      }

      // 23.2.2.3 modifiers:
      void
      push_front(const value_type& __x)
      {
        __profcxx_list_invalid_operator(this);
        __profcxx_list_operation(this);
        _Base::push_front(__x);
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      using _Base::emplace_front;
#endif

      void
      pop_front()
      {
        __profcxx_list_operation(this);
	_Base::pop_front();
      }

      using _Base::push_back;

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      using _Base::emplace_back;
#endif

      void
      pop_back()
      {
	iterator __victim = end();
	--__victim;
	_Base::pop_back();
        __profcxx_list_rewind(this);
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      template<typename... _Args>
        iterator
        emplace(iterator __position, _Args&&... __args)
	{
	  return iterator(_Base::emplace(__position.base(),
                                         std::forward<_Args>(__args)...));
	}
#endif

      iterator
      insert(iterator __position, const _Tp& __x)
      {
        _M_profile_insert(this, __position, size());
        return iterator(_Base::insert(__position.base(), __x), this);
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      iterator
      insert(iterator __position, _Tp&& __x)
      { 
        _M_profile_insert(this, __position, size());
        return iterator(_Base::emplace(__position.base(), std::move(__x)),
                        this); 
      }

      void
      insert(iterator __position, initializer_list<value_type> __l)
      {
        _M_profile_insert(this, __position, size());
        _Base::insert(__position.base(), __l);
      }
#endif

      void
      insert(iterator __position, size_type __n, const _Tp& __x)
      {
        _M_profile_insert(this, __position, size());
	_Base::insert(__position.base(), __n, __x);
      }

      template<class _InputIterator>
        void
        insert(iterator __position, _InputIterator __first,
	       _InputIterator __last)
      {
        _M_profile_insert(this, __position, size());
        _Base::insert(__position.base(), __first, __last);
      }

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

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

      void
      swap(list& __x)
      {	_Base::swap(__x); }

      void
      clear()
      {	_Base::clear(); }

      // 23.2.2.4 list operations:
      void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
      splice(iterator __position, list&& __x)
#else
      splice(iterator __position, list& __x)
#endif
      { this->splice(__position, _GLIBCXX_MOVE(__x), __x.begin(), __x.end()); }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      void
      splice(iterator __position, list& __x)
      { this->splice(__position, std::move(__x)); }
#endif

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      void
      splice(iterator __position, list& __x, iterator __i)
      { this->splice(__position, std::move(__x), __i); }
#endif

      void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
      splice(iterator __position, list&& __x, iterator __i)
#else
      splice(iterator __position, list& __x, iterator __i)
#endif
      {
	// We used to perform the splice_alloc check:  not anymore, redundant
	// after implementing the relevant bits of N1599.

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
		      __i.base());
      }

      void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
      splice(iterator __position, list&& __x, iterator __first,
	     iterator __last)
#else
      splice(iterator __position, list& __x, iterator __first,
	     iterator __last)
#endif
      {
	// We used to perform the splice_alloc check:  not anymore, redundant
	// after implementing the relevant bits of N1599.

	_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
		      __first.base(), __last.base());
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      void
      splice(iterator __position, list& __x, iterator __first, iterator __last)
      { this->splice(__position, std::move(__x), __first, __last); }
#endif

      void
      remove(const _Tp& __value)
      {
	for (iterator __x = begin(); __x != end(); )
	  {
	    if (*__x == __value)
	      __x = erase(__x);
	    else
	      ++__x;
	  }
      }

      template<class _Predicate>
        void
        remove_if(_Predicate __pred)
        {
	  for (iterator __x = begin(); __x != end(); )
	    {
              __profcxx_list_operation(this);
	      if (__pred(*__x))
		__x = erase(__x);
	      else
		++__x;
	    }
	}

      void
      unique()
      {
	iterator __first = begin();
	iterator __last = end();
	if (__first == __last)
	  return;
	iterator __next = __first;
	while (++__next != __last)
	  {
            __profcxx_list_operation(this);
	    if (*__first == *__next)
	      erase(__next);
	    else
	      __first = __next;
	    __next = __first;
	  }
      }

      template<class _BinaryPredicate>
        void
        unique(_BinaryPredicate __binary_pred)
        {
	  iterator __first = begin();
	  iterator __last = end();
	  if (__first == __last)
	    return;
	  iterator __next = __first;
	  while (++__next != __last)
	    {
              __profcxx_list_operation(this);
	      if (__binary_pred(*__first, *__next))
		erase(__next);
	      else
		__first = __next;
	      __next = __first;
	    }
	}

      void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
      merge(list&& __x)
#else
      merge(list& __x)
#endif
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 300. list::merge() specification incomplete
	if (this != &__x)
	  { _Base::merge(_GLIBCXX_MOVE(__x._M_base())); }
      }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      void
      merge(list& __x)
      { this->merge(std::move(__x)); }
#endif

      template<class _Compare>
        void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
        merge(list&& __x, _Compare __comp)
#else
        merge(list& __x, _Compare __comp)
#endif
        {
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 300. list::merge() specification incomplete
	  if (this != &__x)
	    { _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp); }
	}

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      template<typename _Compare>
        void
        merge(list& __x, _Compare __comp)
        { this->merge(std::move(__x), __comp); }
#endif

      void
      sort() { _Base::sort(); }

      template<typename _StrictWeakOrdering>
        void
        sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }

      using _Base::reverse;

      _Base&
      _M_base()       { return *this; }

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

      inline void _M_profile_find() const 
      { }

      inline void _M_profile_iterate(int __rewind = 0) const 
      {
        __profcxx_list_operation(this);
        __profcxx_list_iterate(this); 
        if (__rewind)
          __profcxx_list_rewind(this);
      }

    private:
      size_type _M_profile_insert(void* obj, iterator __pos, size_type __size)
      {
        size_type __shift = 0;
        typename _Base::iterator __it = __pos.base();
        for ( ; __it!=_Base::end(); __it++)
          __shift++;
        __profcxx_list_rewind(this);
        __profcxx_list_operation(this);
        __profcxx_list_insert(this, __shift, __size);
      }
    };

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

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

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

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

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

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

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

} // namespace __profile
} // namespace std

#endif
