404

[ Avaa Bypassed ]




Upload:

Command:

botdev@18.220.140.173: ~ $
// Debugging unordered_map/unordered_multimap implementation -*- C++ -*-

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

#ifndef _GLIBCXX_DEBUG_UNORDERED_MAP
#define _GLIBCXX_DEBUG_UNORDERED_MAP 1

#pragma GCC system_header

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

#include <debug/safe_unordered_container.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
#include <debug/safe_local_iterator.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __debug
{
  /// Class std::unordered_map with safety/checking/debug 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 __gnu_debug::_Safe_container<
	unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
	__gnu_debug::_Safe_unordered_container>,
      public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
    {
      typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
					    _Pred, _Alloc>		_Base;
      typedef __gnu_debug::_Safe_container<unordered_map,
		   _Alloc, __gnu_debug::_Safe_unordered_container>	_Safe;
      typedef typename _Base::const_iterator	_Base_const_iterator;
      typedef typename _Base::iterator		_Base_iterator;
      typedef typename _Base::const_local_iterator
						_Base_const_local_iterator;
      typedef typename _Base::local_iterator	_Base_local_iterator;

    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 __gnu_debug::_Safe_iterator<
	_Base_iterator, unordered_map>			iterator;
      typedef __gnu_debug::_Safe_iterator<
	_Base_const_iterator, unordered_map>		const_iterator;
      typedef __gnu_debug::_Safe_local_iterator<
	_Base_local_iterator, unordered_map>		local_iterator;
      typedef __gnu_debug::_Safe_local_iterator<
	_Base_const_local_iterator, unordered_map>	const_local_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 __first, _InputIterator __last,
		      size_type __n = 0,
		      const hasher& __hf = hasher(),
		      const key_equal& __eql = key_equal(),
		      const allocator_type& __a = allocator_type())
	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
								     __last)),
		__gnu_debug::__base(__last), __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)
      : _Safe(std::move(__umap._M_safe()), __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() = default;

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

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

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

      void
      swap(unordered_map& __x)
	noexcept( noexcept(declval<_Base&>().swap(__x)) )
      {
	_Safe::_M_swap(__x);
	_Base::swap(__x);
      }

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

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

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

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

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

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

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

      // local versions
      local_iterator
      begin(size_type __b)
      {
	__glibcxx_check_bucket_index(__b);
	return local_iterator(_Base::begin(__b), this);
      }

      local_iterator
      end(size_type __b)
      {
	__glibcxx_check_bucket_index(__b);
	return local_iterator(_Base::end(__b), this);
      }

      const_local_iterator
      begin(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::begin(__b), this);
      }

      const_local_iterator
      end(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::end(__b), this);
      }

      const_local_iterator
      cbegin(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::cbegin(__b), this);
      }

      const_local_iterator
      cend(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::cend(__b), this);
      }

      size_type
      bucket_size(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return _Base::bucket_size(__b);
      }

      float
      max_load_factor() const noexcept
      { return _Base::max_load_factor(); }

      void
      max_load_factor(float __f)
      {
	__glibcxx_check_max_load_factor(__f);
	_Base::max_load_factor(__f);
      }

      template<typename... _Args>
	std::pair<iterator, bool>
	emplace(_Args&&... __args)
	{
	  size_type __bucket_count = this->bucket_count();
	  std::pair<_Base_iterator, bool> __res
	    = _Base::emplace(std::forward<_Args>(__args)...);
	  _M_check_rehashed(__bucket_count);
	  return std::make_pair(iterator(__res.first, this), __res.second);
	}

      template<typename... _Args>
	iterator
	emplace_hint(const_iterator __hint, _Args&&... __args)
	{
	  __glibcxx_check_insert(__hint);
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it = _Base::emplace_hint(__hint.base(),
					std::forward<_Args>(__args)...);
	  _M_check_rehashed(__bucket_count);
	  return iterator(__it, this);
	}

      std::pair<iterator, bool>
      insert(const value_type& __obj)
      {
	size_type __bucket_count = this->bucket_count();
	auto __res = _Base::insert(__obj);
	_M_check_rehashed(__bucket_count);
	return { iterator(__res.first, this), __res.second };
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2354. Unnecessary copying when inserting into maps with braced-init
      std::pair<iterator, bool>
      insert(value_type&& __x)
      {
	size_type __bucket_count = this->bucket_count();
	auto __res = _Base::insert(std::move(__x));
	_M_check_rehashed(__bucket_count);
	return { iterator(__res.first, this), __res.second };
      }

      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 __bucket_count = this->bucket_count();
	  std::pair<_Base_iterator, bool> __res =
	    _Base::insert(std::forward<_Pair>(__obj));
	  _M_check_rehashed(__bucket_count);
	  return std::make_pair(iterator(__res.first, this), __res.second);
	}

      iterator
      insert(const_iterator __hint, const value_type& __obj)
      {
	__glibcxx_check_insert(__hint);
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __it = _Base::insert(__hint.base(), __obj);
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2354. Unnecessary copying when inserting into maps with braced-init
      iterator
      insert(const_iterator __hint, value_type&& __x)
      {
	__glibcxx_check_insert(__hint);
	size_type __bucket_count = this->bucket_count();
	auto __it = _Base::insert(__hint.base(), std::move(__x));
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

      template<typename _Pair, typename = typename
	       std::enable_if<std::is_constructible<value_type,
						    _Pair&&>::value>::type>
	iterator
	insert(const_iterator __hint, _Pair&& __obj)
	{
	  __glibcxx_check_insert(__hint);
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it =
	    _Base::insert(__hint.base(), std::forward<_Pair>(__obj));
	  _M_check_rehashed(__bucket_count);
	  return iterator(__it, this);
	}

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

      template<typename _InputIterator>
	void
	insert(_InputIterator __first, _InputIterator __last)
	{
	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
	  __glibcxx_check_valid_range2(__first, __last, __dist);
	  size_type __bucket_count = this->bucket_count();

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

	  _M_check_rehashed(__bucket_count);
	}

#if __cplusplus > 201402L
      template <typename... _Args>
        pair<iterator, bool>
        try_emplace(const key_type& __k, _Args&&... __args)
        {
	  auto __res = _Base::try_emplace(__k,
					  std::forward<_Args>(__args)...);
	  return { iterator(__res.first, this), __res.second };
	}

      template <typename... _Args>
        pair<iterator, bool>
        try_emplace(key_type&& __k, _Args&&... __args)
        {
	  auto __res = _Base::try_emplace(std::move(__k),
					  std::forward<_Args>(__args)...);
	  return { iterator(__res.first, this), __res.second };
	}

      template <typename... _Args>
        iterator
        try_emplace(const_iterator __hint, const key_type& __k,
                    _Args&&... __args)
        {
	  __glibcxx_check_insert(__hint);
	  return iterator(_Base::try_emplace(__hint.base(), __k,
					     std::forward<_Args>(__args)...),
			  this);
	}

      template <typename... _Args>
        iterator
        try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
        {
	  __glibcxx_check_insert(__hint);
	  return iterator(_Base::try_emplace(__hint.base(), std::move(__k),
					     std::forward<_Args>(__args)...),
			  this);
	}

      template <typename _Obj>
        pair<iterator, bool>
        insert_or_assign(const key_type& __k, _Obj&& __obj)
        {
	  auto __res = _Base::insert_or_assign(__k,
					       std::forward<_Obj>(__obj));
	  return { iterator(__res.first, this), __res.second };
	}

      template <typename _Obj>
        pair<iterator, bool>
        insert_or_assign(key_type&& __k, _Obj&& __obj)
        {
	  auto __res = _Base::insert_or_assign(std::move(__k),
					       std::forward<_Obj>(__obj));
	  return { iterator(__res.first, this), __res.second };
	}

      template <typename _Obj>
        iterator
        insert_or_assign(const_iterator __hint, const key_type& __k,
                         _Obj&& __obj)
        {
	  __glibcxx_check_insert(__hint);
	  return iterator(_Base::insert_or_assign(__hint.base(), __k,
						  std::forward<_Obj>(__obj)),
			  this);
	}

      template <typename _Obj>
        iterator
        insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
        {
	  __glibcxx_check_insert(__hint);
	  return iterator(_Base::insert_or_assign(__hint.base(),
						  std::move(__k),
						  std::forward<_Obj>(__obj)),
			  this);
	}
#endif // C++17

#if __cplusplus > 201402L
      using node_type = typename _Base::node_type;

      struct insert_return_type
      {
	bool inserted;
	iterator position;
	node_type node;
      };

      node_type
      extract(const_iterator __position)
      {
	__glibcxx_check_erase(__position);
	_Base_const_iterator __victim = __position.base();
	this->_M_invalidate_if(
	    [__victim](_Base_const_iterator __it) { return __it == __victim; }
	    );
	this->_M_invalidate_local_if(
	    [__victim](_Base_const_local_iterator __it) {
		return __it._M_curr() == __victim._M_cur;
	    });
	return _Base::extract(__position.base());
      }

      node_type
      extract(const key_type& __key)
      {
	const auto __position = find(__key);
	if (__position != end())
	  return extract(__position);
	return {};
      }

      insert_return_type
      insert(node_type&& __nh)
      {
	auto __ret = _Base::insert(std::move(__nh));
	iterator __pos = iterator(__ret.position, this);
	return { __ret.inserted, __pos, std::move(__ret.node) };
      }

      iterator
      insert(const_iterator __hint, node_type&& __nh)
      {
	__glibcxx_check_insert(__hint);
	return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
      }

      using _Base::merge;
#endif // C++17

      iterator
      find(const key_type& __key)
      { return iterator(_Base::find(__key), this); }

      const_iterator
      find(const key_type& __key) const
      { return const_iterator(_Base::find(__key), this); }

      std::pair<iterator, iterator>
      equal_range(const key_type& __key)
      {
	std::pair<_Base_iterator, _Base_iterator> __res =
	  _Base::equal_range(__key);
	return std::make_pair(iterator(__res.first, this),
			      iterator(__res.second, this));
      }

      std::pair<const_iterator, const_iterator>
      equal_range(const key_type& __key) const
      {
	std::pair<_Base_const_iterator, _Base_const_iterator> __res =
	  _Base::equal_range(__key);
	return std::make_pair(const_iterator(__res.first, this),
			      const_iterator(__res.second, this));
      }

      size_type
      erase(const key_type& __key)
      {
	size_type __ret(0);
	_Base_iterator __victim(_Base::find(__key));
	if (__victim != _Base::end())
	  {
	    this->_M_invalidate_if([__victim](_Base_const_iterator __it)
			    { return __it == __victim; });
	    this->_M_invalidate_local_if(
			    [__victim](_Base_const_local_iterator __it)
			    { return __it._M_curr() == __victim._M_cur; });
	    size_type __bucket_count = this->bucket_count();
	    _Base::erase(__victim);
	    _M_check_rehashed(__bucket_count);
	    __ret = 1;
	  }
	return __ret;
      }

      iterator
      erase(const_iterator __it)
      {
	__glibcxx_check_erase(__it);
	_Base_const_iterator __victim = __it.base();
	this->_M_invalidate_if([__victim](_Base_const_iterator __it)
			{ return __it == __victim; });
	this->_M_invalidate_local_if(
			[__victim](_Base_const_local_iterator __it)
			{ return __it._M_curr() == __victim._M_cur; });
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __next = _Base::erase(__it.base());
	_M_check_rehashed(__bucket_count);
	return iterator(__next, this);
      }

      iterator
      erase(iterator __it)
      { return erase(const_iterator(__it)); }

      iterator
      erase(const_iterator __first, const_iterator __last)
      {
	__glibcxx_check_erase_range(__first, __last);
	for (_Base_const_iterator __tmp = __first.base();
	     __tmp != __last.base(); ++__tmp)
	  {
	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
				  _M_message(__gnu_debug::__msg_valid_range)
				  ._M_iterator(__first, "first")
				  ._M_iterator(__last, "last"));
	    this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
			    { return __it == __tmp; });
	    this->_M_invalidate_local_if(
			    [__tmp](_Base_const_local_iterator __it)
			    { return __it._M_curr() == __tmp._M_cur; });
	  }
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __next = _Base::erase(__first.base(), __last.base());
	_M_check_rehashed(__bucket_count);
	return iterator(__next, this);
      }

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

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

    private:
      void
      _M_check_rehashed(size_type __prev_count)
      {
	if (__prev_count != this->bucket_count())
	  this->_M_invalidate_locals();
      }
    };

  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)
    noexcept(noexcept(__x.swap(__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 __x._M_base() == __y._M_base(); }

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


  /// Class std::unordered_multimap with safety/checking/debug 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 __gnu_debug::_Safe_container<
	unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
	__gnu_debug::_Safe_unordered_container>,
	public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
    {
      typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
						 _Pred, _Alloc>		_Base;
      typedef __gnu_debug::_Safe_container<unordered_multimap,
	_Alloc, __gnu_debug::_Safe_unordered_container>			_Safe;
      typedef typename _Base::const_iterator	   _Base_const_iterator;
      typedef typename _Base::iterator		   _Base_iterator;
      typedef typename _Base::const_local_iterator _Base_const_local_iterator;
      typedef typename _Base::local_iterator	   _Base_local_iterator;

    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 __gnu_debug::_Safe_iterator<
	_Base_iterator, unordered_multimap>		iterator;
      typedef __gnu_debug::_Safe_iterator<
	_Base_const_iterator, unordered_multimap>	const_iterator;
      typedef __gnu_debug::_Safe_local_iterator<
	_Base_local_iterator, unordered_multimap>	local_iterator;
      typedef __gnu_debug::_Safe_local_iterator<
	_Base_const_local_iterator, unordered_multimap> const_local_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 __first, _InputIterator __last,
			   size_type __n = 0,
			   const hasher& __hf = hasher(),
			   const key_equal& __eql = key_equal(),
			   const allocator_type& __a = allocator_type())
	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
								     __last)),
		__gnu_debug::__base(__last), __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& __umap,
			 const allocator_type& __a)
      : _Base(__umap, __a) { }

      unordered_multimap(unordered_multimap&& __umap,
			 const allocator_type& __a)
      : _Safe(std::move(__umap._M_safe()), __a),
	_Base(std::move(__umap._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() = default;

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

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

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

      void
      swap(unordered_multimap& __x)
	noexcept( noexcept(declval<_Base&>().swap(__x)) )
      {
	_Safe::_M_swap(__x);
	_Base::swap(__x);
      }

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

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

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

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

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

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

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

      // local versions
      local_iterator
      begin(size_type __b)
      {
	__glibcxx_check_bucket_index(__b);
	return local_iterator(_Base::begin(__b), this);
      }

      local_iterator
      end(size_type __b)
      {
	__glibcxx_check_bucket_index(__b);
	return local_iterator(_Base::end(__b), this);
      }

      const_local_iterator
      begin(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::begin(__b), this);
      }

      const_local_iterator
      end(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::end(__b), this);
      }

      const_local_iterator
      cbegin(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::cbegin(__b), this);
      }

      const_local_iterator
      cend(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::cend(__b), this);
      }

      size_type
      bucket_size(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return _Base::bucket_size(__b);
      }

      float
      max_load_factor() const noexcept
      { return _Base::max_load_factor(); }

      void
      max_load_factor(float __f)
      {
	__glibcxx_check_max_load_factor(__f);
	_Base::max_load_factor(__f);
      }

      template<typename... _Args>
	iterator
	emplace(_Args&&... __args)
	{
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it
	    = _Base::emplace(std::forward<_Args>(__args)...);
	  _M_check_rehashed(__bucket_count);
	  return iterator(__it, this);
	}

      template<typename... _Args>
	iterator
	emplace_hint(const_iterator __hint, _Args&&... __args)
	{
	  __glibcxx_check_insert(__hint);
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it = _Base::emplace_hint(__hint.base(),
					std::forward<_Args>(__args)...);
	  _M_check_rehashed(__bucket_count);
	  return iterator(__it, this);
	}

      iterator
      insert(const value_type& __obj)
      {
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __it = _Base::insert(__obj);
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2354. Unnecessary copying when inserting into maps with braced-init
      iterator
      insert(value_type&& __x)
      {
	size_type __bucket_count = this->bucket_count();
	auto __it = _Base::insert(std::move(__x));
	_M_check_rehashed(__bucket_count);
	return { __it, this };
      }

      iterator
      insert(const_iterator __hint, const value_type& __obj)
      {
	__glibcxx_check_insert(__hint);
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __it = _Base::insert(__hint.base(), __obj);
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2354. Unnecessary copying when inserting into maps with braced-init
      iterator
      insert(const_iterator __hint, value_type&& __x)
      {
	__glibcxx_check_insert(__hint);
	size_type __bucket_count = this->bucket_count();
	auto __it = _Base::insert(__hint.base(), std::move(__x));
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

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

      template<typename _Pair, typename = typename
	       std::enable_if<std::is_constructible<value_type,
						    _Pair&&>::value>::type>
	iterator
	insert(const_iterator __hint, _Pair&& __obj)
	{
	  __glibcxx_check_insert(__hint);
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it =
	    _Base::insert(__hint.base(), std::forward<_Pair>(__obj));
	  _M_check_rehashed(__bucket_count);
	  return iterator(__it, this);
	}

      void
      insert(std::initializer_list<value_type> __l)
      { _Base::insert(__l); }

      template<typename _InputIterator>
	void
	insert(_InputIterator __first, _InputIterator __last)
	{
	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
	  __glibcxx_check_valid_range2(__first, __last, __dist);
	  size_type __bucket_count = this->bucket_count();

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

	  _M_check_rehashed(__bucket_count);
	}

#if __cplusplus > 201402L
      using node_type = typename _Base::node_type;

      node_type
      extract(const_iterator __position)
      {
	__glibcxx_check_erase(__position);
	_Base_const_iterator __victim = __position.base();
	this->_M_invalidate_if(
	    [__victim](_Base_const_iterator __it) { return __it == __victim; }
	    );
	this->_M_invalidate_local_if(
	    [__victim](_Base_const_local_iterator __it) {
		return __it._M_curr() == __victim._M_cur;
	    });
	return _Base::extract(__position.base());
      }

      node_type
      extract(const key_type& __key)
      {
	const auto __position = find(__key);
	if (__position != end())
	  return extract(__position);
	return {};
      }

      iterator
      insert(node_type&& __nh)
      { return iterator(_Base::insert(std::move(__nh)), this); }

      iterator
      insert(const_iterator __hint, node_type&& __nh)
      {
	__glibcxx_check_insert(__hint);
	return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
      }

      using _Base::merge;
#endif // C++17

      iterator
      find(const key_type& __key)
      { return iterator(_Base::find(__key), this); }

      const_iterator
      find(const key_type& __key) const
      { return const_iterator(_Base::find(__key), this); }

      std::pair<iterator, iterator>
      equal_range(const key_type& __key)
      {
	std::pair<_Base_iterator, _Base_iterator> __res =
	  _Base::equal_range(__key);
	return std::make_pair(iterator(__res.first, this),
			      iterator(__res.second, this));
      }

      std::pair<const_iterator, const_iterator>
      equal_range(const key_type& __key) const
      {
	std::pair<_Base_const_iterator, _Base_const_iterator> __res =
	  _Base::equal_range(__key);
	return std::make_pair(const_iterator(__res.first, this),
			      const_iterator(__res.second, this));
      }

      size_type
      erase(const key_type& __key)
      {
	size_type __ret(0);
	size_type __bucket_count = this->bucket_count();
	std::pair<_Base_iterator, _Base_iterator> __pair =
	  _Base::equal_range(__key);
	for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
	  {
	    this->_M_invalidate_if([__victim](_Base_const_iterator __it)
			    { return __it == __victim; });
	    this->_M_invalidate_local_if(
			    [__victim](_Base_const_local_iterator __it)
			    { return __it._M_curr() == __victim._M_cur; });
	    _Base::erase(__victim++);
	    ++__ret;
	  }
	_M_check_rehashed(__bucket_count);
	return __ret;
      }

      iterator
      erase(const_iterator __it)
      {
	__glibcxx_check_erase(__it);
	_Base_const_iterator __victim = __it.base();
	this->_M_invalidate_if([__victim](_Base_const_iterator __it)
			{ return __it == __victim; });
	this->_M_invalidate_local_if(
			[__victim](_Base_const_local_iterator __it)
			{ return __it._M_curr() == __victim._M_cur; });
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __next = _Base::erase(__it.base());
	_M_check_rehashed(__bucket_count);
	return iterator(__next, this);
      }

      iterator
      erase(iterator __it)
      { return erase(const_iterator(__it)); }

      iterator
      erase(const_iterator __first, const_iterator __last)
      {
	__glibcxx_check_erase_range(__first, __last);
	for (_Base_const_iterator __tmp = __first.base();
	     __tmp != __last.base(); ++__tmp)
	  {
	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
				  _M_message(__gnu_debug::__msg_valid_range)
				  ._M_iterator(__first, "first")
				  ._M_iterator(__last, "last"));
	    this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
			    { return __it == __tmp; });
	    this->_M_invalidate_local_if(
			    [__tmp](_Base_const_local_iterator __it)
			    { return __it._M_curr() == __tmp._M_cur; });
	  }
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __next = _Base::erase(__first.base(), __last.base());
	_M_check_rehashed(__bucket_count);
	return iterator(__next, this);
      }

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

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

    private:
      void
      _M_check_rehashed(size_type __prev_count)
      {
	if (__prev_count != this->bucket_count())
	  this->_M_invalidate_locals();
      }
    };

  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)
    noexcept(noexcept(__x.swap(__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 __x._M_base() == __y._M_base(); }

  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 __debug
} // namespace std

#endif // C++11

#endif

Filemanager

Name Type Size Permission Actions
array File 9.88 KB 0644
assertions.h File 2.35 KB 0644
bitset File 11.62 KB 0644
debug.h File 5.1 KB 0644
deque File 16.61 KB 0644
formatter.h File 13.84 KB 0644
forward_list File 24.66 KB 0644
functions.h File 16.21 KB 0644
helper_functions.h File 6.65 KB 0644
list File 21.88 KB 0644
macros.h File 17.45 KB 0644
map File 1.31 KB 0644
map.h File 20.65 KB 0644
multimap.h File 17.82 KB 0644
multiset.h File 16.77 KB 0644
safe_base.h File 9.06 KB 0644
safe_container.h File 3.33 KB 0644
safe_iterator.h File 29.54 KB 0644
safe_iterator.tcc File 2.89 KB 0644
safe_local_iterator.h File 15.85 KB 0644
safe_local_iterator.tcc File 2.07 KB 0644
safe_sequence.h File 4.98 KB 0644
safe_sequence.tcc File 4.87 KB 0644
safe_unordered_base.h File 6.73 KB 0644
safe_unordered_container.h File 3.81 KB 0644
safe_unordered_container.tcc File 3.19 KB 0644
set File 1.31 KB 0644
set.h File 16.92 KB 0644
stl_iterator.h File 4.18 KB 0644
string File 32.86 KB 0644
unordered_map File 34.58 KB 0644
unordered_set File 29.81 KB 0644
vector File 21.35 KB 0644