LCOV - code coverage report
Current view: top level - usr/include/boost/unordered - unordered_map.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 41 116 35.3 %
Date: 2022-12-08 13:48:47 Functions: 5 30 16.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : // Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
       3             : // Copyright (C) 2005-2011 Daniel James.
       4             : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5             : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6             : 
       7             : //  See http://www.boost.org/libs/unordered for documentation
       8             : 
       9             : #ifndef BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
      10             : #define BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
      11             : 
      12             : #include <boost/config.hpp>
      13             : #if defined(BOOST_HAS_PRAGMA_ONCE)
      14             : #pragma once
      15             : #endif
      16             : 
      17             : #include <boost/core/explicit_operator_bool.hpp>
      18             : #include <boost/functional/hash.hpp>
      19             : #include <boost/move/move.hpp>
      20             : #include <boost/type_traits/is_constructible.hpp>
      21             : #include <boost/unordered/detail/map.hpp>
      22             : 
      23             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
      24             : #include <initializer_list>
      25             : #endif
      26             : 
      27             : #if defined(BOOST_MSVC)
      28             : #pragma warning(push)
      29             : // conditional expression is constant
      30             : #pragma warning(disable : 4127)
      31             : #if BOOST_MSVC >= 1400
      32             : // the inline specifier cannot be used when a friend declaration refers to a
      33             : // specialization of a function template
      34             : #pragma warning(disable : 4396)
      35             : #endif
      36             : #endif
      37             : 
      38             : namespace boost {
      39             :   namespace unordered {
      40             :     template <class K, class T, class H, class P, class A> class unordered_map
      41             :     {
      42             : #if defined(BOOST_UNORDERED_USE_MOVE)
      43             :       BOOST_COPYABLE_AND_MOVABLE(unordered_map)
      44             : #endif
      45             :       template <typename, typename, typename, typename, typename>
      46             :       friend class unordered_multimap;
      47             : 
      48             :     public:
      49             :       typedef K key_type;
      50             :       typedef T mapped_type;
      51             :       typedef std::pair<const K, T> value_type;
      52             :       typedef H hasher;
      53             :       typedef P key_equal;
      54             :       typedef A allocator_type;
      55             : 
      56             :     private:
      57             :       typedef boost::unordered::detail::map<A, K, T, H, P> types;
      58             :       typedef typename types::value_allocator_traits value_allocator_traits;
      59             :       typedef typename types::table table;
      60             :       typedef typename table::node_pointer node_pointer;
      61             :       typedef typename table::link_pointer link_pointer;
      62             : 
      63             :     public:
      64             :       typedef typename value_allocator_traits::pointer pointer;
      65             :       typedef typename value_allocator_traits::const_pointer const_pointer;
      66             : 
      67             :       typedef value_type& reference;
      68             :       typedef value_type const& const_reference;
      69             : 
      70             :       typedef std::size_t size_type;
      71             :       typedef std::ptrdiff_t difference_type;
      72             : 
      73             :       typedef typename table::iterator iterator;
      74             :       typedef typename table::c_iterator const_iterator;
      75             :       typedef typename table::l_iterator local_iterator;
      76             :       typedef typename table::cl_iterator const_local_iterator;
      77             :       typedef typename types::node_type node_type;
      78             :       typedef typename types::insert_return_type insert_return_type;
      79             : 
      80             :     private:
      81             :       table table_;
      82             : 
      83             :     public:
      84             :       // constructors
      85             : 
      86             :       unordered_map();
      87             : 
      88             :       explicit unordered_map(size_type, const hasher& = hasher(),
      89             :         const key_equal& = key_equal(),
      90             :         const allocator_type& = allocator_type());
      91             : 
      92             :       template <class InputIt>
      93             :       unordered_map(InputIt, InputIt,
      94             :         size_type = boost::unordered::detail::default_bucket_count,
      95             :         const hasher& = hasher(), const key_equal& = key_equal(),
      96             :         const allocator_type& = allocator_type());
      97             : 
      98             :       unordered_map(unordered_map const&);
      99             : 
     100             : #if defined(BOOST_UNORDERED_USE_MOVE) ||                                       \
     101             :   !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
     102           0 :       unordered_map(BOOST_RV_REF(unordered_map) other)
     103             :         BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
     104           0 :           : table_(other.table_, boost::unordered::detail::move_tag())
     105             :       {
     106             :         // The move is done in table_
     107           0 :       }
     108             : #endif
     109             : 
     110             :       explicit unordered_map(allocator_type const&);
     111             : 
     112             :       unordered_map(unordered_map const&, allocator_type const&);
     113             : 
     114             :       unordered_map(BOOST_RV_REF(unordered_map), allocator_type const&);
     115             : 
     116             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
     117             :       unordered_map(std::initializer_list<value_type>,
     118             :         size_type = boost::unordered::detail::default_bucket_count,
     119             :         const hasher& = hasher(), const key_equal& l = key_equal(),
     120             :         const allocator_type& = allocator_type());
     121             : #endif
     122             : 
     123             :       explicit unordered_map(size_type, const allocator_type&);
     124             : 
     125             :       explicit unordered_map(size_type, const hasher&, const allocator_type&);
     126             : 
     127             :       template <class InputIt>
     128             :       unordered_map(InputIt, InputIt, size_type, const allocator_type&);
     129             : 
     130             :       template <class InputIt>
     131             :       unordered_map(
     132             :         InputIt, InputIt, size_type, const hasher&, const allocator_type&);
     133             : 
     134             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
     135             :       unordered_map(
     136             :         std::initializer_list<value_type>, size_type, const allocator_type&);
     137             : 
     138             :       unordered_map(std::initializer_list<value_type>, size_type, const hasher&,
     139             :         const allocator_type&);
     140             : #endif
     141             : 
     142             :       // Destructor
     143             : 
     144             :       ~unordered_map() BOOST_NOEXCEPT;
     145             : 
     146             : // Assign
     147             : 
     148             : #if defined(BOOST_UNORDERED_USE_MOVE)
     149             :       unordered_map& operator=(BOOST_COPY_ASSIGN_REF(unordered_map) x)
     150             :       {
     151             :         table_.assign(x.table_, boost::unordered::detail::true_type());
     152             :         return *this;
     153             :       }
     154             : 
     155             :       unordered_map& operator=(BOOST_RV_REF(unordered_map) x)
     156             :         BOOST_NOEXCEPT_IF(value_allocator_traits::is_always_equal::value&&
     157             :             boost::is_nothrow_move_assignable<H>::value&&
     158             :               boost::is_nothrow_move_assignable<P>::value)
     159             :       {
     160             :         table_.move_assign(x.table_, boost::unordered::detail::true_type());
     161             :         return *this;
     162             :       }
     163             : #else
     164           0 :       unordered_map& operator=(unordered_map const& x)
     165             :       {
     166           0 :         table_.assign(x.table_, boost::unordered::detail::true_type());
     167             :         return *this;
     168             :       }
     169             : 
     170             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
     171             :       unordered_map& operator=(unordered_map&& x)
     172             :         BOOST_NOEXCEPT_IF(value_allocator_traits::is_always_equal::value&&
     173             :             boost::is_nothrow_move_assignable<H>::value&&
     174             :               boost::is_nothrow_move_assignable<P>::value)
     175             :       {
     176             :         table_.move_assign(x.table_, boost::unordered::detail::true_type());
     177             :         return *this;
     178             :       }
     179             : #endif
     180             : #endif
     181             : 
     182             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
     183             :       unordered_map& operator=(std::initializer_list<value_type>);
     184             : #endif
     185             : 
     186           0 :       allocator_type get_allocator() const BOOST_NOEXCEPT
     187             :       {
     188           0 :         return table_.node_alloc();
     189             :       }
     190             : 
     191             :       // iterators
     192             : 
     193           0 :       iterator begin() BOOST_NOEXCEPT { return iterator(table_.begin()); }
     194             : 
     195           0 :       const_iterator begin() const BOOST_NOEXCEPT
     196             :       {
     197           0 :         return const_iterator(table_.begin());
     198             :       }
     199             : 
     200         479 :       iterator end() BOOST_NOEXCEPT { return iterator(); }
     201             : 
     202           0 :       const_iterator end() const BOOST_NOEXCEPT { return const_iterator(); }
     203             : 
     204             :       const_iterator cbegin() const BOOST_NOEXCEPT
     205             :       {
     206             :         return const_iterator(table_.begin());
     207             :       }
     208             : 
     209             :       const_iterator cend() const BOOST_NOEXCEPT { return const_iterator(); }
     210             : 
     211             :       // size and capacity
     212             : 
     213             :       bool empty() const BOOST_NOEXCEPT { return table_.size_ == 0; }
     214             : 
     215           0 :       size_type size() const BOOST_NOEXCEPT { return table_.size_; }
     216             : 
     217             :       size_type max_size() const BOOST_NOEXCEPT;
     218             : 
     219             : // emplace
     220             : 
     221             : #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
     222             : 
     223             :       template <class... Args>
     224             :       std::pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args)
     225             :       {
     226             :         return table_.emplace_unique(
     227             :           table::extractor::extract(boost::forward<Args>(args)...),
     228             :           boost::forward<Args>(args)...);
     229             :       }
     230             : 
     231             : #else
     232             : 
     233             : #if !BOOST_UNORDERED_SUN_WORKAROUNDS1
     234             : 
     235             :       // 0 argument emplace requires special treatment in case
     236             :       // the container is instantiated with a value type that
     237             :       // doesn't have a default constructor.
     238             : 
     239             :       std::pair<iterator, bool> emplace(
     240             :         boost::unordered::detail::empty_emplace =
     241             :           boost::unordered::detail::empty_emplace(),
     242             :         value_type v = value_type())
     243             :       {
     244             :         return this->emplace(boost::move(v));
     245             :       }
     246             : 
     247             : #endif
     248             : 
     249             :       template <typename A0>
     250             :       std::pair<iterator, bool> emplace(BOOST_FWD_REF(A0) a0)
     251             :       {
     252             :         return table_.emplace_unique(
     253             :           table::extractor::extract(boost::forward<A0>(a0)),
     254             :           boost::unordered::detail::create_emplace_args(
     255             :             boost::forward<A0>(a0)));
     256             :       }
     257             : 
     258             :       template <typename A0, typename A1>
     259             :       std::pair<iterator, bool> emplace(
     260             :         BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
     261             :       {
     262             :         return table_.emplace_unique(
     263             :           table::extractor::extract(
     264             :             boost::forward<A0>(a0), boost::forward<A1>(a1)),
     265             :           boost::unordered::detail::create_emplace_args(
     266             :             boost::forward<A0>(a0), boost::forward<A1>(a1)));
     267             :       }
     268             : 
     269             :       template <typename A0, typename A1, typename A2>
     270             :       std::pair<iterator, bool> emplace(
     271             :         BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
     272             :       {
     273             :         return table_.emplace_unique(
     274             :           table::extractor::extract(
     275             :             boost::forward<A0>(a0), boost::forward<A1>(a1)),
     276             :           boost::unordered::detail::create_emplace_args(boost::forward<A0>(a0),
     277             :             boost::forward<A1>(a1), boost::forward<A2>(a2)));
     278             :       }
     279             : 
     280             : #endif
     281             : 
     282             : #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
     283             : 
     284             :       template <class... Args>
     285             :       iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
     286             :       {
     287             :         return table_.emplace_hint_unique(hint,
     288             :           table::extractor::extract(boost::forward<Args>(args)...),
     289             :           boost::forward<Args>(args)...);
     290             :       }
     291             : 
     292             : #else
     293             : 
     294             : #if !BOOST_UNORDERED_SUN_WORKAROUNDS1
     295             : 
     296             :       iterator emplace_hint(const_iterator hint,
     297             :         boost::unordered::detail::empty_emplace =
     298             :           boost::unordered::detail::empty_emplace(),
     299             :         value_type v = value_type())
     300             :       {
     301             :         return this->emplace_hint(hint, boost::move(v));
     302             :       }
     303             : 
     304             : #endif
     305             : 
     306             :       template <typename A0>
     307             :       iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
     308             :       {
     309             :         return table_.emplace_hint_unique(hint,
     310             :           table::extractor::extract(boost::forward<A0>(a0)),
     311             :           boost::unordered::detail::create_emplace_args(
     312             :             boost::forward<A0>(a0)));
     313             :       }
     314             : 
     315             :       template <typename A0, typename A1>
     316             :       iterator emplace_hint(
     317             :         const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
     318             :       {
     319             :         return table_.emplace_hint_unique(hint,
     320             :           table::extractor::extract(
     321             :             boost::forward<A0>(a0), boost::forward<A1>(a1)),
     322             :           boost::unordered::detail::create_emplace_args(
     323             :             boost::forward<A0>(a0), boost::forward<A1>(a1)));
     324             :       }
     325             : 
     326             :       template <typename A0, typename A1, typename A2>
     327             :       iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0,
     328             :         BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
     329             :       {
     330             :         return table_.emplace_hint_unique(hint,
     331             :           table::extractor::extract(
     332             :             boost::forward<A0>(a0), boost::forward<A1>(a1)),
     333             :           boost::unordered::detail::create_emplace_args(boost::forward<A0>(a0),
     334             :             boost::forward<A1>(a1), boost::forward<A2>(a2)));
     335             :       }
     336             : 
     337             : #endif
     338             : 
     339             : #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
     340             : 
     341             : #define BOOST_UNORDERED_EMPLACE(z, n, _)                                       \
     342             :   template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                          \
     343             :   std::pair<iterator, bool> emplace(                                           \
     344             :     BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a))                        \
     345             :   {                                                                            \
     346             :     return table_.emplace_unique(                                              \
     347             :       table::extractor::extract(                                               \
     348             :         boost::forward<A0>(a0), boost::forward<A1>(a1)),                       \
     349             :       boost::unordered::detail::create_emplace_args(                           \
     350             :         BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a)));               \
     351             :   }                                                                            \
     352             :                                                                                \
     353             :   template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                          \
     354             :   iterator emplace_hint(                                                       \
     355             :     const_iterator hint, BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a))   \
     356             :   {                                                                            \
     357             :     return table_.emplace_hint_unique(hint,                                    \
     358             :       table::extractor::extract(                                               \
     359             :         boost::forward<A0>(a0), boost::forward<A1>(a1)),                       \
     360             :       boost::unordered::detail::create_emplace_args(                           \
     361             :         BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a)));               \
     362             :   }
     363             : 
     364             :       BOOST_UNORDERED_EMPLACE(1, 4, _)
     365             :       BOOST_UNORDERED_EMPLACE(1, 5, _)
     366             :       BOOST_UNORDERED_EMPLACE(1, 6, _)
     367             :       BOOST_UNORDERED_EMPLACE(1, 7, _)
     368             :       BOOST_UNORDERED_EMPLACE(1, 8, _)
     369             :       BOOST_UNORDERED_EMPLACE(1, 9, _)
     370             :       BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
     371             :         BOOST_UNORDERED_EMPLACE, _)
     372             : 
     373             : #undef BOOST_UNORDERED_EMPLACE
     374             : 
     375             : #endif
     376             : 
     377             :       std::pair<iterator, bool> insert(value_type const& x)
     378             :       {
     379             :         return this->emplace(x);
     380             :       }
     381             : 
     382             :       std::pair<iterator, bool> insert(BOOST_RV_REF(value_type) x)
     383             :       {
     384             :         return this->emplace(boost::move(x));
     385             :       }
     386             : 
     387             :       template <class P2>
     388             :       std::pair<iterator, bool> insert(BOOST_RV_REF(P2) obj,
     389             :         typename boost::enable_if_c<
     390             :           boost::is_constructible<value_type, BOOST_RV_REF(P2)>::value,
     391             :           void*>::type = 0)
     392             :       {
     393             :         return this->emplace(boost::forward<P2>(obj));
     394             :       }
     395             : 
     396             :       iterator insert(const_iterator hint, value_type const& x)
     397             :       {
     398             :         return this->emplace_hint(hint, x);
     399             :       }
     400             : 
     401             :       iterator insert(const_iterator hint, BOOST_RV_REF(value_type) x)
     402             :       {
     403             :         return this->emplace_hint(hint, boost::move(x));
     404             :       }
     405             : 
     406             :       template <class P2>
     407             :       iterator insert(const_iterator hint, BOOST_RV_REF(P2) obj,
     408             :         typename boost::enable_if_c<
     409             :           boost::is_constructible<value_type, BOOST_RV_REF(P2)>::value,
     410             :           void*>::type = 0)
     411             :       {
     412             :         return this->emplace_hint(hint, boost::forward<P2>(obj));
     413             :       }
     414             : 
     415             :       template <class InputIt> void insert(InputIt, InputIt);
     416             : 
     417             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
     418             :       void insert(std::initializer_list<value_type>);
     419             : #endif
     420             : 
     421             :       // extract
     422             : 
     423             :       node_type extract(const_iterator position)
     424             :       {
     425             :         return node_type(
     426             :           table_.extract_by_iterator_unique(position), table_.node_alloc());
     427             :       }
     428             : 
     429             :       node_type extract(const key_type& k)
     430             :       {
     431             :         return node_type(table_.extract_by_key(k), table_.node_alloc());
     432             :       }
     433             : 
     434             :       insert_return_type insert(BOOST_RV_REF(node_type) np)
     435             :       {
     436             :         insert_return_type result;
     437             :         table_.move_insert_node_type_unique(np, result);
     438             :         return boost::move(result);
     439             :       }
     440             : 
     441             :       iterator insert(const_iterator hint, BOOST_RV_REF(node_type) np)
     442             :       {
     443             :         return table_.move_insert_node_type_with_hint_unique(hint, np);
     444             :       }
     445             : 
     446             : #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) ||                               \
     447             :   (BOOST_COMP_GNUC && BOOST_COMP_GNUC < BOOST_VERSION_NUMBER(4, 6, 0))
     448             :     private:
     449             :       // Note: Use r-value node_type to insert.
     450             :       insert_return_type insert(node_type&);
     451             :       iterator insert(const_iterator, node_type& np);
     452             : 
     453             :     public:
     454             : #endif
     455             : 
     456             : #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
     457             : 
     458             :       template <class... Args>
     459             :       std::pair<iterator, bool> try_emplace(
     460             :         key_type const& k, BOOST_FWD_REF(Args)... args)
     461             :       {
     462             :         return table_.try_emplace_unique(k, boost::forward<Args>(args)...);
     463             :       }
     464             : 
     465             :       template <class... Args>
     466             :       std::pair<iterator, bool> try_emplace(
     467             :         BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
     468             :       {
     469             :         return table_.try_emplace_unique(
     470             :           boost::move(k), boost::forward<Args>(args)...);
     471             :       }
     472             : 
     473             :       template <class... Args>
     474             :       iterator try_emplace(
     475             :         const_iterator hint, key_type const& k, BOOST_FWD_REF(Args)... args)
     476             :       {
     477             :         return table_.try_emplace_hint_unique(
     478             :           hint, k, boost::forward<Args>(args)...);
     479             :       }
     480             : 
     481             :       template <class... Args>
     482             :       iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k,
     483             :         BOOST_FWD_REF(Args)... args)
     484             :       {
     485             :         return table_.try_emplace_hint_unique(
     486             :           hint, boost::move(k), boost::forward<Args>(args)...);
     487             :       }
     488             : 
     489             : #else
     490             : 
     491             :       // In order to make this a template, this handles both:
     492             :       // try_emplace(key const&)
     493             :       // try_emplace(key&&)
     494             : 
     495             :       template <typename Key>
     496             :       std::pair<iterator, bool> try_emplace(BOOST_FWD_REF(Key) k)
     497             :       {
     498             :         return table_.try_emplace_unique(boost::forward<Key>(k));
     499             :       }
     500             : 
     501             :       // In order to make this a template, this handles both:
     502             :       // try_emplace(const_iterator hint, key const&)
     503             :       // try_emplace(const_iterator hint, key&&)
     504             : 
     505             :       template <typename Key>
     506             :       iterator try_emplace(const_iterator hint, BOOST_FWD_REF(Key) k)
     507             :       {
     508             :         return table_.try_emplace_hint_unique(hint, boost::forward<Key>(k));
     509             :       }
     510             : 
     511             :       // try_emplace(key const&, Args&&...)
     512             : 
     513             :       template <typename A0>
     514             :       std::pair<iterator, bool> try_emplace(
     515             :         key_type const& k, BOOST_FWD_REF(A0) a0)
     516             :       {
     517             :         return table_.try_emplace_unique(
     518             :           k, boost::unordered::detail::create_emplace_args(
     519             :                boost::forward<A0>(a0)));
     520             :       }
     521             : 
     522             :       template <typename A0, typename A1>
     523             :       std::pair<iterator, bool> try_emplace(
     524             :         key_type const& k, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
     525             :       {
     526             :         return table_.try_emplace_unique(
     527             :           k, boost::unordered::detail::create_emplace_args(
     528             :                boost::forward<A0>(a0), boost::forward<A1>(a1)));
     529             :       }
     530             : 
     531             :       template <typename A0, typename A1, typename A2>
     532             :       std::pair<iterator, bool> try_emplace(key_type const& k,
     533             :         BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
     534             :       {
     535             :         return table_.try_emplace_unique(k,
     536             :           boost::unordered::detail::create_emplace_args(boost::forward<A0>(a0),
     537             :             boost::forward<A1>(a1), boost::forward<A2>(a2)));
     538             :       }
     539             : 
     540             :       // try_emplace(key&&, Args&&...)
     541             : 
     542             :       template <typename A0>
     543             :       std::pair<iterator, bool> try_emplace(
     544             :         BOOST_RV_REF(key_type) k, BOOST_FWD_REF(A0) a0)
     545             :       {
     546             :         return table_.try_emplace_unique(
     547             :           boost::move(k), boost::unordered::detail::create_emplace_args(
     548             :                             boost::forward<A0>(a0)));
     549             :       }
     550             : 
     551             :       template <typename A0, typename A1>
     552             :       std::pair<iterator, bool> try_emplace(
     553             :         BOOST_RV_REF(key_type) k, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
     554             :       {
     555             :         return table_.try_emplace_unique(
     556             :           boost::move(k), boost::unordered::detail::create_emplace_args(
     557             :                             boost::forward<A0>(a0), boost::forward<A1>(a1)));
     558             :       }
     559             : 
     560             :       template <typename A0, typename A1, typename A2>
     561             :       std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k,
     562             :         BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
     563             :       {
     564             :         return table_.try_emplace_unique(boost::move(k),
     565             :           boost::unordered::detail::create_emplace_args(boost::forward<A0>(a0),
     566             :             boost::forward<A1>(a1), boost::forward<A2>(a2)));
     567             :       }
     568             : 
     569             :       // try_emplace(const_iterator hint, key const&, Args&&...)
     570             : 
     571             :       template <typename A0>
     572             :       iterator try_emplace(
     573             :         const_iterator hint, key_type const& k, BOOST_FWD_REF(A0) a0)
     574             :       {
     575             :         return table_.try_emplace_hint_unique(
     576             :           hint, k, boost::unordered::detail::create_emplace_args(
     577             :                      boost::forward<A0>(a0)));
     578             :       }
     579             : 
     580             :       template <typename A0, typename A1>
     581             :       iterator try_emplace(const_iterator hint, key_type const& k,
     582             :         BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
     583             :       {
     584             :         return table_.try_emplace_hint_unique(
     585             :           hint, k, boost::unordered::detail::create_emplace_args(
     586             :                      boost::forward<A0>(a0), boost::forward<A1>(a1)));
     587             :       }
     588             : 
     589             :       template <typename A0, typename A1, typename A2>
     590             :       iterator try_emplace(const_iterator hint, key_type const& k,
     591             :         BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
     592             :       {
     593             :         return table_.try_emplace_hint_unique(hint, k,
     594             :           boost::unordered::detail::create_emplace_args(boost::forward<A0>(a0),
     595             :             boost::forward<A1>(a1), boost::forward<A2>(a2)));
     596             :       }
     597             : 
     598             :       // try_emplace(const_iterator hint, key&&, Args&&...)
     599             : 
     600             :       template <typename A0>
     601             :       iterator try_emplace(
     602             :         const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(A0) a0)
     603             :       {
     604             :         return table_.try_emplace_hint_unique(
     605             :           hint, boost::move(k), boost::unordered::detail::create_emplace_args(
     606             :                                   boost::forward<A0>(a0)));
     607             :       }
     608             : 
     609             :       template <typename A0, typename A1>
     610             :       iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k,
     611             :         BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
     612             :       {
     613             :         return table_.try_emplace_hint_unique(hint, boost::move(k),
     614             :           boost::unordered::detail::create_emplace_args(
     615             :             boost::forward<A0>(a0), boost::forward<A1>(a1)));
     616             :       }
     617             : 
     618             :       template <typename A0, typename A1, typename A2>
     619             :       iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k,
     620             :         BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
     621             :       {
     622             :         return table_.try_emplace_hint_unique(hint, boost::move(k),
     623             :           boost::unordered::detail::create_emplace_args(boost::forward<A0>(a0),
     624             :             boost::forward<A1>(a1), boost::forward<A2>(a2)));
     625             :       }
     626             : 
     627             : #define BOOST_UNORDERED_TRY_EMPLACE(z, n, _)                                   \
     628             :                                                                                \
     629             :   template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                          \
     630             :   std::pair<iterator, bool> try_emplace(                                       \
     631             :     key_type const& k, BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a))     \
     632             :   {                                                                            \
     633             :     return table_.try_emplace_unique(                                          \
     634             :       k, boost::unordered::detail::create_emplace_args(                        \
     635             :            BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a)));            \
     636             :   }                                                                            \
     637             :                                                                                \
     638             :   template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                          \
     639             :   std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k,              \
     640             :     BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a))                        \
     641             :   {                                                                            \
     642             :     return table_.try_emplace_unique(boost::move(k),                           \
     643             :       boost::unordered::detail::create_emplace_args(                           \
     644             :         BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a)));               \
     645             :   }                                                                            \
     646             :                                                                                \
     647             :   template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                          \
     648             :   iterator try_emplace(const_iterator hint, key_type const& k,                 \
     649             :     BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a))                        \
     650             :   {                                                                            \
     651             :     return table_.try_emplace_hint_unique(                                     \
     652             :       hint, k, boost::unordered::detail::create_emplace_args(                  \
     653             :                  BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a)));      \
     654             :   }                                                                            \
     655             :                                                                                \
     656             :   template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                          \
     657             :   iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k,          \
     658             :     BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a))                        \
     659             :   {                                                                            \
     660             :     return table_.try_emplace_hint_unique(hint, boost::move(k),                \
     661             :       boost::unordered::detail::create_emplace_args(                           \
     662             :         BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a)));               \
     663             :   }
     664             : 
     665             :       BOOST_UNORDERED_TRY_EMPLACE(1, 4, _)
     666             :       BOOST_UNORDERED_TRY_EMPLACE(1, 5, _)
     667             :       BOOST_UNORDERED_TRY_EMPLACE(1, 6, _)
     668             :       BOOST_UNORDERED_TRY_EMPLACE(1, 7, _)
     669             :       BOOST_UNORDERED_TRY_EMPLACE(1, 8, _)
     670             :       BOOST_UNORDERED_TRY_EMPLACE(1, 9, _)
     671             :       BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
     672             :         BOOST_UNORDERED_TRY_EMPLACE, _)
     673             : 
     674             : #undef BOOST_UNORDERED_TRY_EMPLACE
     675             : 
     676             : #endif
     677             : 
     678             :       template <class M>
     679             :       std::pair<iterator, bool> insert_or_assign(
     680             :         key_type const& k, BOOST_FWD_REF(M) obj)
     681             :       {
     682             :         return table_.insert_or_assign_unique(k, boost::forward<M>(obj));
     683             :       }
     684             : 
     685             :       template <class M>
     686             :       std::pair<iterator, bool> insert_or_assign(
     687             :         BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
     688             :       {
     689             :         return table_.insert_or_assign_unique(
     690             :           boost::move(k), boost::forward<M>(obj));
     691             :       }
     692             : 
     693             :       template <class M>
     694             :       iterator insert_or_assign(
     695             :         const_iterator, key_type const& k, BOOST_FWD_REF(M) obj)
     696             :       {
     697             :         return table_.insert_or_assign_unique(k, boost::forward<M>(obj)).first;
     698             :       }
     699             : 
     700             :       template <class M>
     701             :       iterator insert_or_assign(
     702             :         const_iterator, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
     703             :       {
     704             :         return table_
     705             :           .insert_or_assign_unique(boost::move(k), boost::forward<M>(obj))
     706             :           .first;
     707             :       }
     708             : 
     709             :       iterator erase(iterator);
     710             :       iterator erase(const_iterator);
     711             :       size_type erase(const key_type&);
     712             :       iterator erase(const_iterator, const_iterator);
     713             :       BOOST_UNORDERED_DEPRECATED("Use erase instead")
     714             :       void quick_erase(const_iterator it) { erase(it); }
     715             :       BOOST_UNORDERED_DEPRECATED("Use erase instead")
     716             :       void erase_return_void(const_iterator it) { erase(it); }
     717             : 
     718             :       void swap(unordered_map&)
     719             :         BOOST_NOEXCEPT_IF(value_allocator_traits::is_always_equal::value&&
     720             :             boost::is_nothrow_swappable<H>::value&&
     721             :               boost::is_nothrow_swappable<P>::value);
     722           1 :       void clear() BOOST_NOEXCEPT { table_.clear_impl(); }
     723             : 
     724             :       template <typename H2, typename P2>
     725             :       void merge(boost::unordered_map<K, T, H2, P2, A>& source);
     726             : 
     727             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
     728             :       template <typename H2, typename P2>
     729             :       void merge(boost::unordered_map<K, T, H2, P2, A>&& source);
     730             : #endif
     731             : 
     732             :       template <typename H2, typename P2>
     733             :       void merge(boost::unordered_multimap<K, T, H2, P2, A>& source);
     734             : 
     735             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
     736             :       template <typename H2, typename P2>
     737             :       void merge(boost::unordered_multimap<K, T, H2, P2, A>&& source);
     738             : #endif
     739             : 
     740             :       // observers
     741             : 
     742             :       hasher hash_function() const;
     743             :       key_equal key_eq() const;
     744             : 
     745             :       // lookup
     746             : 
     747             :       iterator find(const key_type&);
     748             :       const_iterator find(const key_type&) const;
     749             : 
     750             :       template <class CompatibleKey, class CompatibleHash,
     751             :         class CompatiblePredicate>
     752             :       iterator find(CompatibleKey const&, CompatibleHash const&,
     753             :         CompatiblePredicate const&);
     754             : 
     755             :       template <class CompatibleKey, class CompatibleHash,
     756             :         class CompatiblePredicate>
     757             :       const_iterator find(CompatibleKey const&, CompatibleHash const&,
     758             :         CompatiblePredicate const&) const;
     759             : 
     760             :       size_type count(const key_type&) const;
     761             : 
     762             :       std::pair<iterator, iterator> equal_range(const key_type&);
     763             :       std::pair<const_iterator, const_iterator> equal_range(
     764             :         const key_type&) const;
     765             : 
     766             :       mapped_type& operator[](const key_type&);
     767             :       mapped_type& operator[](BOOST_RV_REF(key_type));
     768             :       mapped_type& at(const key_type&);
     769             :       mapped_type const& at(const key_type&) const;
     770             : 
     771             :       // bucket interface
     772             : 
     773             :       size_type bucket_count() const BOOST_NOEXCEPT
     774             :       {
     775             :         return table_.bucket_count_;
     776             :       }
     777             : 
     778             :       size_type max_bucket_count() const BOOST_NOEXCEPT
     779             :       {
     780             :         return table_.max_bucket_count();
     781             :       }
     782             : 
     783             :       size_type bucket_size(size_type) const;
     784             : 
     785             :       size_type bucket(const key_type& k) const
     786             :       {
     787             :         return table_.hash_to_bucket(table_.hash(k));
     788             :       }
     789             : 
     790             :       local_iterator begin(size_type n)
     791             :       {
     792             :         return local_iterator(table_.begin(n), n, table_.bucket_count_);
     793             :       }
     794             : 
     795             :       const_local_iterator begin(size_type n) const
     796             :       {
     797             :         return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
     798             :       }
     799             : 
     800             :       local_iterator end(size_type) { return local_iterator(); }
     801             : 
     802             :       const_local_iterator end(size_type) const
     803             :       {
     804             :         return const_local_iterator();
     805             :       }
     806             : 
     807             :       const_local_iterator cbegin(size_type n) const
     808             :       {
     809             :         return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
     810             :       }
     811             : 
     812             :       const_local_iterator cend(size_type) const
     813             :       {
     814             :         return const_local_iterator();
     815             :       }
     816             : 
     817             :       // hash policy
     818             : 
     819             :       float load_factor() const BOOST_NOEXCEPT;
     820             :       float max_load_factor() const BOOST_NOEXCEPT { return table_.mlf_; }
     821             :       void max_load_factor(float) BOOST_NOEXCEPT;
     822             :       void rehash(size_type);
     823             :       void reserve(size_type);
     824             : 
     825             : #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
     826             :       friend bool operator==
     827             :         <K, T, H, P, A>(unordered_map const&, unordered_map const&);
     828             :       friend bool operator!=
     829             :         <K, T, H, P, A>(unordered_map const&, unordered_map const&);
     830             : #endif
     831             :     }; // class template unordered_map
     832             : 
     833             : #if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
     834             : 
     835             :     namespace detail {
     836             :       template <typename T>
     837             :       using iter_key_t =
     838             :         typename std::iterator_traits<T>::value_type::first_type;
     839             :       template <typename T>
     840             :       using iter_val_t =
     841             :         typename std::iterator_traits<T>::value_type::second_type;
     842             :       template <typename T>
     843             :       using iter_to_alloc_t =
     844             :         typename std::pair<iter_key_t<T> const, iter_val_t<T> >;
     845             :     }
     846             : 
     847             :     template <class InputIterator,
     848             :       class Hash =
     849             :         boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
     850             :       class Pred =
     851             :         std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
     852             :       class Allocator = std::allocator<
     853             :         boost::unordered::detail::iter_to_alloc_t<InputIterator> > >
     854             :     unordered_map(InputIterator, InputIterator,
     855             :       std::size_t = boost::unordered::detail::default_bucket_count,
     856             :       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
     857             :       ->unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
     858             :         boost::unordered::detail::iter_val_t<InputIterator>, Hash, Pred,
     859             :         Allocator>;
     860             : 
     861             :     template <class Key, class T, class Hash = boost::hash<Key>,
     862             :       class Pred = std::equal_to<Key>,
     863             :       class Allocator = std::allocator<std::pair<const Key, T> > >
     864             :     unordered_map(std::initializer_list<std::pair<const Key, T> >,
     865             :       std::size_t = boost::unordered::detail::default_bucket_count,
     866             :       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
     867             :       ->unordered_map<Key, T, Hash, Pred, Allocator>;
     868             : 
     869             :     template <class InputIterator, class Allocator>
     870             :     unordered_map(InputIterator, InputIterator, std::size_t, Allocator)
     871             :       ->unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
     872             :         boost::unordered::detail::iter_val_t<InputIterator>,
     873             :         boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
     874             :         std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
     875             :         Allocator>;
     876             : 
     877             :     template <class InputIterator, class Allocator>
     878             :     unordered_map(InputIterator, InputIterator, Allocator)
     879             :       ->unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
     880             :         boost::unordered::detail::iter_val_t<InputIterator>,
     881             :         boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
     882             :         std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
     883             :         Allocator>;
     884             : 
     885             :     template <class InputIterator, class Hash, class Allocator>
     886             :     unordered_map(InputIterator, InputIterator, std::size_t, Hash, Allocator)
     887             :       ->unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
     888             :         boost::unordered::detail::iter_val_t<InputIterator>, Hash,
     889             :         std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
     890             :         Allocator>;
     891             : 
     892             :     template <class Key, class T, typename Allocator>
     893             :     unordered_map(
     894             :       std::initializer_list<std::pair<const Key, T> >, std::size_t, Allocator)
     895             :       ->unordered_map<Key, T, boost::hash<Key>, std::equal_to<Key>, Allocator>;
     896             : 
     897             :     template <class Key, class T, typename Allocator>
     898             :     unordered_map(std::initializer_list<std::pair<const Key, T> >, Allocator)
     899             :       ->unordered_map<Key, T, boost::hash<Key>, std::equal_to<Key>, Allocator>;
     900             : 
     901             :     template <class Key, class T, class Hash, class Allocator>
     902             :     unordered_map(std::initializer_list<std::pair<const Key, T> >, std::size_t,
     903             :       Hash, Allocator)
     904             :       ->unordered_map<Key, T, Hash, std::equal_to<Key>, Allocator>;
     905             : 
     906             : #endif
     907             : 
     908             :     template <class K, class T, class H, class P, class A>
     909             :     class unordered_multimap
     910             :     {
     911             : #if defined(BOOST_UNORDERED_USE_MOVE)
     912             :       BOOST_COPYABLE_AND_MOVABLE(unordered_multimap)
     913             : #endif
     914             :       template <typename, typename, typename, typename, typename>
     915             :       friend class unordered_map;
     916             : 
     917             :     public:
     918             :       typedef K key_type;
     919             :       typedef T mapped_type;
     920             :       typedef std::pair<const K, T> value_type;
     921             :       typedef H hasher;
     922             :       typedef P key_equal;
     923             :       typedef A allocator_type;
     924             : 
     925             :     private:
     926             :       typedef boost::unordered::detail::map<A, K, T, H, P> types;
     927             :       typedef typename types::value_allocator_traits value_allocator_traits;
     928             :       typedef typename types::table table;
     929             :       typedef typename table::node_pointer node_pointer;
     930             :       typedef typename table::link_pointer link_pointer;
     931             : 
     932             :     public:
     933             :       typedef typename value_allocator_traits::pointer pointer;
     934             :       typedef typename value_allocator_traits::const_pointer const_pointer;
     935             : 
     936             :       typedef value_type& reference;
     937             :       typedef value_type const& const_reference;
     938             : 
     939             :       typedef std::size_t size_type;
     940             :       typedef std::ptrdiff_t difference_type;
     941             : 
     942             :       typedef typename table::iterator iterator;
     943             :       typedef typename table::c_iterator const_iterator;
     944             :       typedef typename table::l_iterator local_iterator;
     945             :       typedef typename table::cl_iterator const_local_iterator;
     946             :       typedef typename types::node_type node_type;
     947             : 
     948             :     private:
     949             :       table table_;
     950             : 
     951             :     public:
     952             :       // constructors
     953             : 
     954             :       unordered_multimap();
     955             : 
     956             :       explicit unordered_multimap(size_type, const hasher& = hasher(),
     957             :         const key_equal& = key_equal(),
     958             :         const allocator_type& = allocator_type());
     959             : 
     960             :       template <class InputIt>
     961             :       unordered_multimap(InputIt, InputIt,
     962             :         size_type = boost::unordered::detail::default_bucket_count,
     963             :         const hasher& = hasher(), const key_equal& = key_equal(),
     964             :         const allocator_type& = allocator_type());
     965             : 
     966             :       unordered_multimap(unordered_multimap const&);
     967             : 
     968             : #if defined(BOOST_UNORDERED_USE_MOVE) ||                                       \
     969             :   !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
     970             :       unordered_multimap(BOOST_RV_REF(unordered_multimap) other)
     971             :         BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
     972             :           : table_(other.table_, boost::unordered::detail::move_tag())
     973             :       {
     974             :         // The move is done in table_
     975             :       }
     976             : #endif
     977             : 
     978             :       explicit unordered_multimap(allocator_type const&);
     979             : 
     980             :       unordered_multimap(unordered_multimap const&, allocator_type const&);
     981             : 
     982             :       unordered_multimap(
     983             :         BOOST_RV_REF(unordered_multimap), allocator_type const&);
     984             : 
     985             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
     986             :       unordered_multimap(std::initializer_list<value_type>,
     987             :         size_type = boost::unordered::detail::default_bucket_count,
     988             :         const hasher& = hasher(), const key_equal& l = key_equal(),
     989             :         const allocator_type& = allocator_type());
     990             : #endif
     991             : 
     992             :       explicit unordered_multimap(size_type, const allocator_type&);
     993             : 
     994             :       explicit unordered_multimap(
     995             :         size_type, const hasher&, const allocator_type&);
     996             : 
     997             :       template <class InputIt>
     998             :       unordered_multimap(InputIt, InputIt, size_type, const allocator_type&);
     999             : 
    1000             :       template <class InputIt>
    1001             :       unordered_multimap(
    1002             :         InputIt, InputIt, size_type, const hasher&, const allocator_type&);
    1003             : 
    1004             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    1005             :       unordered_multimap(
    1006             :         std::initializer_list<value_type>, size_type, const allocator_type&);
    1007             : 
    1008             :       unordered_multimap(std::initializer_list<value_type>, size_type,
    1009             :         const hasher&, const allocator_type&);
    1010             : #endif
    1011             : 
    1012             :       // Destructor
    1013             : 
    1014             :       ~unordered_multimap() BOOST_NOEXCEPT;
    1015             : 
    1016             : // Assign
    1017             : 
    1018             : #if defined(BOOST_UNORDERED_USE_MOVE)
    1019             :       unordered_multimap& operator=(BOOST_COPY_ASSIGN_REF(unordered_multimap) x)
    1020             :       {
    1021             :         table_.assign(x.table_, boost::unordered::detail::false_type());
    1022             :         return *this;
    1023             :       }
    1024             : 
    1025             :       unordered_multimap& operator=(BOOST_RV_REF(unordered_multimap) x)
    1026             :         BOOST_NOEXCEPT_IF(value_allocator_traits::is_always_equal::value&&
    1027             :             boost::is_nothrow_move_assignable<H>::value&&
    1028             :               boost::is_nothrow_move_assignable<P>::value)
    1029             :       {
    1030             :         table_.move_assign(x.table_, boost::unordered::detail::false_type());
    1031             :         return *this;
    1032             :       }
    1033             : #else
    1034           0 :       unordered_multimap& operator=(unordered_multimap const& x)
    1035             :       {
    1036           0 :         table_.assign(x.table_, boost::unordered::detail::false_type());
    1037             :         return *this;
    1038             :       }
    1039             : 
    1040             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    1041             :       unordered_multimap& operator=(unordered_multimap&& x)
    1042             :         BOOST_NOEXCEPT_IF(value_allocator_traits::is_always_equal::value&&
    1043             :             boost::is_nothrow_move_assignable<H>::value&&
    1044             :               boost::is_nothrow_move_assignable<P>::value)
    1045             :       {
    1046             :         table_.move_assign(x.table_, boost::unordered::detail::false_type());
    1047             :         return *this;
    1048             :       }
    1049             : #endif
    1050             : #endif
    1051             : 
    1052             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    1053             :       unordered_multimap& operator=(std::initializer_list<value_type>);
    1054             : #endif
    1055             : 
    1056           0 :       allocator_type get_allocator() const BOOST_NOEXCEPT
    1057             :       {
    1058           0 :         return table_.node_alloc();
    1059             :       }
    1060             : 
    1061             :       // iterators
    1062             : 
    1063      695285 :       iterator begin() BOOST_NOEXCEPT { return iterator(table_.begin()); }
    1064             : 
    1065           0 :       const_iterator begin() const BOOST_NOEXCEPT
    1066             :       {
    1067           0 :         return const_iterator(table_.begin());
    1068             :       }
    1069             : 
    1070    43456296 :       iterator end() BOOST_NOEXCEPT { return iterator(); }
    1071             : 
    1072           0 :       const_iterator end() const BOOST_NOEXCEPT { return const_iterator(); }
    1073             : 
    1074             :       const_iterator cbegin() const BOOST_NOEXCEPT
    1075             :       {
    1076             :         return const_iterator(table_.begin());
    1077             :       }
    1078             : 
    1079             :       const_iterator cend() const BOOST_NOEXCEPT { return const_iterator(); }
    1080             : 
    1081             :       // size and capacity
    1082             : 
    1083         192 :       bool empty() const BOOST_NOEXCEPT { return table_.size_ == 0; }
    1084             : 
    1085     2482929 :       size_type size() const BOOST_NOEXCEPT { return table_.size_; }
    1086             : 
    1087             :       size_type max_size() const BOOST_NOEXCEPT;
    1088             : 
    1089             : // emplace
    1090             : 
    1091             : #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
    1092             : 
    1093     2448950 :       template <class... Args> iterator emplace(BOOST_FWD_REF(Args)... args)
    1094             :       {
    1095     2448950 :         return iterator(table_.emplace_equiv(
    1096     2448950 :           boost::unordered::detail::func::construct_node_from_args(
    1097             :             table_.node_alloc(), boost::forward<Args>(args)...)));
    1098             :       }
    1099             : 
    1100             : #else
    1101             : 
    1102             : #if !BOOST_UNORDERED_SUN_WORKAROUNDS1
    1103             : 
    1104             :       // 0 argument emplace requires special treatment in case
    1105             :       // the container is instantiated with a value type that
    1106             :       // doesn't have a default constructor.
    1107             : 
    1108             :       iterator emplace(boost::unordered::detail::empty_emplace =
    1109             :                          boost::unordered::detail::empty_emplace(),
    1110             :         value_type v = value_type())
    1111             :       {
    1112             :         return this->emplace(boost::move(v));
    1113             :       }
    1114             : 
    1115             : #endif
    1116             : 
    1117             :       template <typename A0> iterator emplace(BOOST_FWD_REF(A0) a0)
    1118             :       {
    1119             :         return iterator(table_.emplace_equiv(
    1120             :           boost::unordered::detail::func::construct_node_from_args(
    1121             :             table_.node_alloc(), boost::unordered::detail::create_emplace_args(
    1122             :                                    boost::forward<A0>(a0)))));
    1123             :       }
    1124             : 
    1125             :       template <typename A0, typename A1>
    1126             :       iterator emplace(BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
    1127             :       {
    1128             :         return iterator(table_.emplace_equiv(
    1129             :           boost::unordered::detail::func::construct_node_from_args(
    1130             :             table_.node_alloc(),
    1131             :             boost::unordered::detail::create_emplace_args(
    1132             :               boost::forward<A0>(a0), boost::forward<A1>(a1)))));
    1133             :       }
    1134             : 
    1135             :       template <typename A0, typename A1, typename A2>
    1136             :       iterator emplace(
    1137             :         BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
    1138             :       {
    1139             :         return iterator(table_.emplace_equiv(
    1140             :           boost::unordered::detail::func::construct_node_from_args(
    1141             :             table_.node_alloc(),
    1142             :             boost::unordered::detail::create_emplace_args(
    1143             :               boost::forward<A0>(a0), boost::forward<A1>(a1),
    1144             :               boost::forward<A2>(a2)))));
    1145             :       }
    1146             : 
    1147             : #endif
    1148             : 
    1149             : #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
    1150             : 
    1151             :       template <class... Args>
    1152             :       iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
    1153             :       {
    1154             :         return iterator(table_.emplace_hint_equiv(
    1155             :           hint, boost::unordered::detail::func::construct_node_from_args(
    1156             :                   table_.node_alloc(), boost::forward<Args>(args)...)));
    1157             :       }
    1158             : 
    1159             : #else
    1160             : 
    1161             : #if !BOOST_UNORDERED_SUN_WORKAROUNDS1
    1162             : 
    1163             :       iterator emplace_hint(const_iterator hint,
    1164             :         boost::unordered::detail::empty_emplace =
    1165             :           boost::unordered::detail::empty_emplace(),
    1166             :         value_type v = value_type())
    1167             :       {
    1168             :         return this->emplace_hint(hint, boost::move(v));
    1169             :       }
    1170             : 
    1171             : #endif
    1172             : 
    1173             :       template <typename A0>
    1174             :       iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
    1175             :       {
    1176             :         return iterator(table_.emplace_hint_equiv(hint,
    1177             :           boost::unordered::detail::func::construct_node_from_args(
    1178             :             table_.node_alloc(), boost::unordered::detail::create_emplace_args(
    1179             :                                    boost::forward<A0>(a0)))));
    1180             :       }
    1181             : 
    1182             :       template <typename A0, typename A1>
    1183             :       iterator emplace_hint(
    1184             :         const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
    1185             :       {
    1186             :         return iterator(table_.emplace_hint_equiv(
    1187             :           hint, boost::unordered::detail::func::construct_node_from_args(
    1188             :                   table_.node_alloc(),
    1189             :                   boost::unordered::detail::create_emplace_args(
    1190             :                     boost::forward<A0>(a0), boost::forward<A1>(a1)))));
    1191             :       }
    1192             : 
    1193             :       template <typename A0, typename A1, typename A2>
    1194             :       iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0,
    1195             :         BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
    1196             :       {
    1197             :         return iterator(table_.emplace_hint_equiv(
    1198             :           hint, boost::unordered::detail::func::construct_node_from_args(
    1199             :                   table_.node_alloc(),
    1200             :                   boost::unordered::detail::create_emplace_args(
    1201             :                     boost::forward<A0>(a0), boost::forward<A1>(a1),
    1202             :                     boost::forward<A2>(a2)))));
    1203             :       }
    1204             : 
    1205             : #endif
    1206             : 
    1207             : #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
    1208             : 
    1209             : #define BOOST_UNORDERED_EMPLACE(z, n, _)                                       \
    1210             :   template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                          \
    1211             :   iterator emplace(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a))         \
    1212             :   {                                                                            \
    1213             :     return iterator(table_.emplace_equiv(                                      \
    1214             :       boost::unordered::detail::func::construct_node_from_args(                \
    1215             :         table_.node_alloc(),                                                   \
    1216             :         boost::unordered::detail::create_emplace_args(                         \
    1217             :           BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a)))));           \
    1218             :   }                                                                            \
    1219             :                                                                                \
    1220             :   template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                          \
    1221             :   iterator emplace_hint(                                                       \
    1222             :     const_iterator hint, BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a))   \
    1223             :   {                                                                            \
    1224             :     return iterator(table_.emplace_hint_equiv(                                 \
    1225             :       hint, boost::unordered::detail::func::construct_node_from_args(          \
    1226             :               table_.node_alloc(),                                             \
    1227             :               boost::unordered::detail::create_emplace_args(                   \
    1228             :                 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a)))));     \
    1229             :   }
    1230             : 
    1231             :       BOOST_UNORDERED_EMPLACE(1, 4, _)
    1232             :       BOOST_UNORDERED_EMPLACE(1, 5, _)
    1233             :       BOOST_UNORDERED_EMPLACE(1, 6, _)
    1234             :       BOOST_UNORDERED_EMPLACE(1, 7, _)
    1235             :       BOOST_UNORDERED_EMPLACE(1, 8, _)
    1236             :       BOOST_UNORDERED_EMPLACE(1, 9, _)
    1237             :       BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
    1238             :         BOOST_UNORDERED_EMPLACE, _)
    1239             : 
    1240             : #undef BOOST_UNORDERED_EMPLACE
    1241             : 
    1242             : #endif
    1243             : 
    1244             :       iterator insert(value_type const& x) { return this->emplace(x); }
    1245             : 
    1246     2448950 :       iterator insert(BOOST_RV_REF(value_type) x)
    1247             :       {
    1248     2448950 :         return this->emplace(boost::move(x));
    1249             :       }
    1250             : 
    1251             :       template <class P2>
    1252             :       iterator insert(BOOST_RV_REF(P2) obj,
    1253             :         typename boost::enable_if_c<
    1254             :           boost::is_constructible<value_type, BOOST_RV_REF(P2)>::value,
    1255             :           void*>::type = 0)
    1256             :       {
    1257             :         return this->emplace(boost::forward<P2>(obj));
    1258             :       }
    1259             : 
    1260             :       iterator insert(const_iterator hint, value_type const& x)
    1261             :       {
    1262             :         return this->emplace_hint(hint, x);
    1263             :       }
    1264             : 
    1265             :       iterator insert(const_iterator hint, BOOST_RV_REF(value_type) x)
    1266             :       {
    1267             :         return this->emplace_hint(hint, boost::move(x));
    1268             :       }
    1269             : 
    1270             :       template <class P2>
    1271             :       iterator insert(const_iterator hint, BOOST_RV_REF(P2) obj,
    1272             :         typename boost::enable_if_c<
    1273             :           boost::is_constructible<value_type, BOOST_RV_REF(P2)>::value,
    1274             :           void*>::type = 0)
    1275             :       {
    1276             :         return this->emplace_hint(hint, boost::forward<P2>(obj));
    1277             :       }
    1278             : 
    1279             :       template <class InputIt> void insert(InputIt, InputIt);
    1280             : 
    1281             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    1282             :       void insert(std::initializer_list<value_type>);
    1283             : #endif
    1284             : 
    1285             :       // extract
    1286             : 
    1287             :       node_type extract(const_iterator position)
    1288             :       {
    1289             :         return node_type(
    1290             :           table_.extract_by_iterator_equiv(position), table_.node_alloc());
    1291             :       }
    1292             : 
    1293             :       node_type extract(const key_type& k)
    1294             :       {
    1295             :         return node_type(table_.extract_by_key(k), table_.node_alloc());
    1296             :       }
    1297             : 
    1298             :       iterator insert(BOOST_RV_REF(node_type) np)
    1299             :       {
    1300             :         return table_.move_insert_node_type_equiv(np);
    1301             :       }
    1302             : 
    1303             :       iterator insert(const_iterator hint, BOOST_RV_REF(node_type) np)
    1304             :       {
    1305             :         return table_.move_insert_node_type_with_hint_equiv(hint, np);
    1306             :       }
    1307             : 
    1308             : #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) ||                               \
    1309             :   (BOOST_COMP_GNUC && BOOST_COMP_GNUC < BOOST_VERSION_NUMBER(4, 6, 0))
    1310             :     private:
    1311             :       // Note: Use r-value node_type to insert.
    1312             :       iterator insert(node_type&);
    1313             :       iterator insert(const_iterator, node_type& np);
    1314             : 
    1315             :     public:
    1316             : #endif
    1317             : 
    1318             :       iterator erase(iterator);
    1319             :       iterator erase(const_iterator);
    1320             :       size_type erase(const key_type&);
    1321             :       iterator erase(const_iterator, const_iterator);
    1322             :       BOOST_UNORDERED_DEPRECATED("Use erase instead")
    1323             :       void quick_erase(const_iterator it) { erase(it); }
    1324             :       BOOST_UNORDERED_DEPRECATED("Use erase instead")
    1325             :       void erase_return_void(const_iterator it) { erase(it); }
    1326             : 
    1327             :       void swap(unordered_multimap&)
    1328             :         BOOST_NOEXCEPT_IF(value_allocator_traits::is_always_equal::value&&
    1329             :             boost::is_nothrow_swappable<H>::value&&
    1330             :               boost::is_nothrow_swappable<P>::value);
    1331       54458 :       void clear() BOOST_NOEXCEPT { table_.clear_impl(); }
    1332             : 
    1333             :       template <typename H2, typename P2>
    1334             :       void merge(boost::unordered_multimap<K, T, H2, P2, A>& source);
    1335             : 
    1336             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    1337             :       template <typename H2, typename P2>
    1338             :       void merge(boost::unordered_multimap<K, T, H2, P2, A>&& source);
    1339             : #endif
    1340             : 
    1341             :       template <typename H2, typename P2>
    1342             :       void merge(boost::unordered_map<K, T, H2, P2, A>& source);
    1343             : 
    1344             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    1345             :       template <typename H2, typename P2>
    1346             :       void merge(boost::unordered_map<K, T, H2, P2, A>&& source);
    1347             : #endif
    1348             : 
    1349             :       // observers
    1350             : 
    1351             :       hasher hash_function() const;
    1352             :       key_equal key_eq() const;
    1353             : 
    1354             :       // lookup
    1355             : 
    1356             :       iterator find(const key_type&);
    1357             :       const_iterator find(const key_type&) const;
    1358             : 
    1359             :       template <class CompatibleKey, class CompatibleHash,
    1360             :         class CompatiblePredicate>
    1361             :       iterator find(CompatibleKey const&, CompatibleHash const&,
    1362             :         CompatiblePredicate const&);
    1363             : 
    1364             :       template <class CompatibleKey, class CompatibleHash,
    1365             :         class CompatiblePredicate>
    1366             :       const_iterator find(CompatibleKey const&, CompatibleHash const&,
    1367             :         CompatiblePredicate const&) const;
    1368             : 
    1369             :       size_type count(const key_type&) const;
    1370             : 
    1371             :       std::pair<iterator, iterator> equal_range(const key_type&);
    1372             :       std::pair<const_iterator, const_iterator> equal_range(
    1373             :         const key_type&) const;
    1374             : 
    1375             :       // bucket interface
    1376             : 
    1377           0 :       size_type bucket_count() const BOOST_NOEXCEPT
    1378             :       {
    1379             :         return table_.bucket_count_;
    1380             :       }
    1381             : 
    1382             :       size_type max_bucket_count() const BOOST_NOEXCEPT
    1383             :       {
    1384             :         return table_.max_bucket_count();
    1385             :       }
    1386             : 
    1387             :       size_type bucket_size(size_type) const;
    1388             : 
    1389             :       size_type bucket(const key_type& k) const
    1390             :       {
    1391             :         return table_.hash_to_bucket(table_.hash(k));
    1392             :       }
    1393             : 
    1394             :       local_iterator begin(size_type n)
    1395             :       {
    1396             :         return local_iterator(table_.begin(n), n, table_.bucket_count_);
    1397             :       }
    1398             : 
    1399             :       const_local_iterator begin(size_type n) const
    1400             :       {
    1401             :         return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
    1402             :       }
    1403             : 
    1404             :       local_iterator end(size_type) { return local_iterator(); }
    1405             : 
    1406             :       const_local_iterator end(size_type) const
    1407             :       {
    1408             :         return const_local_iterator();
    1409             :       }
    1410             : 
    1411             :       const_local_iterator cbegin(size_type n) const
    1412             :       {
    1413             :         return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
    1414             :       }
    1415             : 
    1416             :       const_local_iterator cend(size_type) const
    1417             :       {
    1418             :         return const_local_iterator();
    1419             :       }
    1420             : 
    1421             :       // hash policy
    1422             : 
    1423             :       float load_factor() const BOOST_NOEXCEPT;
    1424           0 :       float max_load_factor() const BOOST_NOEXCEPT { return table_.mlf_; }
    1425             :       void max_load_factor(float) BOOST_NOEXCEPT;
    1426             :       void rehash(size_type);
    1427             :       void reserve(size_type);
    1428             : 
    1429             : #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
    1430             :       friend bool operator==
    1431             :         <K, T, H, P, A>(unordered_multimap const&, unordered_multimap const&);
    1432             :       friend bool operator!=
    1433             :         <K, T, H, P, A>(unordered_multimap const&, unordered_multimap const&);
    1434             : #endif
    1435             :     }; // class template unordered_multimap
    1436             : 
    1437             : #if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
    1438             : 
    1439             :     template <class InputIterator,
    1440             :       class Hash =
    1441             :         boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
    1442             :       class Pred =
    1443             :         std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
    1444             :       class Allocator = std::allocator<
    1445             :         boost::unordered::detail::iter_to_alloc_t<InputIterator> > >
    1446             :     unordered_multimap(InputIterator, InputIterator,
    1447             :       std::size_t = boost::unordered::detail::default_bucket_count,
    1448             :       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
    1449             :       ->unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
    1450             :         boost::unordered::detail::iter_val_t<InputIterator>, Hash, Pred,
    1451             :         Allocator>;
    1452             : 
    1453             :     template <class Key, class T, class Hash = boost::hash<Key>,
    1454             :       class Pred = std::equal_to<Key>,
    1455             :       class Allocator = std::allocator<std::pair<const Key, T> > >
    1456             :     unordered_multimap(std::initializer_list<std::pair<const Key, T> >,
    1457             :       std::size_t = boost::unordered::detail::default_bucket_count,
    1458             :       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
    1459             :       ->unordered_multimap<Key, T, Hash, Pred, Allocator>;
    1460             : 
    1461             :     template <class InputIterator, class Allocator>
    1462             :     unordered_multimap(InputIterator, InputIterator, std::size_t, Allocator)
    1463             :       ->unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
    1464             :         boost::unordered::detail::iter_val_t<InputIterator>,
    1465             :         boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
    1466             :         std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
    1467             :         Allocator>;
    1468             : 
    1469             :     template <class InputIterator, class Allocator>
    1470             :     unordered_multimap(InputIterator, InputIterator, Allocator)
    1471             :       ->unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
    1472             :         boost::unordered::detail::iter_val_t<InputIterator>,
    1473             :         boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
    1474             :         std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
    1475             :         Allocator>;
    1476             : 
    1477             :     template <class InputIterator, class Hash, class Allocator>
    1478             :     unordered_multimap(
    1479             :       InputIterator, InputIterator, std::size_t, Hash, Allocator)
    1480             :       ->unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
    1481             :         boost::unordered::detail::iter_val_t<InputIterator>, Hash,
    1482             :         std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
    1483             :         Allocator>;
    1484             : 
    1485             :     template <class Key, class T, typename Allocator>
    1486             :     unordered_multimap(
    1487             :       std::initializer_list<std::pair<const Key, T> >, std::size_t, Allocator)
    1488             :       ->unordered_multimap<Key, T, boost::hash<Key>, std::equal_to<Key>,
    1489             :         Allocator>;
    1490             : 
    1491             :     template <class Key, class T, typename Allocator>
    1492             :     unordered_multimap(
    1493             :       std::initializer_list<std::pair<const Key, T> >, Allocator)
    1494             :       ->unordered_multimap<Key, T, boost::hash<Key>, std::equal_to<Key>,
    1495             :         Allocator>;
    1496             : 
    1497             :     template <class Key, class T, class Hash, class Allocator>
    1498             :     unordered_multimap(std::initializer_list<std::pair<const Key, T> >,
    1499             :       std::size_t, Hash, Allocator)
    1500             :       ->unordered_multimap<Key, T, Hash, std::equal_to<Key>, Allocator>;
    1501             : 
    1502             : #endif
    1503             : 
    1504             :     ////////////////////////////////////////////////////////////////////////////
    1505             : 
    1506             :     template <class K, class T, class H, class P, class A>
    1507           1 :     unordered_map<K, T, H, P, A>::unordered_map()
    1508             :         : table_(boost::unordered::detail::default_bucket_count, hasher(),
    1509           1 :             key_equal(), allocator_type())
    1510             :     {
    1511           0 :     }
    1512             : 
    1513             :     template <class K, class T, class H, class P, class A>
    1514             :     unordered_map<K, T, H, P, A>::unordered_map(size_type n, const hasher& hf,
    1515             :       const key_equal& eql, const allocator_type& a)
    1516             :         : table_(n, hf, eql, a)
    1517             :     {
    1518             :     }
    1519             : 
    1520             :     template <class K, class T, class H, class P, class A>
    1521             :     template <class InputIt>
    1522             :     unordered_map<K, T, H, P, A>::unordered_map(InputIt f, InputIt l,
    1523             :       size_type n, const hasher& hf, const key_equal& eql,
    1524             :       const allocator_type& a)
    1525             :         : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a)
    1526             :     {
    1527             :       this->insert(f, l);
    1528             :     }
    1529             : 
    1530             :     template <class K, class T, class H, class P, class A>
    1531           0 :     unordered_map<K, T, H, P, A>::unordered_map(unordered_map const& other)
    1532           0 :         : table_(other.table_,
    1533             :             unordered_map::value_allocator_traits::
    1534           0 :               select_on_container_copy_construction(other.get_allocator()))
    1535             :     {
    1536           0 :       if (other.table_.size_) {
    1537           0 :         table_.copy_buckets(
    1538             :           other.table_, boost::unordered::detail::true_type());
    1539             :       }
    1540           0 :     }
    1541             : 
    1542             :     template <class K, class T, class H, class P, class A>
    1543             :     unordered_map<K, T, H, P, A>::unordered_map(allocator_type const& a)
    1544             :         : table_(boost::unordered::detail::default_bucket_count, hasher(),
    1545             :             key_equal(), a)
    1546             :     {
    1547             :     }
    1548             : 
    1549             :     template <class K, class T, class H, class P, class A>
    1550             :     unordered_map<K, T, H, P, A>::unordered_map(
    1551             :       unordered_map const& other, allocator_type const& a)
    1552             :         : table_(other.table_, a)
    1553             :     {
    1554             :       if (other.table_.size_) {
    1555             :         table_.copy_buckets(
    1556             :           other.table_, boost::unordered::detail::true_type());
    1557             :       }
    1558             :     }
    1559             : 
    1560             :     template <class K, class T, class H, class P, class A>
    1561             :     unordered_map<K, T, H, P, A>::unordered_map(
    1562             :       BOOST_RV_REF(unordered_map) other, allocator_type const& a)
    1563             :         : table_(other.table_, a, boost::unordered::detail::move_tag())
    1564             :     {
    1565             :       table_.move_construct_buckets(other.table_);
    1566             :     }
    1567             : 
    1568             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    1569             : 
    1570             :     template <class K, class T, class H, class P, class A>
    1571             :     unordered_map<K, T, H, P, A>::unordered_map(
    1572             :       std::initializer_list<value_type> list, size_type n, const hasher& hf,
    1573             :       const key_equal& eql, const allocator_type& a)
    1574             :         : table_(
    1575             :             boost::unordered::detail::initial_size(list.begin(), list.end(), n),
    1576             :             hf, eql, a)
    1577             :     {
    1578             :       this->insert(list.begin(), list.end());
    1579             :     }
    1580             : 
    1581             : #endif
    1582             : 
    1583             :     template <class K, class T, class H, class P, class A>
    1584             :     unordered_map<K, T, H, P, A>::unordered_map(
    1585             :       size_type n, const allocator_type& a)
    1586             :         : table_(n, hasher(), key_equal(), a)
    1587             :     {
    1588             :     }
    1589             : 
    1590             :     template <class K, class T, class H, class P, class A>
    1591             :     unordered_map<K, T, H, P, A>::unordered_map(
    1592             :       size_type n, const hasher& hf, const allocator_type& a)
    1593             :         : table_(n, hf, key_equal(), a)
    1594             :     {
    1595             :     }
    1596             : 
    1597             :     template <class K, class T, class H, class P, class A>
    1598             :     template <class InputIt>
    1599             :     unordered_map<K, T, H, P, A>::unordered_map(
    1600             :       InputIt f, InputIt l, size_type n, const allocator_type& a)
    1601             :         : table_(boost::unordered::detail::initial_size(f, l, n), hasher(),
    1602             :             key_equal(), a)
    1603             :     {
    1604             :       this->insert(f, l);
    1605             :     }
    1606             : 
    1607             :     template <class K, class T, class H, class P, class A>
    1608             :     template <class InputIt>
    1609             :     unordered_map<K, T, H, P, A>::unordered_map(InputIt f, InputIt l,
    1610             :       size_type n, const hasher& hf, const allocator_type& a)
    1611             :         : table_(
    1612             :             boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a)
    1613             :     {
    1614             :       this->insert(f, l);
    1615             :     }
    1616             : 
    1617             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    1618             : 
    1619             :     template <class K, class T, class H, class P, class A>
    1620             :     unordered_map<K, T, H, P, A>::unordered_map(
    1621             :       std::initializer_list<value_type> list, size_type n,
    1622             :       const allocator_type& a)
    1623             :         : table_(
    1624             :             boost::unordered::detail::initial_size(list.begin(), list.end(), n),
    1625             :             hasher(), key_equal(), a)
    1626             :     {
    1627             :       this->insert(list.begin(), list.end());
    1628             :     }
    1629             : 
    1630             :     template <class K, class T, class H, class P, class A>
    1631             :     unordered_map<K, T, H, P, A>::unordered_map(
    1632             :       std::initializer_list<value_type> list, size_type n, const hasher& hf,
    1633             :       const allocator_type& a)
    1634             :         : table_(
    1635             :             boost::unordered::detail::initial_size(list.begin(), list.end(), n),
    1636             :             hf, key_equal(), a)
    1637             :     {
    1638             :       this->insert(list.begin(), list.end());
    1639             :     }
    1640             : 
    1641             : #endif
    1642             : 
    1643             :     template <class K, class T, class H, class P, class A>
    1644         356 :     unordered_map<K, T, H, P, A>::~unordered_map() BOOST_NOEXCEPT
    1645             :     {
    1646         356 :     }
    1647             : 
    1648             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    1649             : 
    1650             :     template <class K, class T, class H, class P, class A>
    1651             :     unordered_map<K, T, H, P, A>& unordered_map<K, T, H, P, A>::operator=(
    1652             :       std::initializer_list<value_type> list)
    1653             :     {
    1654             :       this->clear();
    1655             :       this->insert(list.begin(), list.end());
    1656             :       return *this;
    1657             :     }
    1658             : 
    1659             : #endif
    1660             : 
    1661             :     // size and capacity
    1662             : 
    1663             :     template <class K, class T, class H, class P, class A>
    1664             :     std::size_t unordered_map<K, T, H, P, A>::max_size() const BOOST_NOEXCEPT
    1665             :     {
    1666             :       using namespace std;
    1667             : 
    1668             :       // size <= mlf_ * count
    1669             :       return boost::unordered::detail::double_to_size(
    1670             :                ceil(static_cast<double>(table_.mlf_) *
    1671             :                     static_cast<double>(table_.max_bucket_count()))) -
    1672             :              1;
    1673             :     }
    1674             : 
    1675             :     // modifiers
    1676             : 
    1677             :     template <class K, class T, class H, class P, class A>
    1678             :     template <class InputIt>
    1679             :     void unordered_map<K, T, H, P, A>::insert(InputIt first, InputIt last)
    1680             :     {
    1681             :       if (first != last) {
    1682             :         table_.insert_range_unique(
    1683             :           table::extractor::extract(*first), first, last);
    1684             :       }
    1685             :     }
    1686             : 
    1687             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    1688             :     template <class K, class T, class H, class P, class A>
    1689             :     void unordered_map<K, T, H, P, A>::insert(
    1690             :       std::initializer_list<value_type> list)
    1691             :     {
    1692             :       this->insert(list.begin(), list.end());
    1693             :     }
    1694             : #endif
    1695             : 
    1696             :     template <class K, class T, class H, class P, class A>
    1697             :     typename unordered_map<K, T, H, P, A>::iterator
    1698             :     unordered_map<K, T, H, P, A>::erase(iterator position)
    1699             :     {
    1700             :       node_pointer node = table::get_node(position);
    1701             :       BOOST_ASSERT(node);
    1702             :       node_pointer next = table::next_node(node);
    1703             :       table_.erase_nodes_unique(node, next);
    1704             :       return iterator(next);
    1705             :     }
    1706             : 
    1707             :     template <class K, class T, class H, class P, class A>
    1708             :     typename unordered_map<K, T, H, P, A>::iterator
    1709             :     unordered_map<K, T, H, P, A>::erase(const_iterator position)
    1710             :     {
    1711             :       node_pointer node = table::get_node(position);
    1712             :       BOOST_ASSERT(node);
    1713             :       node_pointer next = table::next_node(node);
    1714             :       table_.erase_nodes_unique(node, next);
    1715             :       return iterator(next);
    1716             :     }
    1717             : 
    1718             :     template <class K, class T, class H, class P, class A>
    1719             :     typename unordered_map<K, T, H, P, A>::size_type
    1720           0 :     unordered_map<K, T, H, P, A>::erase(const key_type& k)
    1721             :     {
    1722           0 :       return table_.erase_key_unique(k);
    1723             :     }
    1724             : 
    1725             :     template <class K, class T, class H, class P, class A>
    1726             :     typename unordered_map<K, T, H, P, A>::iterator
    1727             :     unordered_map<K, T, H, P, A>::erase(
    1728             :       const_iterator first, const_iterator last)
    1729             :     {
    1730             :       node_pointer last_node = table::get_node(last);
    1731             :       if (first == last)
    1732             :         return iterator(last_node);
    1733             :       table_.erase_nodes_unique(table::get_node(first), last_node);
    1734             :       return iterator(last_node);
    1735             :     }
    1736             : 
    1737             :     template <class K, class T, class H, class P, class A>
    1738             :     void unordered_map<K, T, H, P, A>::swap(unordered_map& other)
    1739             :       BOOST_NOEXCEPT_IF(value_allocator_traits::is_always_equal::value&&
    1740             :           boost::is_nothrow_swappable<H>::value&&
    1741             :             boost::is_nothrow_swappable<P>::value)
    1742             :     {
    1743             :       table_.swap(other.table_);
    1744             :     }
    1745             : 
    1746             :     template <class K, class T, class H, class P, class A>
    1747             :     template <typename H2, typename P2>
    1748             :     void unordered_map<K, T, H, P, A>::merge(
    1749             :       boost::unordered_map<K, T, H2, P2, A>& source)
    1750             :     {
    1751             :       table_.merge_unique(source.table_);
    1752             :     }
    1753             : 
    1754             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    1755             :     template <class K, class T, class H, class P, class A>
    1756             :     template <typename H2, typename P2>
    1757             :     void unordered_map<K, T, H, P, A>::merge(
    1758             :       boost::unordered_map<K, T, H2, P2, A>&& source)
    1759             :     {
    1760             :       table_.merge_unique(source.table_);
    1761             :     }
    1762             : #endif
    1763             : 
    1764             :     template <class K, class T, class H, class P, class A>
    1765             :     template <typename H2, typename P2>
    1766             :     void unordered_map<K, T, H, P, A>::merge(
    1767             :       boost::unordered_multimap<K, T, H2, P2, A>& source)
    1768             :     {
    1769             :       table_.merge_unique(source.table_);
    1770             :     }
    1771             : 
    1772             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    1773             :     template <class K, class T, class H, class P, class A>
    1774             :     template <typename H2, typename P2>
    1775             :     void unordered_map<K, T, H, P, A>::merge(
    1776             :       boost::unordered_multimap<K, T, H2, P2, A>&& source)
    1777             :     {
    1778             :       table_.merge_unique(source.table_);
    1779             :     }
    1780             : #endif
    1781             : 
    1782             :     // observers
    1783             : 
    1784             :     template <class K, class T, class H, class P, class A>
    1785             :     typename unordered_map<K, T, H, P, A>::hasher
    1786             :     unordered_map<K, T, H, P, A>::hash_function() const
    1787             :     {
    1788             :       return table_.hash_function();
    1789             :     }
    1790             : 
    1791             :     template <class K, class T, class H, class P, class A>
    1792             :     typename unordered_map<K, T, H, P, A>::key_equal
    1793             :     unordered_map<K, T, H, P, A>::key_eq() const
    1794             :     {
    1795             :       return table_.key_eq();
    1796             :     }
    1797             : 
    1798             :     // lookup
    1799             : 
    1800             :     template <class K, class T, class H, class P, class A>
    1801             :     typename unordered_map<K, T, H, P, A>::iterator
    1802         479 :     unordered_map<K, T, H, P, A>::find(const key_type& k)
    1803             :     {
    1804         479 :       return iterator(table_.find_node(k));
    1805             :     }
    1806             : 
    1807             :     template <class K, class T, class H, class P, class A>
    1808             :     typename unordered_map<K, T, H, P, A>::const_iterator
    1809           0 :     unordered_map<K, T, H, P, A>::find(const key_type& k) const
    1810             :     {
    1811           0 :       return const_iterator(table_.find_node(k));
    1812             :     }
    1813             : 
    1814             :     template <class K, class T, class H, class P, class A>
    1815             :     template <class CompatibleKey, class CompatibleHash,
    1816             :       class CompatiblePredicate>
    1817             :     typename unordered_map<K, T, H, P, A>::iterator
    1818             :     unordered_map<K, T, H, P, A>::find(CompatibleKey const& k,
    1819             :       CompatibleHash const& hash, CompatiblePredicate const& eq)
    1820             :     {
    1821             :       return iterator(
    1822             :         table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
    1823             :     }
    1824             : 
    1825             :     template <class K, class T, class H, class P, class A>
    1826             :     template <class CompatibleKey, class CompatibleHash,
    1827             :       class CompatiblePredicate>
    1828             :     typename unordered_map<K, T, H, P, A>::const_iterator
    1829             :     unordered_map<K, T, H, P, A>::find(CompatibleKey const& k,
    1830             :       CompatibleHash const& hash, CompatiblePredicate const& eq) const
    1831             :     {
    1832             :       return const_iterator(
    1833             :         table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
    1834             :     }
    1835             : 
    1836             :     template <class K, class T, class H, class P, class A>
    1837             :     typename unordered_map<K, T, H, P, A>::size_type
    1838           0 :     unordered_map<K, T, H, P, A>::count(const key_type& k) const
    1839             :     {
    1840           0 :       return table_.find_node(k) ? 1 : 0;
    1841             :     }
    1842             : 
    1843             :     template <class K, class T, class H, class P, class A>
    1844             :     std::pair<typename unordered_map<K, T, H, P, A>::iterator,
    1845             :       typename unordered_map<K, T, H, P, A>::iterator>
    1846             :     unordered_map<K, T, H, P, A>::equal_range(const key_type& k)
    1847             :     {
    1848             :       node_pointer n = table_.find_node(k);
    1849             :       return std::make_pair(iterator(n), iterator(n ? table::next_node(n) : n));
    1850             :     }
    1851             : 
    1852             :     template <class K, class T, class H, class P, class A>
    1853             :     std::pair<typename unordered_map<K, T, H, P, A>::const_iterator,
    1854             :       typename unordered_map<K, T, H, P, A>::const_iterator>
    1855             :     unordered_map<K, T, H, P, A>::equal_range(const key_type& k) const
    1856             :     {
    1857             :       node_pointer n = table_.find_node(k);
    1858             :       return std::make_pair(
    1859             :         const_iterator(n), const_iterator(n ? table::next_node(n) : n));
    1860             :     }
    1861             : 
    1862             :     template <class K, class T, class H, class P, class A>
    1863             :     typename unordered_map<K, T, H, P, A>::mapped_type&
    1864          80 :       unordered_map<K, T, H, P, A>::operator[](const key_type& k)
    1865             :     {
    1866          80 :       return table_.try_emplace_unique(k).first->second;
    1867             :     }
    1868             : 
    1869             :     template <class K, class T, class H, class P, class A>
    1870             :     typename unordered_map<K, T, H, P, A>::mapped_type&
    1871           0 :       unordered_map<K, T, H, P, A>::operator[](BOOST_RV_REF(key_type) k)
    1872             :     {
    1873           0 :       return table_.try_emplace_unique(boost::move(k)).first->second;
    1874             :     }
    1875             : 
    1876             :     template <class K, class T, class H, class P, class A>
    1877             :     typename unordered_map<K, T, H, P, A>::mapped_type&
    1878           0 :     unordered_map<K, T, H, P, A>::at(const key_type& k)
    1879             :     {
    1880           0 :       if (table_.size_) {
    1881           0 :         node_pointer n = table_.find_node(k);
    1882           0 :         if (n)
    1883           0 :           return n->value().second;
    1884             :       }
    1885             : 
    1886           0 :       boost::throw_exception(
    1887             :         std::out_of_range("Unable to find key in unordered_map."));
    1888             :     }
    1889             : 
    1890             :     template <class K, class T, class H, class P, class A>
    1891             :     typename unordered_map<K, T, H, P, A>::mapped_type const&
    1892             :     unordered_map<K, T, H, P, A>::at(const key_type& k) const
    1893             :     {
    1894             :       if (table_.size_) {
    1895             :         node_pointer n = table_.find_node(k);
    1896             :         if (n)
    1897             :           return n->value().second;
    1898             :       }
    1899             : 
    1900             :       boost::throw_exception(
    1901             :         std::out_of_range("Unable to find key in unordered_map."));
    1902             :     }
    1903             : 
    1904             :     template <class K, class T, class H, class P, class A>
    1905             :     typename unordered_map<K, T, H, P, A>::size_type
    1906             :     unordered_map<K, T, H, P, A>::bucket_size(size_type n) const
    1907             :     {
    1908             :       return table_.bucket_size(n);
    1909             :     }
    1910             : 
    1911             :     // hash policy
    1912             : 
    1913             :     template <class K, class T, class H, class P, class A>
    1914             :     float unordered_map<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
    1915             :     {
    1916             :       BOOST_ASSERT(table_.bucket_count_ != 0);
    1917             :       return static_cast<float>(table_.size_) /
    1918             :              static_cast<float>(table_.bucket_count_);
    1919             :     }
    1920             : 
    1921             :     template <class K, class T, class H, class P, class A>
    1922             :     void unordered_map<K, T, H, P, A>::max_load_factor(float m) BOOST_NOEXCEPT
    1923             :     {
    1924             :       table_.max_load_factor(m);
    1925             :     }
    1926             : 
    1927             :     template <class K, class T, class H, class P, class A>
    1928           0 :     void unordered_map<K, T, H, P, A>::rehash(size_type n)
    1929             :     {
    1930           0 :       table_.rehash(n);
    1931             :     }
    1932             : 
    1933             :     template <class K, class T, class H, class P, class A>
    1934             :     void unordered_map<K, T, H, P, A>::reserve(size_type n)
    1935             :     {
    1936             :       table_.rehash(static_cast<std::size_t>(
    1937             :         std::ceil(static_cast<double>(n) / table_.mlf_)));
    1938             :     }
    1939             : 
    1940             :     template <class K, class T, class H, class P, class A>
    1941             :     inline bool operator==(unordered_map<K, T, H, P, A> const& m1,
    1942             :       unordered_map<K, T, H, P, A> const& m2)
    1943             :     {
    1944             : #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
    1945             :       struct dummy
    1946             :       {
    1947             :         unordered_map<K, T, H, P, A> x;
    1948             :       };
    1949             : #endif
    1950             :       return m1.table_.equals_unique(m2.table_);
    1951             :     }
    1952             : 
    1953             :     template <class K, class T, class H, class P, class A>
    1954             :     inline bool operator!=(unordered_map<K, T, H, P, A> const& m1,
    1955             :       unordered_map<K, T, H, P, A> const& m2)
    1956             :     {
    1957             : #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
    1958             :       struct dummy
    1959             :       {
    1960             :         unordered_map<K, T, H, P, A> x;
    1961             :       };
    1962             : #endif
    1963             :       return !m1.table_.equals_unique(m2.table_);
    1964             :     }
    1965             : 
    1966             :     template <class K, class T, class H, class P, class A>
    1967             :     inline void swap(
    1968             :       unordered_map<K, T, H, P, A>& m1, unordered_map<K, T, H, P, A>& m2)
    1969             :       BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.swap(m2)))
    1970             :     {
    1971             : #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
    1972             :       struct dummy
    1973             :       {
    1974             :         unordered_map<K, T, H, P, A> x;
    1975             :       };
    1976             : #endif
    1977             :       m1.swap(m2);
    1978             :     }
    1979             : 
    1980             :     ////////////////////////////////////////////////////////////////////////////
    1981             : 
    1982             :     template <class K, class T, class H, class P, class A>
    1983           0 :     unordered_multimap<K, T, H, P, A>::unordered_multimap()
    1984             :         : table_(boost::unordered::detail::default_bucket_count, hasher(),
    1985           0 :             key_equal(), allocator_type())
    1986             :     {
    1987           0 :     }
    1988             : 
    1989             :     template <class K, class T, class H, class P, class A>
    1990      304102 :     unordered_multimap<K, T, H, P, A>::unordered_multimap(size_type n,
    1991             :       const hasher& hf, const key_equal& eql, const allocator_type& a)
    1992      304102 :         : table_(n, hf, eql, a)
    1993             :     {
    1994             :     }
    1995             : 
    1996             :     template <class K, class T, class H, class P, class A>
    1997             :     template <class InputIt>
    1998             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(InputIt f, InputIt l,
    1999             :       size_type n, const hasher& hf, const key_equal& eql,
    2000             :       const allocator_type& a)
    2001             :         : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a)
    2002             :     {
    2003             :       this->insert(f, l);
    2004             :     }
    2005             : 
    2006             :     template <class K, class T, class H, class P, class A>
    2007           0 :     unordered_multimap<K, T, H, P, A>::unordered_multimap(
    2008             :       unordered_multimap const& other)
    2009           0 :         : table_(other.table_,
    2010             :             unordered_multimap::value_allocator_traits::
    2011           0 :               select_on_container_copy_construction(other.get_allocator()))
    2012             :     {
    2013           0 :       if (other.table_.size_) {
    2014           0 :         table_.copy_buckets(
    2015             :           other.table_, boost::unordered::detail::false_type());
    2016             :       }
    2017           0 :     }
    2018             : 
    2019             :     template <class K, class T, class H, class P, class A>
    2020             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(
    2021             :       allocator_type const& a)
    2022             :         : table_(boost::unordered::detail::default_bucket_count, hasher(),
    2023             :             key_equal(), a)
    2024             :     {
    2025             :     }
    2026             : 
    2027             :     template <class K, class T, class H, class P, class A>
    2028             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(
    2029             :       unordered_multimap const& other, allocator_type const& a)
    2030             :         : table_(other.table_, a)
    2031             :     {
    2032             :       if (other.table_.size_) {
    2033             :         table_.copy_buckets(
    2034             :           other.table_, boost::unordered::detail::false_type());
    2035             :       }
    2036             :     }
    2037             : 
    2038             :     template <class K, class T, class H, class P, class A>
    2039             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(
    2040             :       BOOST_RV_REF(unordered_multimap) other, allocator_type const& a)
    2041             :         : table_(other.table_, a, boost::unordered::detail::move_tag())
    2042             :     {
    2043             :       table_.move_construct_buckets(other.table_);
    2044             :     }
    2045             : 
    2046             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    2047             : 
    2048             :     template <class K, class T, class H, class P, class A>
    2049             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(
    2050             :       std::initializer_list<value_type> list, size_type n, const hasher& hf,
    2051             :       const key_equal& eql, const allocator_type& a)
    2052             :         : table_(
    2053             :             boost::unordered::detail::initial_size(list.begin(), list.end(), n),
    2054             :             hf, eql, a)
    2055             :     {
    2056             :       this->insert(list.begin(), list.end());
    2057             :     }
    2058             : 
    2059             : #endif
    2060             : 
    2061             :     template <class K, class T, class H, class P, class A>
    2062             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(
    2063             :       size_type n, const allocator_type& a)
    2064             :         : table_(n, hasher(), key_equal(), a)
    2065             :     {
    2066             :     }
    2067             : 
    2068             :     template <class K, class T, class H, class P, class A>
    2069             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(
    2070             :       size_type n, const hasher& hf, const allocator_type& a)
    2071             :         : table_(n, hf, key_equal(), a)
    2072             :     {
    2073             :     }
    2074             : 
    2075             :     template <class K, class T, class H, class P, class A>
    2076             :     template <class InputIt>
    2077             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(
    2078             :       InputIt f, InputIt l, size_type n, const allocator_type& a)
    2079             :         : table_(boost::unordered::detail::initial_size(f, l, n), hasher(),
    2080             :             key_equal(), a)
    2081             :     {
    2082             :       this->insert(f, l);
    2083             :     }
    2084             : 
    2085             :     template <class K, class T, class H, class P, class A>
    2086             :     template <class InputIt>
    2087             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(InputIt f, InputIt l,
    2088             :       size_type n, const hasher& hf, const allocator_type& a)
    2089             :         : table_(
    2090             :             boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a)
    2091             :     {
    2092             :       this->insert(f, l);
    2093             :     }
    2094             : 
    2095             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    2096             : 
    2097             :     template <class K, class T, class H, class P, class A>
    2098             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(
    2099             :       std::initializer_list<value_type> list, size_type n,
    2100             :       const allocator_type& a)
    2101             :         : table_(
    2102             :             boost::unordered::detail::initial_size(list.begin(), list.end(), n),
    2103             :             hasher(), key_equal(), a)
    2104             :     {
    2105             :       this->insert(list.begin(), list.end());
    2106             :     }
    2107             : 
    2108             :     template <class K, class T, class H, class P, class A>
    2109             :     unordered_multimap<K, T, H, P, A>::unordered_multimap(
    2110             :       std::initializer_list<value_type> list, size_type n, const hasher& hf,
    2111             :       const allocator_type& a)
    2112             :         : table_(
    2113             :             boost::unordered::detail::initial_size(list.begin(), list.end(), n),
    2114             :             hf, key_equal(), a)
    2115             :     {
    2116             :       this->insert(list.begin(), list.end());
    2117             :     }
    2118             : 
    2119             : #endif
    2120             : 
    2121             :     template <class K, class T, class H, class P, class A>
    2122       54458 :     unordered_multimap<K, T, H, P, A>::~unordered_multimap() BOOST_NOEXCEPT
    2123             :     {
    2124       54458 :     }
    2125             : 
    2126             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    2127             : 
    2128             :     template <class K, class T, class H, class P, class A>
    2129             :     unordered_multimap<K, T, H, P, A>& unordered_multimap<K, T, H, P, A>::
    2130             :     operator=(std::initializer_list<value_type> list)
    2131             :     {
    2132             :       this->clear();
    2133             :       this->insert(list.begin(), list.end());
    2134             :       return *this;
    2135             :     }
    2136             : 
    2137             : #endif
    2138             : 
    2139             :     // size and capacity
    2140             : 
    2141             :     template <class K, class T, class H, class P, class A>
    2142             :     std::size_t
    2143             :     unordered_multimap<K, T, H, P, A>::max_size() const BOOST_NOEXCEPT
    2144             :     {
    2145             :       using namespace std;
    2146             : 
    2147             :       // size <= mlf_ * count
    2148             :       return boost::unordered::detail::double_to_size(
    2149             :                ceil(static_cast<double>(table_.mlf_) *
    2150             :                     static_cast<double>(table_.max_bucket_count()))) -
    2151             :              1;
    2152             :     }
    2153             : 
    2154             :     // modifiers
    2155             : 
    2156             :     template <class K, class T, class H, class P, class A>
    2157             :     template <class InputIt>
    2158             :     void unordered_multimap<K, T, H, P, A>::insert(InputIt first, InputIt last)
    2159             :     {
    2160             :       table_.insert_range_equiv(first, last);
    2161             :     }
    2162             : 
    2163             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    2164             :     template <class K, class T, class H, class P, class A>
    2165             :     void unordered_multimap<K, T, H, P, A>::insert(
    2166             :       std::initializer_list<value_type> list)
    2167             :     {
    2168             :       this->insert(list.begin(), list.end());
    2169             :     }
    2170             : #endif
    2171             : 
    2172             :     template <class K, class T, class H, class P, class A>
    2173             :     typename unordered_multimap<K, T, H, P, A>::iterator
    2174       26493 :     unordered_multimap<K, T, H, P, A>::erase(iterator position)
    2175             :     {
    2176       26493 :       node_pointer node = table::get_node(position);
    2177       26493 :       BOOST_ASSERT(node);
    2178       26493 :       node_pointer next = table::next_node(node);
    2179       26493 :       table_.erase_nodes_equiv(node, next);
    2180       26493 :       return iterator(next);
    2181             :     }
    2182             : 
    2183             :     template <class K, class T, class H, class P, class A>
    2184             :     typename unordered_multimap<K, T, H, P, A>::iterator
    2185           0 :     unordered_multimap<K, T, H, P, A>::erase(const_iterator position)
    2186             :     {
    2187           0 :       node_pointer node = table::get_node(position);
    2188           0 :       BOOST_ASSERT(node);
    2189           0 :       node_pointer next = table::next_node(node);
    2190           0 :       table_.erase_nodes_equiv(node, next);
    2191           0 :       return iterator(next);
    2192             :     }
    2193             : 
    2194             :     template <class K, class T, class H, class P, class A>
    2195             :     typename unordered_multimap<K, T, H, P, A>::size_type
    2196           0 :     unordered_multimap<K, T, H, P, A>::erase(const key_type& k)
    2197             :     {
    2198           0 :       return table_.erase_key_equiv(k);
    2199             :     }
    2200             : 
    2201             :     template <class K, class T, class H, class P, class A>
    2202             :     typename unordered_multimap<K, T, H, P, A>::iterator
    2203             :     unordered_multimap<K, T, H, P, A>::erase(
    2204             :       const_iterator first, const_iterator last)
    2205             :     {
    2206             :       node_pointer last_node = table::get_node(last);
    2207             :       if (first == last)
    2208             :         return iterator(last_node);
    2209             :       table_.erase_nodes_equiv(table::get_node(first), last_node);
    2210             :       return iterator(last_node);
    2211             :     }
    2212             : 
    2213             :     template <class K, class T, class H, class P, class A>
    2214             :     void unordered_multimap<K, T, H, P, A>::swap(unordered_multimap& other)
    2215             :       BOOST_NOEXCEPT_IF(value_allocator_traits::is_always_equal::value&&
    2216             :           boost::is_nothrow_swappable<H>::value&&
    2217             :             boost::is_nothrow_swappable<P>::value)
    2218             :     {
    2219             :       table_.swap(other.table_);
    2220             :     }
    2221             : 
    2222             :     // observers
    2223             : 
    2224             :     template <class K, class T, class H, class P, class A>
    2225             :     typename unordered_multimap<K, T, H, P, A>::hasher
    2226             :     unordered_multimap<K, T, H, P, A>::hash_function() const
    2227             :     {
    2228             :       return table_.hash_function();
    2229             :     }
    2230             : 
    2231             :     template <class K, class T, class H, class P, class A>
    2232             :     typename unordered_multimap<K, T, H, P, A>::key_equal
    2233    18682100 :     unordered_multimap<K, T, H, P, A>::key_eq() const
    2234             :     {
    2235    18682100 :       return table_.key_eq();
    2236             :     }
    2237             : 
    2238             :     template <class K, class T, class H, class P, class A>
    2239             :     template <typename H2, typename P2>
    2240             :     void unordered_multimap<K, T, H, P, A>::merge(
    2241             :       boost::unordered_multimap<K, T, H2, P2, A>& source)
    2242             :     {
    2243             :       while (!source.empty()) {
    2244             :         insert(source.extract(source.begin()));
    2245             :       }
    2246             :     }
    2247             : 
    2248             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    2249             :     template <class K, class T, class H, class P, class A>
    2250             :     template <typename H2, typename P2>
    2251             :     void unordered_multimap<K, T, H, P, A>::merge(
    2252             :       boost::unordered_multimap<K, T, H2, P2, A>&& source)
    2253             :     {
    2254             :       while (!source.empty()) {
    2255             :         insert(source.extract(source.begin()));
    2256             :       }
    2257             :     }
    2258             : #endif
    2259             : 
    2260             :     template <class K, class T, class H, class P, class A>
    2261             :     template <typename H2, typename P2>
    2262             :     void unordered_multimap<K, T, H, P, A>::merge(
    2263             :       boost::unordered_map<K, T, H2, P2, A>& source)
    2264             :     {
    2265             :       while (!source.empty()) {
    2266             :         insert(source.extract(source.begin()));
    2267             :       }
    2268             :     }
    2269             : 
    2270             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    2271             :     template <class K, class T, class H, class P, class A>
    2272             :     template <typename H2, typename P2>
    2273             :     void unordered_multimap<K, T, H, P, A>::merge(
    2274             :       boost::unordered_map<K, T, H2, P2, A>&& source)
    2275             :     {
    2276             :       while (!source.empty()) {
    2277             :         insert(source.extract(source.begin()));
    2278             :       }
    2279             :     }
    2280             : #endif
    2281             : 
    2282             :     // lookup
    2283             : 
    2284             :     template <class K, class T, class H, class P, class A>
    2285             :     typename unordered_multimap<K, T, H, P, A>::iterator
    2286    24556122 :     unordered_multimap<K, T, H, P, A>::find(const key_type& k)
    2287             :     {
    2288    24639744 :       return iterator(table_.find_node(k));
    2289             :     }
    2290             : 
    2291             :     template <class K, class T, class H, class P, class A>
    2292             :     typename unordered_multimap<K, T, H, P, A>::const_iterator
    2293           0 :     unordered_multimap<K, T, H, P, A>::find(const key_type& k) const
    2294             :     {
    2295           0 :       return const_iterator(table_.find_node(k));
    2296             :     }
    2297             : 
    2298             :     template <class K, class T, class H, class P, class A>
    2299             :     template <class CompatibleKey, class CompatibleHash,
    2300             :       class CompatiblePredicate>
    2301             :     typename unordered_multimap<K, T, H, P, A>::iterator
    2302             :     unordered_multimap<K, T, H, P, A>::find(CompatibleKey const& k,
    2303             :       CompatibleHash const& hash, CompatiblePredicate const& eq)
    2304             :     {
    2305             :       return iterator(
    2306             :         table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
    2307             :     }
    2308             : 
    2309             :     template <class K, class T, class H, class P, class A>
    2310             :     template <class CompatibleKey, class CompatibleHash,
    2311             :       class CompatiblePredicate>
    2312             :     typename unordered_multimap<K, T, H, P, A>::const_iterator
    2313             :     unordered_multimap<K, T, H, P, A>::find(CompatibleKey const& k,
    2314             :       CompatibleHash const& hash, CompatiblePredicate const& eq) const
    2315             :     {
    2316             :       return const_iterator(
    2317             :         table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
    2318             :     }
    2319             : 
    2320             :     template <class K, class T, class H, class P, class A>
    2321             :     typename unordered_multimap<K, T, H, P, A>::size_type
    2322       91948 :     unordered_multimap<K, T, H, P, A>::count(const key_type& k) const
    2323             :     {
    2324       91948 :       node_pointer n = table_.find_node(k);
    2325      133300 :       return n ? table_.group_count(n) : 0;
    2326             :     }
    2327             : 
    2328             :     template <class K, class T, class H, class P, class A>
    2329             :     std::pair<typename unordered_multimap<K, T, H, P, A>::iterator,
    2330             :       typename unordered_multimap<K, T, H, P, A>::iterator>
    2331    10615300 :     unordered_multimap<K, T, H, P, A>::equal_range(const key_type& k)
    2332             :     {
    2333    10615300 :       node_pointer n = table_.find_node(k);
    2334    10615300 :       return std::make_pair(
    2335     8226120 :         iterator(n), iterator(n ? table_.next_group(n) : n));
    2336             :     }
    2337             : 
    2338             :     template <class K, class T, class H, class P, class A>
    2339             :     std::pair<typename unordered_multimap<K, T, H, P, A>::const_iterator,
    2340             :       typename unordered_multimap<K, T, H, P, A>::const_iterator>
    2341           0 :     unordered_multimap<K, T, H, P, A>::equal_range(const key_type& k) const
    2342             :     {
    2343           0 :       node_pointer n = table_.find_node(k);
    2344           0 :       return std::make_pair(
    2345           0 :         const_iterator(n), const_iterator(n ? table_.next_group(n) : n));
    2346             :     }
    2347             : 
    2348             :     template <class K, class T, class H, class P, class A>
    2349             :     typename unordered_multimap<K, T, H, P, A>::size_type
    2350           0 :     unordered_multimap<K, T, H, P, A>::bucket_size(size_type n) const
    2351             :     {
    2352           0 :       return table_.bucket_size(n);
    2353             :     }
    2354             : 
    2355             :     // hash policy
    2356             : 
    2357             :     template <class K, class T, class H, class P, class A>
    2358           0 :     float unordered_multimap<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
    2359             :     {
    2360           0 :       BOOST_ASSERT(table_.bucket_count_ != 0);
    2361           0 :       return static_cast<float>(table_.size_) /
    2362           0 :              static_cast<float>(table_.bucket_count_);
    2363             :     }
    2364             : 
    2365             :     template <class K, class T, class H, class P, class A>
    2366             :     void unordered_multimap<K, T, H, P, A>::max_load_factor(
    2367             :       float m) BOOST_NOEXCEPT
    2368             :     {
    2369             :       table_.max_load_factor(m);
    2370             :     }
    2371             : 
    2372             :     template <class K, class T, class H, class P, class A>
    2373           0 :     void unordered_multimap<K, T, H, P, A>::rehash(size_type n)
    2374             :     {
    2375           0 :       table_.rehash(n);
    2376             :     }
    2377             : 
    2378             :     template <class K, class T, class H, class P, class A>
    2379             :     void unordered_multimap<K, T, H, P, A>::reserve(size_type n)
    2380             :     {
    2381             :       table_.rehash(static_cast<std::size_t>(
    2382             :         std::ceil(static_cast<double>(n) / table_.mlf_)));
    2383             :     }
    2384             : 
    2385             :     template <class K, class T, class H, class P, class A>
    2386             :     inline bool operator==(unordered_multimap<K, T, H, P, A> const& m1,
    2387             :       unordered_multimap<K, T, H, P, A> const& m2)
    2388             :     {
    2389             : #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
    2390             :       struct dummy
    2391             :       {
    2392             :         unordered_multimap<K, T, H, P, A> x;
    2393             :       };
    2394             : #endif
    2395             :       return m1.table_.equals_equiv(m2.table_);
    2396             :     }
    2397             : 
    2398             :     template <class K, class T, class H, class P, class A>
    2399             :     inline bool operator!=(unordered_multimap<K, T, H, P, A> const& m1,
    2400             :       unordered_multimap<K, T, H, P, A> const& m2)
    2401             :     {
    2402             : #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
    2403             :       struct dummy
    2404             :       {
    2405             :         unordered_multimap<K, T, H, P, A> x;
    2406             :       };
    2407             : #endif
    2408             :       return !m1.table_.equals_equiv(m2.table_);
    2409             :     }
    2410             : 
    2411             :     template <class K, class T, class H, class P, class A>
    2412             :     inline void swap(unordered_multimap<K, T, H, P, A>& m1,
    2413             :       unordered_multimap<K, T, H, P, A>& m2)
    2414             :       BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.swap(m2)))
    2415             :     {
    2416             : #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
    2417             :       struct dummy
    2418             :       {
    2419             :         unordered_multimap<K, T, H, P, A> x;
    2420             :       };
    2421             : #endif
    2422             :       m1.swap(m2);
    2423             :     }
    2424             : 
    2425             :     template <typename N, class K, class T, class A> class node_handle_map
    2426             :     {
    2427             :       BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle_map)
    2428             : 
    2429             :       template <typename Types> friend struct ::boost::unordered::detail::table;
    2430             :       template <class K2, class T2, class H2, class P2, class A2>
    2431             :       friend class boost::unordered::unordered_map;
    2432             :       template <class K2, class T2, class H2, class P2, class A2>
    2433             :       friend class boost::unordered::unordered_multimap;
    2434             : 
    2435             :       typedef typename boost::unordered::detail::rebind_wrap<A,
    2436             :         std::pair<K const, T> >::type value_allocator;
    2437             :       typedef boost::unordered::detail::allocator_traits<value_allocator>
    2438             :         value_allocator_traits;
    2439             :       typedef N node;
    2440             :       typedef typename boost::unordered::detail::rebind_wrap<A, node>::type
    2441             :         node_allocator;
    2442             :       typedef boost::unordered::detail::allocator_traits<node_allocator>
    2443             :         node_allocator_traits;
    2444             :       typedef typename node_allocator_traits::pointer node_pointer;
    2445             : 
    2446             :     public:
    2447             :       typedef K key_type;
    2448             :       typedef T mapped_type;
    2449             :       typedef A allocator_type;
    2450             : 
    2451             :     private:
    2452             :       node_pointer ptr_;
    2453             :       boost::unordered::detail::optional<value_allocator> alloc_;
    2454             : 
    2455             :       node_handle_map(node_pointer ptr, allocator_type const& a)
    2456             :           : ptr_(ptr), alloc_(a)
    2457             :       {
    2458             :       }
    2459             : 
    2460             :     public:
    2461             :       BOOST_CONSTEXPR node_handle_map() BOOST_NOEXCEPT : ptr_(), alloc_() {}
    2462             : 
    2463             :       ~node_handle_map()
    2464             :       {
    2465             :         if (ptr_) {
    2466             :           node_allocator node_alloc(*alloc_);
    2467             :           boost::unordered::detail::node_tmp<node_allocator> tmp(
    2468             :             ptr_, node_alloc);
    2469             :         }
    2470             :       }
    2471             : 
    2472             :       node_handle_map(BOOST_RV_REF(node_handle_map) n) BOOST_NOEXCEPT
    2473             :         : ptr_(n.ptr_),
    2474             :           alloc_(boost::move(n.alloc_))
    2475             :       {
    2476             :         n.ptr_ = node_pointer();
    2477             :       }
    2478             : 
    2479             :       node_handle_map& operator=(BOOST_RV_REF(node_handle_map) n)
    2480             :       {
    2481             :         BOOST_ASSERT(!alloc_.has_value() ||
    2482             :                      value_allocator_traits::
    2483             :                        propagate_on_container_move_assignment::value ||
    2484             :                      (n.alloc_.has_value() && alloc_ == n.alloc_));
    2485             : 
    2486             :         if (ptr_) {
    2487             :           node_allocator node_alloc(*alloc_);
    2488             :           boost::unordered::detail::node_tmp<node_allocator> tmp(
    2489             :             ptr_, node_alloc);
    2490             :           ptr_ = node_pointer();
    2491             :         }
    2492             : 
    2493             :         if (!alloc_.has_value() ||
    2494             :             value_allocator_traits::propagate_on_container_move_assignment::
    2495             :               value) {
    2496             :           alloc_ = boost::move(n.alloc_);
    2497             :         }
    2498             :         ptr_ = n.ptr_;
    2499             :         n.ptr_ = node_pointer();
    2500             : 
    2501             :         return *this;
    2502             :       }
    2503             : 
    2504             :       key_type& key() const
    2505             :       {
    2506             :         return const_cast<key_type&>(ptr_->value().first);
    2507             :       }
    2508             : 
    2509             :       mapped_type& mapped() const { return ptr_->value().second; }
    2510             : 
    2511             :       allocator_type get_allocator() const { return *alloc_; }
    2512             : 
    2513             :       BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
    2514             : 
    2515             :       bool operator!() const BOOST_NOEXCEPT { return ptr_ ? 0 : 1; }
    2516             : 
    2517             :       bool empty() const BOOST_NOEXCEPT { return ptr_ ? 0 : 1; }
    2518             : 
    2519             :       void swap(node_handle_map& n) BOOST_NOEXCEPT_IF(
    2520             :         value_allocator_traits::propagate_on_container_swap::value ||
    2521             :         value_allocator_traits::is_always_equal::value)
    2522             :       {
    2523             :         BOOST_ASSERT(
    2524             :           !alloc_.has_value() || !n.alloc_.has_value() ||
    2525             :           value_allocator_traits::propagate_on_container_swap::value ||
    2526             :           alloc_ == n.alloc_);
    2527             :         if (value_allocator_traits::propagate_on_container_swap::value ||
    2528             :             !alloc_.has_value() || !n.alloc_.has_value()) {
    2529             :           boost::swap(alloc_, n.alloc_);
    2530             :         }
    2531             :         boost::swap(ptr_, n.ptr_);
    2532             :       }
    2533             :     };
    2534             : 
    2535             :     template <class N, class K, class T, class A>
    2536             :     void swap(node_handle_map<N, K, T, A>& x, node_handle_map<N, K, T, A>& y)
    2537             :       BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(x.swap(y)))
    2538             :     {
    2539             :       x.swap(y);
    2540             :     }
    2541             : 
    2542             :     template <class N, class K, class T, class A> struct insert_return_type_map
    2543             :     {
    2544             :     private:
    2545             :       BOOST_MOVABLE_BUT_NOT_COPYABLE(insert_return_type_map)
    2546             : 
    2547             :       typedef typename boost::unordered::detail::rebind_wrap<A,
    2548             :         std::pair<K const, T> >::type value_allocator;
    2549             :       typedef N node_;
    2550             : 
    2551             :     public:
    2552             :       bool inserted;
    2553             :       boost::unordered::iterator_detail::iterator<node_> position;
    2554             :       boost::unordered::node_handle_map<N, K, T, A> node;
    2555             : 
    2556             :       insert_return_type_map() : inserted(false), position(), node() {}
    2557             : 
    2558             :       insert_return_type_map(BOOST_RV_REF(insert_return_type_map)
    2559             :           x) BOOST_NOEXCEPT : inserted(x.inserted),
    2560             :                               position(x.position),
    2561             :                               node(boost::move(x.node))
    2562             :       {
    2563             :       }
    2564             : 
    2565             :       insert_return_type_map& operator=(BOOST_RV_REF(insert_return_type_map) x)
    2566             :       {
    2567             :         inserted = x.inserted;
    2568             :         position = x.position;
    2569             :         node = boost::move(x.node);
    2570             :         return *this;
    2571             :       }
    2572             :     };
    2573             : 
    2574             :     template <class N, class K, class T, class A>
    2575             :     void swap(insert_return_type_map<N, K, T, A>& x,
    2576             :       insert_return_type_map<N, K, T, A>& y)
    2577             :     {
    2578             :       boost::swap(x.node, y.node);
    2579             :       boost::swap(x.inserted, y.inserted);
    2580             :       boost::swap(x.position, y.position);
    2581             :     }
    2582             :   } // namespace unordered
    2583             : } // namespace boost
    2584             : 
    2585             : #if defined(BOOST_MSVC)
    2586             : #pragma warning(pop)
    2587             : #endif
    2588             : 
    2589             : #endif // BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED

Generated by: LCOV version 1.14