// Profiling unordered_map/unordered_multimap implementation -*- C++ -*-

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

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

#ifndef _GLIBCXX_PROFILE_UNORDERED_MAP
#define _GLIBCXX_PROFILE_UNORDERED_MAP 1

#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
# include <unordered_map>

#include <profile/base.h>
#include <profile/unordered_base.h>

#define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
#define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __profile
{
  /// Class std::unordered_map wrapper with performance instrumentation.
  template<typename _Key, typename _Tp,
	   typename _Hash = std::hash<_Key>,
	   typename _Pred = std::equal_to<_Key>,
	   typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
    class unordered_map
    : public _GLIBCXX_STD_BASE,
      public _Unordered_profile<unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
				true>
    {
      typedef typename _GLIBCXX_STD_BASE _Base;

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

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

    public:
      typedef typename _Base::size_type		size_type;
      typedef typename _Base::hasher		hasher;
      typedef typename _Base::key_equal		key_equal;
      typedef typename _Base::allocator_type	allocator_type;
      typedef typename _Base::key_type		key_type;
      typedef typename _Base::value_type	value_type;
      typedef typename _Base::difference_type	difference_type;
      typedef typename _Base::reference		reference;
      typedef typename _Base::const_reference	const_reference;
      typedef typename _Base::mapped_type	mapped_type;

      typedef typename _Base::iterator		iterator;
      typedef typename _Base::const_iterator	const_iterator;

      unordered_map() = default;

      explicit
      unordered_map(size_type __n,
		    const hasher& __hf = hasher(),
		    const key_equal& __eql = key_equal(),
		    const allocator_type& __a = allocator_type())
      : _Base(__n, __hf, __eql, __a) { }

      template<typename _InputIterator>
	unordered_map(_InputIterator __f, _InputIterator __l,
		      size_type __n = 0,
		      const hasher& __hf = hasher(),
		      const key_equal& __eql = key_equal(),
		      const allocator_type& __a = allocator_type())
	: _Base(__f, __l, __n, __hf, __eql, __a) { }

      unordered_map(const unordered_map&) = default;

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

      unordered_map(unordered_map&&) = default;

      explicit
      unordered_map(const allocator_type& __a)
      : _Base(__a) { }

      unordered_map(const unordered_map& __umap,
		    const allocator_type& __a)
      : _Base(__umap, __a) { }

      unordered_map(unordered_map&& __umap,
		    const allocator_type& __a)
      : _Base(std::move(__umap._M_base()), __a) { }

      unordered_map(initializer_list<value_type> __l,
		    size_type __n = 0,
		    const hasher& __hf = hasher(),
		    const key_equal& __eql = key_equal(),
		    const allocator_type& __a = allocator_type())
      : _Base(__l, __n, __hf, __eql, __a) { }

      unordered_map(size_type __n, const allocator_type& __a)
      : unordered_map(__n, hasher(), key_equal(), __a)
      { }

      unordered_map(size_type __n, const hasher& __hf,
		    const allocator_type& __a)
      : unordered_map(__n, __hf, key_equal(), __a)
      { }

      template<typename _InputIterator>
	unordered_map(_InputIterator __first, _InputIterator __last,
		      size_type __n,
		      const allocator_type& __a)
	  : unordered_map(__first, __last, __n, hasher(), key_equal(), __a)
	{ }

      template<typename _InputIterator>
	unordered_map(_InputIterator __first, _InputIterator __last,
		      size_type __n, const hasher& __hf,
		      const allocator_type& __a)
	  : unordered_map(__first, __last, __n, __hf, key_equal(), __a)
	{ }

      unordered_map(initializer_list<value_type> __l,
		    size_type __n,
		    const allocator_type& __a)
	: unordered_map(__l, __n, hasher(), key_equal(), __a)
      { }

      unordered_map(initializer_list<value_type> __l,
		    size_type __n, const hasher& __hf,
		    const allocator_type& __a)
	: unordered_map(__l, __n, __hf, key_equal(), __a)
      { }

      unordered_map&
      operator=(const unordered_map&) = default;

      unordered_map&
      operator=(unordered_map&&) = default;

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

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

      template<typename... _Args>
	std::pair<iterator, bool>
	emplace(_Args&&... __args)
	{
	  size_type __old_size = _Base::bucket_count();
	  std::pair<iterator, bool> __res
	    = _Base::emplace(std::forward<_Args>(__args)...);
	  this->_M_profile_resize(__old_size);
	  return __res;
	}

      template<typename... _Args>
	iterator
	emplace_hint(const_iterator __it, _Args&&... __args)
	{
	  size_type __old_size = _Base::bucket_count();
	  iterator __res
	    = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
	  this->_M_profile_resize(__old_size);
	  return __res;
	}

      void
      insert(std::initializer_list<value_type> __l)
      {
	size_type __old_size = _Base::bucket_count();
	_Base::insert(__l);
	this->_M_profile_resize(__old_size);
      }

      std::pair<iterator, bool>
      insert(const value_type& __obj)
      {
	size_type __old_size = _Base::bucket_count();
	std::pair<iterator, bool> __res = _Base::insert(__obj);
	this->_M_profile_resize(__old_size);
	return __res;
      }

      iterator
      insert(const_iterator __iter, const value_type& __v)
      {
	size_type __old_size = _Base::bucket_count();
	iterator __res = _Base::insert(__iter, __v);
	this->_M_profile_resize(__old_size);
	return __res;
      }

      template<typename _Pair, typename = typename
	       std::enable_if<std::is_constructible<value_type,
						    _Pair&&>::value>::type>
	std::pair<iterator, bool>
	insert(_Pair&& __obj)
	{
	  size_type __old_size = _Base::bucket_count();
	  std::pair<iterator, bool> __res
	    = _Base::insert(std::forward<_Pair>(__obj));
	  this->_M_profile_resize(__old_size);
	  return __res;
	}

      template<typename _Pair, typename = typename
	       std::enable_if<std::is_constructible<value_type,
						    _Pair&&>::value>::type>
	iterator
	insert(const_iterator __iter, _Pair&& __v)
	{
	  size_type __old_size = _Base::bucket_count();
	  iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
	  this->_M_profile_resize(__old_size);
	  return __res;
	}

      template<typename _InputIter>
	void
	insert(_InputIter __first, _InputIter __last)
	{
	  size_type __old_size = _Base::bucket_count();
	  _Base::insert(__first, __last);
	  this->_M_profile_resize(__old_size);
	}

      // operator[]
      mapped_type&
      operator[](const _Key& __k)
      {
	size_type __old_size = _Base::bucket_count();
	mapped_type& __res = _M_base()[__k];
	this->_M_profile_resize(__old_size);
	return __res;
      }

      mapped_type&
      operator[](_Key&& __k)
      {
	size_type __old_size = _Base::bucket_count();
	mapped_type& __res = _M_base()[std::move(__k)];
	this->_M_profile_resize(__old_size);
	return __res;
      }

      void
      swap(unordered_map& __x)
      noexcept( noexcept(__x._M_base().swap(__x)) )
      {
	_Base::swap(__x._M_base());
	this->_M_swap(__x);
      }

      void rehash(size_type __n)
      {
	size_type __old_size = _Base::bucket_count();
	_Base::rehash(__n);
	this->_M_profile_resize(__old_size);
      }
  };

  template<typename _Key, typename _Tp, typename _Hash,
	   typename _Pred, typename _Alloc>
    inline void
    swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
	 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    { __x.swap(__y); }

  template<typename _Key, typename _Tp, typename _Hash,
	   typename _Pred, typename _Alloc>
    inline bool
    operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
	       const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }

  template<typename _Key, typename _Tp, typename _Hash,
	   typename _Pred, typename _Alloc>
    inline bool
    operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
	       const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    { return !(__x == __y); }

#undef _GLIBCXX_BASE
#undef _GLIBCXX_STD_BASE
#define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
#define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE

  /// Class std::unordered_multimap wrapper with performance instrumentation.
  template<typename _Key, typename _Tp,
	   typename _Hash = std::hash<_Key>,
	   typename _Pred = std::equal_to<_Key>,
	   typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
    class unordered_multimap
    : public _GLIBCXX_STD_BASE,
      public _Unordered_profile<unordered_multimap<_Key, _Tp,
						   _Hash, _Pred, _Alloc>,
				false>
    {
      typedef typename _GLIBCXX_STD_BASE _Base;

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

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

    public:
      typedef typename _Base::size_type		size_type;
      typedef typename _Base::hasher		hasher;
      typedef typename _Base::key_equal		key_equal;
      typedef typename _Base::allocator_type	allocator_type;
      typedef typename _Base::key_type		key_type;
      typedef typename _Base::value_type	value_type;
      typedef typename _Base::difference_type	difference_type;
      typedef typename _Base::reference		reference;
      typedef typename _Base::const_reference	const_reference;

      typedef typename _Base::iterator		iterator;
      typedef typename _Base::const_iterator	const_iterator;

      unordered_multimap() = default;

      explicit
      unordered_multimap(size_type __n,
			 const hasher& __hf = hasher(),
			 const key_equal& __eql = key_equal(),
			 const allocator_type& __a = allocator_type())
      : _Base(__n, __hf, __eql, __a) { }

      template<typename _InputIterator>
	unordered_multimap(_InputIterator __f, _InputIterator __l,
			   size_type __n = 0,
			   const hasher& __hf = hasher(),
			   const key_equal& __eql = key_equal(),
			   const allocator_type& __a = allocator_type())
	: _Base(__f, __l, __n, __hf, __eql, __a) { }

      unordered_multimap(const unordered_multimap&) = default;

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

      unordered_multimap(unordered_multimap&&) = default;

      explicit
      unordered_multimap(const allocator_type& __a)
      : _Base(__a) { }

      unordered_multimap(const unordered_multimap& __ummap,
			 const allocator_type& __a)
      : _Base(__ummap._M_base(), __a) { }

      unordered_multimap(unordered_multimap&& __ummap,
			 const allocator_type& __a)
      : _Base(std::move(__ummap._M_base()), __a) { }

      unordered_multimap(initializer_list<value_type> __l,
			 size_type __n = 0,
			 const hasher& __hf = hasher(),
			 const key_equal& __eql = key_equal(),
			 const allocator_type& __a = allocator_type())
      : _Base(__l, __n, __hf, __eql, __a) { }

      unordered_multimap(size_type __n, const allocator_type& __a)
      : unordered_multimap(__n, hasher(), key_equal(), __a)
      { }

      unordered_multimap(size_type __n, const hasher& __hf,
			 const allocator_type& __a)
      : unordered_multimap(__n, __hf, key_equal(), __a)
      { }

      template<typename _InputIterator>
	unordered_multimap(_InputIterator __first, _InputIterator __last,
			   size_type __n,
			   const allocator_type& __a)
	  : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a)
	{ }

      template<typename _InputIterator>
	unordered_multimap(_InputIterator __first, _InputIterator __last,
			   size_type __n, const hasher& __hf,
			   const allocator_type& __a)
	  : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a)
	{ }

      unordered_multimap(initializer_list<value_type> __l,
			 size_type __n,
			 const allocator_type& __a)
	: unordered_multimap(__l, __n, hasher(), key_equal(), __a)
      { }

      unordered_multimap(initializer_list<value_type> __l,
			 size_type __n, const hasher& __hf,
			 const allocator_type& __a)
	: unordered_multimap(__l, __n, __hf, key_equal(), __a)
      { }

      unordered_multimap&
      operator=(const unordered_multimap&) = default;

      unordered_multimap&
      operator=(unordered_multimap&&) = default;

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

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

      template<typename... _Args>
	iterator
	emplace(_Args&&... __args)
	{
	  size_type __old_size = _Base::bucket_count();
	  iterator __res
	    = _Base::emplace(std::forward<_Args>(__args)...);
	  this->_M_profile_resize(__old_size);
	  return __res;
	}

      template<typename... _Args>
	iterator
	emplace_hint(const_iterator __it, _Args&&... __args)
	{
	  size_type __old_size = _Base::bucket_count();
	  iterator __res
	    = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
	  this->_M_profile_resize(__old_size);
	  return __res;
	}

      void
      insert(std::initializer_list<value_type> __l)
      {
	size_type __old_size = _Base::bucket_count();
	_Base::insert(__l);
	this->_M_profile_resize(__old_size);
      }

      iterator
      insert(const value_type& __obj)
      {
	size_type __old_size = _Base::bucket_count();
	iterator __res = _Base::insert(__obj);
	this->_M_profile_resize(__old_size);
	return __res;
      }

      iterator
      insert(const_iterator __iter, const value_type& __v)
      {
	size_type __old_size = _Base::bucket_count();
	iterator __res = _Base::insert(__iter, __v);
	this->_M_profile_resize(__old_size);
	return __res;
      }

      template<typename _Pair, typename = typename
	       std::enable_if<std::is_constructible<value_type,
						    _Pair&&>::value>::type>
	iterator
	insert(_Pair&& __obj)
	{
	  size_type __old_size = _Base::bucket_count();
	  iterator __res = _Base::insert(std::forward<_Pair>(__obj));
	  this->_M_profile_resize(__old_size);
	  return __res;
	}

      template<typename _Pair, typename = typename
	       std::enable_if<std::is_constructible<value_type,
						    _Pair&&>::value>::type>
	iterator
	insert(const_iterator __iter, _Pair&& __v)
	{
	  size_type __old_size = _Base::bucket_count();
	  iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
	  this->_M_profile_resize(__old_size);
	  return __res;
	}

      template<typename _InputIter>
	void
	insert(_InputIter __first, _InputIter __last)
	{
	  size_type __old_size = _Base::bucket_count();
	  _Base::insert(__first, __last);
	  this->_M_profile_resize(__old_size);
	}

      void
      swap(unordered_multimap& __x)
      noexcept( noexcept(__x._M_base().swap(__x)) )
      {
	_Base::swap(__x._M_base());
	this->_M_swap(__x);
      }

      void
      rehash(size_type __n)
      {
	size_type __old_size = _Base::bucket_count();
	_Base::rehash(__n);
	this->_M_profile_resize(__old_size);
      }
  };

  template<typename _Key, typename _Tp, typename _Hash,
	   typename _Pred, typename _Alloc>
    inline void
    swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
	 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    { __x.swap(__y); }

  template<typename _Key, typename _Tp, typename _Hash,
	   typename _Pred, typename _Alloc>
    inline bool
    operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
	       const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }

  template<typename _Key, typename _Tp, typename _Hash,
	   typename _Pred, typename _Alloc>
    inline bool
    operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
	       const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    { return !(__x == __y); }

} // namespace __profile
} // namespace std

#undef _GLIBCXX_BASE
#undef _GLIBCXX_STD_BASE

#endif // C++11

#endif
