BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_unorderedmultimap.h
Go to the documentation of this file.
1/// @file bslstl_unorderedmultimap.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_unorderedmultimap.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_UNORDEREDMULTIMAP
9#define INCLUDED_BSLSTL_UNORDEREDMULTIMAP
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_unorderedmultimap bslstl_unorderedmultimap
15/// @brief Provide an STL-compliant `unordered_multimap` container.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_unorderedmultimap
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_unorderedmultimap-purpose"> Purpose</a>
25/// * <a href="#bslstl_unorderedmultimap-classes"> Classes </a>
26/// * <a href="#bslstl_unorderedmultimap-description"> Description </a>
27/// * <a href="#bslstl_unorderedmultimap-requirements-on-key-and-value"> Requirements on KEY and VALUE </a>
28/// * <a href="#bslstl_unorderedmultimap-requirements-on-hash-and-equal"> Requirements on HASH and EQUAL </a>
29/// * <a href="#bslstl_unorderedmultimap-memory-allocation"> Memory Allocation </a>
30/// * <a href="#bslstl_unorderedmultimap-bslma-style-allocators"> bslma-Style Allocators </a>
31/// * <a href="#bslstl_unorderedmultimap-operations"> Operations </a>
32/// * <a href="#bslstl_unorderedmultimap-iterator-pointer-and-reference-invalidation"> Iterator, Pointer, and Reference Invalidation </a>
33/// * <a href="#bslstl_unorderedmultimap-unordered-multimap-configuration"> Unordered Multimap Configuration </a>
34/// * <a href="#bslstl_unorderedmultimap-practical-requirements-on-hash"> Practical Requirements on HASH </a>
35/// * <a href="#bslstl_unorderedmultimap-usage"> Usage </a>
36/// * <a href="#bslstl_unorderedmultimap-example-1-creating-a-concordance"> Example 1: Creating a Concordance </a>
37///
38/// # Purpose {#bslstl_unorderedmultimap-purpose}
39/// Provide an STL-compliant @ref unordered_multimap container.
40///
41/// # Classes {#bslstl_unorderedmultimap-classes}
42///
43/// - bsl::unordered_multimap : hashed-map container
44///
45/// **Canonical header:** bsl_unordered_map.h
46///
47/// @see package bos+stdhdrs in the bos package group
48///
49/// # Description {#bslstl_unorderedmultimap-description}
50/// This component defines a single class template,
51/// `bsl::unordered_multimap`, implementing the standard container holding a
52/// collection of (possibly equivalent) keys, each mapped to an associated value
53/// (with minimal guarantees on ordering).
54///
55/// An instantiation of @ref unordered_multimap is an allocator-aware,
56/// value-semantic type whose salient attributes are its size (number of keys)
57/// and the set of key-value pairs the @ref unordered_multimap contains, without
58/// regard to their order. If @ref unordered_multimap is instantiated with a key
59/// type or mapped-value type that is not itself value-semantic, then it will
60/// not retain all of its value-semantic qualities. In particular, if ether the
61/// key or value type cannot be tested for equality, then an
62/// @ref unordered_multimap containing that type cannot be tested for equality. It
63/// is even possible to instantiate @ref unordered_multimap with a key or value
64/// type that does not have an accessible copy-constructor, in which case the
65/// @ref unordered_multimap will not be copyable. Note that the equality operator
66/// for each key-value pair is used to determine when two @ref unordered_multimap
67/// objects have the same value, and not the object of `EQUAL` type supplied at
68/// construction.
69///
70/// An @ref unordered_multimap meets the requirements of an unordered associative
71/// container with forward iterators in the C++11 standard [23.2.5]. The
72/// @ref unordered_multimap implemented here adheres to the C++11 standard when
73/// compiled with a C++11 compiler, and makes the best approximation when
74/// compiled with a C++03 compiler. In particular, for C++03 we emulate move
75/// semantics, but limit forwarding (in `emplace`) to `const` lvalues, and make
76/// no effort to emulate `noexcept` or initializer-lists.
77///
78/// ## Requirements on KEY and VALUE {#bslstl_unorderedmultimap-requirements-on-key-and-value}
79///
80///
81/// An @ref unordered_multimap is a fully Value-Semantic Type (see
82/// @ref bsldoc_glossary ) only if the supplied `KEY` and `VALUE` template
83/// parameters are themselves fully value-semantic. It is possible to
84/// instantiate an @ref unordered_multimap with `KEY` and `VALUE` parameter
85/// arguments that do not provide a full set of value-semantic operations, but
86/// then some methods of the container may not be instantiable. The following
87/// terminology, adopted from the C++11 standard, is used in the function
88/// documentation of @ref unordered_multimap to describe a function's requirements
89/// for the `KEY` and `VALUE` template parameters. These terms are also defined
90/// in section [17.6.3.1] of the C++11 standard. Note that, in the context of
91/// an @ref unordered_multimap instantiation, the requirements apply specifically
92/// to the unordered multimap's element type, `value_type`, which is an alias
93/// for `pair<const KEY, VALUE>`.
94///
95/// Legend
96/// ------
97/// `X` - denotes an allocator-aware container type (@ref unordered_multimap )
98/// `T` - `value_type` associated with `X`
99/// `A` - type of the allocator used by `X`
100/// `m` - lvalue of type `A` (allocator)
101/// `p`, - address (`T *`) of uninitialized storage for a `T` within an `X`
102/// `rv` - rvalue of type (non-`const`) `T`
103/// `v` - rvalue or lvalue of type (possibly `const`) `T`
104/// `args` - 0 or more arguments
105///
106/// The following terms are used to more precisely specify the requirements on
107/// template parameter types in function-level documentation.
108///
109/// *default-insertable*: `T` has a default constructor. More precisely, `T`
110/// is `default-insertable` into `X` means that the following expression is
111/// well-formed:
112///
113/// `allocator_traits<A>::construct(m, p)`
114///
115/// *move-insertable*: `T` provides a constructor that takes an rvalue of type
116/// (non-`const`) `T`. More precisely, `T` is `move-insertable` into `X`
117/// means that the following expression is well-formed:
118///
119/// `allocator_traits<A>::construct(m, p, rv)`
120///
121/// *copy-insertable*: `T` provides a constructor that takes an lvalue or
122/// rvalue of type (possibly `const`) `T`. More precisely, `T` is
123/// `copy-insertable` into `X` means that the following expression is
124/// well-formed:
125///
126/// `allocator_traits<A>::construct(m, p, v)`
127///
128/// *move-assignable*: `T` provides an assignment operator that takes an rvalue
129/// of type (non-`const`) `T`.
130///
131/// *copy-assignable*: `T` provides an assignment operator that takes an lvalue
132/// or rvalue of type (possibly `const`) `T`.
133///
134/// *emplace-constructible*: `T` is `emplace-constructible` into `X` from
135/// `args` means that the following expression is well-formed:
136///
137/// `allocator_traits<A>::construct(m, p, args)`
138///
139/// *erasable*: `T` provides a destructor. More precisely, `T` is `erasable`
140/// from `X` means that the following expression is well-formed:
141///
142/// `allocator_traits<A>::destroy(m, p)`
143///
144/// *equality-comparable*: The type provides an equality-comparison operator
145/// that defines an equivalence relationship and is both reflexive and
146/// transitive.
147///
148/// ## Requirements on HASH and EQUAL {#bslstl_unorderedmultimap-requirements-on-hash-and-equal}
149///
150///
151/// The (template parameter) types `HASH` and `EQUAL` must be copy-constructible
152/// function-objects. Note that this requirement is somewhat stronger than the
153/// requirement currently in the standard; see the discussion for Issue 2215
154/// (http://cplusplus.github.com/LWG/lwg-active.html#2215);
155///
156/// `HASH` shall support a function call operator compatible with the following
157/// statements:
158/// @code
159/// HASH hash;
160/// KEY key;
161/// std::size_t result = hash(key);
162/// @endcode
163/// where the definition of the called function meets the requirements of a
164/// hash function, as specified in {@ref bslstl_hash |Standard Hash Function}.
165///
166/// `EQUAL` shall support a function call operator compatible with the following
167/// statements:
168/// @code
169/// EQUAL equal;
170/// KEY key1, key2;
171/// bool result = equal(key1, key2);
172/// @endcode
173/// where the definition of the called function defines an equivalence
174/// relationship on keys that is both reflexive and transitive.
175///
176/// `HASH` and `EQUAL` function-objects are further constrained such that any
177/// two objects whose keys compare equivalent by the comparator shall also
178/// produce the same value from the hasher.
179///
180/// ## Memory Allocation {#bslstl_unorderedmultimap-memory-allocation}
181///
182///
183/// The type supplied as an unordered multimap's `ALLOCATOR` template parameter
184/// determines how that unordered multimap will allocate memory. The
185/// @ref unordered_multimap template supports allocators meeting the requirements
186/// of the C++11 standard [17.6.3.5]. In addition, it supports
187/// scoped-allocators derived from the `bslma::Allocator` memory allocation
188/// protocol. Clients intending to use `bslma`-style allocators should use the
189/// template's default `ALLOCATOR` type. The default type for the `ALLOCATOR`
190/// template parameter, `bsl::allocator`, provides a C++11 standard-compatible
191/// adapter for a `bslma::Allocator` object.
192///
193/// ### bslma-Style Allocators {#bslstl_unorderedmultimap-bslma-style-allocators}
194///
195///
196/// If the (template parameter) type `ALLOCATOR` of an @ref unordered_multimap
197/// instantiation is `bsl::allocator`, then objects of that unordered multimap
198/// type will conform to the standard behavior of a `bslma`-allocator-enabled
199/// type. Such an unordered multimap accepts an optional `bslma::Allocator`
200/// argument at construction. If the address of a `bslma::Allocator` object is
201/// explicitly supplied at construction, it is used to supply memory for the
202/// unordered multimap throughout its lifetime; otherwise, the unordered
203/// multimap will use the default allocator installed at the time of the
204/// unordered multimap's construction (see @ref bslma_default ). In addition to
205/// directly allocating memory from the indicated `bslma::Allocator`, an
206/// unordered multimap supplies that allocator's address to the constructors of
207/// contained objects of the (template parameter) types `KEY` and `VALUE`, if
208/// respectively, the types define the `bslma::UsesBslmaAllocator` trait.
209///
210/// ## Operations {#bslstl_unorderedmultimap-operations}
211///
212///
213/// This section describes the run-time complexity of operations on instances
214/// of @ref unordered_multimap :
215/// @code
216/// Legend
217/// ------
218/// 'K' - (template parameter) type 'KEY' of 'unordered_multimap'
219/// 'V' - (template parameter) type 'VALUE' of 'unordered_multimap'
220/// 'a', 'b' - two distinct objects of type 'unordered_multimap<K, V>'
221/// 'rv' - modifiable rvalue of type 'unordered_multimap<K, V>'
222/// 'n', 'm' - number of elements in 'a' and 'b', respectively
223/// 'w' - number of buckets of 'a'
224/// 'value_type' - 'pair<const K, V>'
225/// 'hf' - hash function for objects of type 'K'
226/// 'eq' - equivalence comparator for objects of type 'K'
227/// 'al' - STL-style memory allocator
228/// 'k' - an object of type 'K'
229/// 'v' - object of type 'V'
230/// 'vt' - object of type 'value_type'
231/// 'rvt' - modifiable rvalue of type 'value_type'
232/// 'idx' - bucket index
233/// 'li' - object of type 'initializer_list<value_type>'
234/// 'i1', 'i2' - two iterators defining a sequence of 'value_type' objects
235/// 'p1', 'p2' - two iterators belonging to 'a'
236/// distance(i1,i2) - the number of elements in the range '[i1 .. i2)'
237/// distance(p1,p2) - the number of elements in the range '[p1 .. p2)'
238/// 'z' - floating point value representing a load factor
239///
240/// +----------------------------------------------------+--------------------+
241/// | Operation | Complexity |
242/// +====================================================+====================+
243/// | unordered_multimap<K, V> a; (dflt construction) | O[1] |
244/// | unordered_multimap<K, V> a(al); | |
245/// +----------------------------------------------------+--------------------+
246/// | unordered_multimap<K, V> a(rv);(move construction) | O[1] if 'a' and |
247/// | unordered_multimap<K, V> a(rv, al); | 'rv' use the same |
248/// | | allocator, |
249/// | | O[n] otherwise |
250/// +----------------------------------------------------+--------------------+
251/// | unordered_multimap<K, V> a(b); (copy construction) | Average: O[n] |
252/// | unordered_multimap<K, V> a(b, al); | Worst: O[n^2] |
253/// +----------------------------------------------------+--------------------+
254/// | unordered_multimap<K, V> a(w); | O[n] |
255/// | unordered_multimap<K, V> a(w, al); | |
256/// | unordered_multimap<K, V> a(w, hf); | |
257/// | unordered_multimap<K, V> a(w, hf, al); | |
258/// | unordered_multimap<K, V> a(w, hf, eq); | |
259/// | unordered_multimap<K, V> a(w, hf, eq, al); | |
260/// +----------------------------------------------------+--------------------+
261/// | unordered_multimap<K, V> a(i1, i2); | Average: O[N] |
262/// | unordered_multimap<K, V> a(i1, i2, al); | Worst: O[N^2] |
263/// | unordered_multimap<K, V> a(i1, i2, w); | where N = |
264/// | unordered_multimap<K, V> a(i1, i2, w, al); | distance(i1, i2)] |
265/// | unordered_multimap<K, V> a(i1, i2, w, hf); | |
266/// | unordered_multimap<K, V> a(i1, i2, w, hf, al); | |
267/// | unordered_multimap<K, V> a(i1, i2, w, hf, eq); | |
268/// | unordered_multimap<K, V> a(i1, i2, w, hf, eq, al); | |
269/// +----------------------------------------------------+--------------------+
270/// | unordered_multimap<K, V> a(li); | Average: O[N] |
271/// | unordered_multimap<K, V> a(li, al); | Worst: O[N^2] |
272/// | unordered_multimap<K, V> a(li, w); | where N = |
273/// | unordered_multimap<K, V> a(li, w, al); | 'li.size()'|
274/// | unordered_multimap<K, V> a(li, w, hf); | |
275/// | unordered_multimap<K, V> a(li, w, hf, al); | |
276/// | unordered_multimap<K, V> a(li, w, hf, eq); | |
277/// | unordered_multimap<K, V> a(li, w, hf, eq, al); | |
278/// +----------------------------------------------------+--------------------+
279/// | a.~unordered_multimap<K, V>(); (destruction) | O[n] |
280/// +----------------------------------------------------+--------------------+
281/// | a = rv; (move assignment) | O[1] if 'a' and |
282/// | | 'rv' use the same |
283/// | | allocator, |
284/// | | O[n] otherwise |
285/// +----------------------------------------------------+--------------------+
286/// | a = b; (copy assignment) | Average: O[n] |
287/// | | Worst: O[n^2] |
288/// +----------------------------------------------------+--------------------+
289/// | a = li; | Average: O[N] |
290/// | | Worst: O[N^2] |
291/// | | where N = |
292/// | | 'li.size()'|
293/// +----------------------------------------------------+--------------------+
294/// | a.begin(), a.end(), a.cbegin(), a.cend() | O[1] |
295/// +----------------------------------------------------+--------------------+
296/// | a.begin(idx), a.end(idx), a.cbegin(idx), | O[1] |
297/// | a.cend(idx) | |
298/// +----------------------------------------------------+--------------------+
299/// | a == b, a != b | Best: O[n] |
300/// | | Worst: O[n^2] |
301/// +----------------------------------------------------+--------------------+
302/// | a.swap(b), swap(a, b) | O[1] |
303/// +----------------------------------------------------+--------------------+
304/// | a.key_eq() | O[1] |
305/// +----------------------------------------------------+--------------------+
306/// | a.hash_function() | O[1] |
307/// +----------------------------------------------------+--------------------+
308/// | a.size() | O[1] |
309/// +----------------------------------------------------+--------------------+
310/// | a.max_size() | O[1] |
311/// +----------------------------------------------------+--------------------+
312/// | a.empty() | O[1] |
313/// +----------------------------------------------------+--------------------+
314/// | a.allocator() | O[1] |
315/// +----------------------------------------------------+--------------------+
316/// | a.insert(vt) | Average: O[1] |
317/// | a.insert(rvt) | Worst: O[n] |
318/// | a.emplace(Args&&...) | |
319/// +----------------------------------------------------+--------------------+
320/// | a.insert(p1, vt) | Average: O[1] |
321/// | a.insert(p1, rvt) | Worst: O[n] |
322/// | a.emplace(p1, Args&&...) | |
323/// +----------------------------------------------------+--------------------+
324/// | a.insert(i1, i2) | Average: O[ |
325/// | | distance(i1, i2)]|
326/// | | Worst: O[n * |
327/// | | distance(i1, i2)]|
328/// +----------------------------------------------------+--------------------+
329/// | a.insert(li); | Average: O[N] |
330/// | | Worst: O[n * N] |
331/// | | where N = |
332/// | | 'li.size()'|
333/// +----------------------------------------------------+--------------------+
334/// | a.erase(p1) | Average: O[1] |
335/// | | Worst: O[n] |
336/// +----------------------------------------------------+--------------------+
337/// | a.erase(k) | Average: |
338/// | | O[a.count(k)]|
339/// | | Worst: |
340/// | | O[n] |
341/// +----------------------------------------------------+--------------------+
342/// | a.erase(p1, p2) | Average: O[ |
343/// | | distance(p1, p2)]|
344/// | | Worst: O[n] |
345/// +----------------------------------------------------+--------------------+
346/// | a.clear() | O[n] |
347/// +----------------------------------------------------+--------------------+
348/// | a.contains(k) | Average: O[1] |
349/// | | Worst: O[n] |
350/// +----------------------------------------------------+--------------------+
351/// | a.find(k) | Average: O[1] |
352/// | | Worst: O[n] |
353/// +----------------------------------------------------+--------------------+
354/// | a.count(k) | Average: O[1] |
355/// | | Worst: O[n] |
356/// +----------------------------------------------------+--------------------+
357/// | a.equal_range(k) | Average: O[ |
358/// | | a.count(k)]|
359/// | | Worst: O[n] |
360/// +----------------------------------------------------+--------------------+
361/// | a.bucket_count() | O[1] |
362/// +----------------------------------------------------+--------------------+
363/// | a.max_bucket_count() | O[1] |
364/// +----------------------------------------------------+--------------------+
365/// | a.bucket(k) | O[1] |
366/// +----------------------------------------------------+--------------------+
367/// | a.bucket_size(idx) | O[1] |
368/// +----------------------------------------------------+--------------------+
369/// | a.load_factor() | O[1] |
370/// +----------------------------------------------------+--------------------+
371/// | a.max_load_factor() | O[1] |
372/// | a.max_load_factor(z) | Average: O[1] |
373/// +----------------------------------------------------+--------------------+
374/// | a.rehash(w) | Average: O[n] |
375/// | | Worst: O[n^2] |
376/// +----------------------------------------------------+--------------------+
377/// | a.reserve(w) | Average: O[n] |
378/// | | Worst: O[n^2] |
379/// +----------------------------------------------------+--------------------+
380/// @endcode
381///
382/// ## Iterator, Pointer, and Reference Invalidation {#bslstl_unorderedmultimap-iterator-pointer-and-reference-invalidation}
383///
384///
385/// No method of @ref unordered_multimap invalidates a pointer or reference to an
386/// element in the unordered multimap unless it erases that element, such as any
387/// `erase` overload, `clear`, or the destructor (which erases all elements).
388/// Pointers and references are stable through a rehash.
389///
390/// Iterators to elements in the container are invalidated by any rehash, so
391/// iterators may be invalidated by an `insert` or `emplace` call if it triggers
392/// a rehash (but not otherwise). Iterators to specific elements are also
393/// invalidated when those elements are erased. Note that although the `end`
394/// iterator does not refer to any element in the container, it may be
395/// invalidated by any non-`const` method.
396///
397/// ## Unordered Multimap Configuration {#bslstl_unorderedmultimap-unordered-multimap-configuration}
398///
399///
400/// The unordered multimap has interfaces that can provide insight into, and
401/// control of, its inner workings. The syntax and semantics of these
402/// interfaces for `bsl::unordered_multimap` are identical to those of
403/// `bsl::unordered_map`. See the discussion in
404/// {@ref bslstl_unorderedmap |Unordered Map Configuration} and the illustrative
405/// material in {@ref bslstl_unorderedmap |Example 2}.
406///
407/// ## Practical Requirements on HASH {#bslstl_unorderedmultimap-practical-requirements-on-hash}
408///
409///
410/// An important factor in the performance of an unordered multimap (and any of
411/// the other unordered containers) is the choice of a hash function. Please
412/// see the discussion in {@ref bslstl_unorderedmap |Practical Requirements on
413/// `HASH`}.
414///
415/// ## Usage {#bslstl_unorderedmultimap-usage}
416///
417///
418/// In this section we show intended use of this component.
419///
420/// ### Example 1: Creating a Concordance {#bslstl_unorderedmultimap-example-1-creating-a-concordance}
421///
422///
423/// Unordered multimaps are useful in situations when there is no meaningful way
424/// to compare key values, when the order of the keys is irrelevant to the
425/// problem domain, or (even if there is a meaningful ordering) the benefit of
426/// ordering the results is outweighed by the higher performance provided by
427/// unordered multimaps (compared to ordered multimaps).
428///
429/// One uses a multimap (ordered or unordered) when there may be more than one
430/// mapped value associated with a key value. In this example we will use
431/// @ref bslstl_unorderedmultimap to create a concordance (an index of where each
432/// unique word appears in the set of documents).
433///
434/// Our source of documents is a set of statically initialized arrays:
435/// @code
436/// static char document0[] =
437/// " IN CONGRESS, July 4, 1776.\n"
438/// "\n"
439/// " The unanimous Declaration of the thirteen united States of America,\n"
440/// "\n"
441/// " When in the Course of human events, it becomes necessary for one\n"
442/// " people to dissolve the political bands which have connected them with\n"
443/// " another, and to assume among the powers of the earth, the separate\n"
444/// " and equal station to which the Laws of Nature and of Nature's God\n"
445/// " entitle them, a decent respect to the opinions of mankind requires\n"
446/// " that they should declare the causes which impel them to the\n"
447/// " separation. We hold these truths to be self-evident, that all men\n"
448/// " are created equal, that they are endowed by their Creator with\n"
449/// " certain unalienable Rights, that among these are Life, Liberty and\n"
450/// " the pursuit of Happiness.--That to secure these rights, Governments\n"
451/// " are instituted among Men, deriving their just powers from the consent\n"
452/// " of the governed, --That whenever any Form of Government becomes\n"
453/// ...
454/// " States may of right do. And for the support of this Declaration,\n"
455/// " with a firm reliance on the protection of divine Providence, we\n"
456/// " mutually pledge to each other our Lives, our Fortunes and our sacred\n"
457/// " Honor.\n";
458///
459/// static char document1[] =
460/// "/The Universal Declaration of Human Rights\n"
461/// "/-----------------------------------------\n"
462/// "/Preamble\n"
463/// "/ - - - -\n"
464/// " Whereas recognition of the inherent dignity and of the equal and\n"
465/// " inalienable rights of all members of the human family is the\n"
466/// " foundation of freedom, justice and peace in the world,\n"
467/// ...
468/// "/Article 30\n"
469/// "/ - - - - -\n"
470/// " Nothing in this Declaration may be interpreted as implying for any\n"
471/// " State, group or person any right to engage in any activity or to\n"
472/// " perform any act aimed at the destruction of any of the rights and\n"
473/// " freedoms set forth herein.\n";
474///
475/// static char document2[] =
476/// "/CHARTER OF FUNDAMENTAL RIGHTS OF THE EUROPEAN UNION\n"
477/// "/---------------------------------------------------\n"
478/// " PREAMBLE\n"
479/// "\n"
480/// " The peoples of Europe, in creating an ever closer union among them,\n"
481/// " are resolved to share a peaceful future based on common values.\n"
482/// ...
483/// "/Article 54\n"
484/// "/- - - -\n"
485/// " Prohibition of abuse of rights\n"
486/// "\n"
487/// " Nothing in this Charter shall be interpreted as implying any right to\n"
488/// " engage in any activity or to perform any act aimed at the destruction\n"
489/// " of any of the rights and freedoms recognized in this Charter or at\n"
490/// " their limitation to a greater extent than is provided for herein.\n";
491///
492/// static char * const documents[] = { document0,
493/// document1,
494/// document2
495/// };
496/// const int numDocuments = sizeof documents / sizeof *documents;
497/// @endcode
498/// First, we define several aliases to make our code more comprehensible:
499/// @code
500/// /// Document code number (`first`) and word offset (`second`) in that
501/// /// document specify a word location. The first word in the document
502/// /// is at word offset 0.
503/// typedef bsl::pair<int, int> WordLocation;
504///
505/// typedef bsl::unordered_multimap<bsl::string, WordLocation>
506/// Concordance;
507/// typedef Concordance::const_iterator ConcordanceConstItr;
508/// @endcode
509/// Next, we create an (empty) unordered multimap to hold our word tallies:
510/// @code
511/// Concordance concordance;
512/// @endcode
513/// Then, we define the set of characters that define word boundaries:
514/// @code
515/// const char *delimiters = " \n\t,:;.()[]?!/";
516/// @endcode
517/// Next, we extract the words from our documents. Note that `strtok` modifies
518/// the document arrays (which were not made `const`).
519///
520/// As each word is located, we create a map value -- a pair of the word
521/// converted to a `bsl::string` and a `WordLocation` object (itself a pair of
522/// document code and (word) offset of that word in the document) -- and insert
523/// the map value into the unordered multimap. Note that (unlike maps and
524/// unordered maps) there is no status to check; the insertion succeeds even if
525/// the key is already present in the unordered multimap.
526/// @code
527/// for (int idx = 0; idx < numDocuments; ++idx) {
528/// int wordOffset = 0;
529/// for (char *cur = strtok(documents[idx], delimiters);
530/// cur;
531/// cur = strtok(NULL, delimiters)) {
532/// WordLocation location(idx, wordOffset++);
533/// Concordance::value_type value(bsl::string(cur), location);
534/// concordance.insert(value);
535/// }
536/// }
537/// @endcode
538/// Then, we can print a complete concordance by iterating through the unordered
539/// multimap:
540/// @code
541/// for (ConcordanceConstItr itr = concordance.begin(),
542/// end = concordance.end();
543/// end != itr; ++itr) {
544/// printf("\"%s\", %2d, %4d\n",
545/// itr->first.c_str(),
546/// itr->second.first,
547/// itr->second.second);
548/// }
549/// @endcode
550/// Standard output shows:
551/// @code
552/// "extent", 2, 3837
553/// "greater", 2, 3836
554/// "abuse", 2, 3791
555/// "constitutions", 2, 3782
556/// "affecting", 2, 3727
557/// ...
558/// "he", 1, 1746
559/// "he", 1, 714
560/// "he", 0, 401
561/// "include", 2, 847
562/// @endcode
563/// Next, if there are some particular words of interest, we seek them out using
564/// the @ref equal_range method of the `concordance` object:
565/// @code
566/// const bsl::string wordsOfInterest[] = { "human",
567/// "rights",
568/// "unalienable",
569/// "inalienable"
570/// };
571/// const size_t numWordsOfInterest = sizeof wordsOfInterest
572/// / sizeof *wordsOfInterest;
573///
574/// for (size_t idx = 0; idx < numWordsOfInterest; ++idx) {
575/// bsl::pair<ConcordanceConstItr,
576/// ConcordanceConstItr> found = concordance.equal_range(
577/// wordsOfInterest[idx]);
578/// for (ConcordanceConstItr itr = found.first,
579/// end = found.second;
580/// end != itr; ++itr) {
581/// printf("\"%s\", %2d, %4d\n",
582/// itr->first.c_str(),
583/// itr->second.first,
584/// itr->second.second);
585/// }
586/// printf("\n");
587/// }
588/// @endcode
589/// Finally, we see on standard output:
590/// @code
591/// "human", 2, 3492
592/// "human", 2, 2192
593/// "human", 2, 534
594/// ...
595/// "human", 1, 65
596/// "human", 1, 43
597/// "human", 1, 25
598/// "human", 0, 20
599///
600/// "rights", 2, 3583
601/// "rights", 2, 3553
602/// "rights", 2, 3493
603/// ...
604/// "rights", 1, 44
605/// "rights", 1, 19
606/// "rights", 0, 496
607/// "rights", 0, 126
608///
609/// "unalienable", 0, 109
610///
611/// "inalienable", 1, 18
612///
613/// @endcode
614/// {@ref bslstl_unorderedmap |Example 3} shows how to use the concordance to create
615/// an inverse concordance, and how to use the inverse concordance to find the
616/// context (surrounding words) of a word of interest.
617/// @}
618/** @} */
619/** @} */
620
621/** @addtogroup bsl
622 * @{
623 */
624/** @addtogroup bslstl
625 * @{
626 */
627/** @addtogroup bslstl_unorderedmultimap
628 * @{
629 */
630
631#include <bslscm_version.h>
632
633#include <bslstl_equalto.h>
634#include <bslstl_hash.h>
635#include <bslstl_hashtable.h>
638#include <bslstl_iteratorutil.h>
639#include <bslstl_pair.h>
641
645
647#include <bslma_isstdallocator.h>
648#include <bslma_bslallocator.h>
650
651#include <bslmf_enableif.h>
653#include <bslmf_isconvertible.h>
654#include <bslmf_movableref.h>
656#include <bslmf_typeidentity.h>
657#include <bslmf_util.h> // 'forward(V)'
658
659#include <bsls_assert.h>
661#include <bsls_keyword.h>
662#include <bsls_performancehint.h>
663#include <bsls_platform.h>
664#include <bsls_util.h> // 'forward<T>(V)'
665
666#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
667# include <initializer_list>
668#endif
669
670#ifdef BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
671#include <type_traits> // 'std::is_constructible'
672 #ifndef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
673 #error Rvalue references curiously absent despite native 'type_traits'.
674 #endif
675#endif
676
677#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
678// Include version that can be compiled with C++03
679// Generated on Thu Oct 21 10:11:37 2021
680// Command line: sim_cpp11_features.pl bslstl_unorderedmultimap.h
681# define COMPILING_BSLSTL_UNORDEREDMULTIMAP_H
683# undef COMPILING_BSLSTL_UNORDEREDMULTIMAP_H
684#else
685
686namespace bsl {
687
688/// This class template implements a value-semantic container type holding a
689/// collection of (possibly equivalent) keys (of the template parameter type
690/// `KEY`), each mapped to their associated values (of another template
691/// parameter type `VALUE`).
692///
693/// This class:
694/// * supports a complete set of *value-semantic* operations
695/// - except for BDEX serialization
696/// * is *exception-neutral* (agnostic except for the `at` method)
697/// * is *alias-safe*
698/// * is `const` *thread-safe*
699/// For terminology see @ref bsldoc_glossary .
700///
701/// See @ref bslstl_unorderedmultimap
702template <class KEY,
703 class VALUE,
704 class HASH = bsl::hash<KEY>,
705 class EQUAL = bsl::equal_to<KEY>,
708
709 private:
710 // PRIVATE TYPES
711
712 /// This `typedef` is an alias for the allocator traits type associated
713 /// with this container.
715
716 /// This `typedef` is an alias for the type of key-value pair objects
717 /// maintained by this unordered multimap.
719
720 /// This `typedef` is an alias for the policy used internally by this
721 /// container to extract the `KEY` value from the values maintained by
722 /// this unordered multimap.
723 typedef ::BloombergLP::bslstl::UnorderedMapKeyConfiguration<const KEY,
724 ValueType>
725 ListConfiguration;
726
727 /// This `typedef` is an alias for the template instantiation of the
728 /// underlying `bslstl::HashTable` used to implement this unordered
729 /// multimap.
730 typedef ::BloombergLP::bslstl::HashTable<ListConfiguration,
731 HASH,
732 EQUAL,
733 ALLOCATOR> Impl;
734
735 /// This `typedef` is an alias for the type of links maintained by the
736 /// linked list of elements held by the underlying `bslstl::HashTable`.
737 typedef ::BloombergLP::bslalg::BidirectionalLink HashTableLink;
738
739 /// This `typedef` is a convenient alias for the utility associated with
740 /// movable references.
741 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
742
743 // FRIENDS
744 template <class KEY2,
745 class VALUE2,
746 class HASH2,
747 class EQUAL2,
748 class ALLOCATOR2>
749 friend bool operator==(
752
753 public:
754 // PUBLIC TYPES
755 typedef KEY key_type;
756 typedef VALUE mapped_type;
758 typedef HASH hasher;
759 typedef EQUAL key_equal;
760 typedef ALLOCATOR allocator_type;
761
764
769
770 typedef ::BloombergLP::bslstl::HashTableIterator<
772
773 typedef ::BloombergLP::bslstl::HashTableIterator<
775
776 typedef ::BloombergLP::bslstl::HashTableBucketIterator<
778
779 typedef ::BloombergLP::bslstl::HashTableBucketIterator<
781
782 private:
783 // DATA
784 Impl d_impl;
785
786 public:
787 // CREATORS
788
790 explicit unordered_multimap(size_type initialNumBuckets,
791 const HASH& hashFunction = HASH(),
792 const EQUAL& keyEqual = EQUAL(),
793 const ALLOCATOR& basicAllocator = ALLOCATOR());
794 unordered_multimap(size_type initialNumBuckets,
795 const HASH& hashFunction,
796 const ALLOCATOR& basicAllocator);
797 unordered_multimap(size_type initialNumBuckets,
798 const ALLOCATOR& basicAllocator);
799 /// Create an empty unordered multimap. Optionally specify an
800 /// `initialNumBuckets` indicating the minimum initial size of the array
801 /// of buckets of this container. If `initialNumBuckets` is not
802 /// supplied, a single empty bucket is used. Optionally specify a
803 /// `hashFunction` used to generate the hash values for the keys
804 /// contained in this unordered multimap. If `hashFunction` is not
805 /// supplied, a default-constructed object of the (template parameter)
806 /// type `HASH` is used. Optionally specify a key-equivalence functor
807 /// `keyEqual` used to verify that two keys are equivalent. If
808 /// `keyEqual` is not supplied, a default-constructed object of the
809 /// (template parameter) type `EQUAL` is used. Optionally specify a
810 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
811 /// supplied, a default-constructed object of the (template parameter)
812 /// type `ALLOCATOR` is used. If the type `ALLOCATOR` is
813 /// `bsl::allocator` (the default), then `basicAllocator`, if supplied,
814 /// shall be convertible to `bslma::Allocator *`. If the type
815 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
816 /// supplied, the currently installed default allocator is used.
817 explicit unordered_multimap(const ALLOCATOR& basicAllocator);
818
819 /// Create an unordered multimap having the same value as the specified
820 /// `original` object. Use a copy of `original.hash_function()` to
821 /// generate hash values for the keys contained in this unordered
822 /// multimap. Use a copy of `original.key_eq()` to verify that two keys
823 /// are equivalent. Use the allocator returned by
824 /// `bsl::allocator_traits<ALLOCATOR>::
825 /// select_on_container_copy_construction(original.get_allocator())` to
826 /// allocate memory. This method requires that the (template parameter)
827 /// types `KEY` and `VALUE` both be `copy-insertable` into this
828 /// unordered multimap (see {Requirements on `KEY` and `VALUE`}).
829 unordered_multimap(const unordered_multimap& original);
830
831 /// Create an unordered multimap having the same value as the specified
832 /// `original` object by moving (in constant time) the contents of
833 /// `original` to the new unordered multimap. Use a copy of
834 /// `original.hash_function()` to generate hash values for the keys
835 /// contained in this unordered multimap. Use a copy of
836 /// `original.key_eq()` to verify that two keys are equivalent. The
837 /// allocator associated with `original` is propagated for use in the
838 /// newly-created unordered multimap. `original` is left in a valid but
839 /// unspecified state.
841 BloombergLP::bslmf::MovableRef<unordered_multimap> original);
842
843 /// Create an unordered multimap having the same value as the specified
844 /// `original` object that uses the specified `basicAllocator` to supply
845 /// memory. Use a copy of `original.hash_function()` to generate hash
846 /// values for the keys contained in this unordered multimap. Use a
847 /// copy of `original.key_eq()` to verify that two keys are equivalent.
848 /// This method requires that the (template parameter) types `KEY` and
849 /// `VALUE` both be `copy-insertable` into this unordered multimap (see
850 /// {Requirements on `KEY` and `VALUE`}). Note that a
851 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
852 /// (template parameter) type `ALLOCATOR` is `bsl::allocator` (the
853 /// default).
855 const unordered_multimap& original,
856 const typename type_identity<ALLOCATOR>::type& basicAllocator);
857
858 /// Create an unordered multimap having the same value as the specified
859 /// `original` object that uses the specified `basicAllocator` to supply
860 /// memory. The contents of `original` are moved (in constant time) to
861 /// the new unordered multimap if `basicAllocator ==
862 /// original.get_allocator()`, and are move-inserted (in linear time)
863 /// using `basicAllocator` otherwise. `original` is left in a valid but
864 /// unspecified state. Use a copy of `original.hash_function()` to
865 /// generate hash values for the keys contained in this unordered
866 /// multimap. Use a copy of `original.key_eq()` to verify that two keys
867 /// are equivalent. This method requires that the (template parameter)
868 /// types `KEY` and `VALUE` both be `move-insertable` into this
869 /// unordered multimap (see {Requirements on `KEY` and `VALUE`}). Note
870 /// that a `bslma::Allocator *` can be supplied for `basicAllocator` if
871 /// the (template parameter) type `ALLOCATOR` is `bsl::allocator` (the
872 /// default).
874 BloombergLP::bslmf::MovableRef<unordered_multimap> original,
875 const typename type_identity<ALLOCATOR>::type& basicAllocator);
876
877 /// Create an unordered multimap, and insert each `value_type` object in
878 /// the sequence starting at the specified `first` element, and ending
879 /// immediately before the specified `last` element. Optionally specify
880 /// an `initialNumBuckets` indicating the minimum initial size of the
881 /// array of buckets of this container. If `initialNumBuckets` is not
882 /// supplied, a single empty bucket is used if `first` and `last` denote
883 /// an empty range, and an unspecified number of buckets is used
884 /// otherwise. Optionally specify a `hashFunction` used to generate
885 /// hash values for the keys contained in this unordered multimap. If
886 /// `hashFunction` is not supplied, a default-constructed object of
887 /// (template parameter) type `HASH` is used. Optionally specify a
888 /// key-equivalence functor `keyEqual` used to verify that two keys are
889 /// equivalent. If `keyEqual` is not supplied, a default-constructed
890 /// object of (template parameter) type `EQUAL` is used. Optionally
891 /// specify a `basicAllocator` used to supply memory. If
892 /// `basicAllocator` is not supplied, a default-constructed object of
893 /// the (template parameter) type `ALLOCATOR` is used. If the type
894 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
895 /// supplied, the currently installed default allocator is used to
896 /// supply memory. The (template parameter) type `INPUT_ITERATOR` shall
897 /// meet the requirements of an input iterator defined in the C++11
898 /// standard [24.2.3] providing access to values of a type convertible
899 /// to `value_type`, and `value_type` must be `emplace-constructible`
900 /// from `*i` into this unordered multimap, where `i` is a
901 /// dereferenceable iterator in the range `[first .. last)` (see
902 /// {Requirements on `KEY` and `VALUE`}). The behavior is undefined
903 /// unless `first` and `last` refer to a sequence of valid values where
904 /// `first` is at a position at or before `last`. Note that a
905 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
906 /// type `ALLOCATOR` is `bsl::allocator` (the default).
907 template <class INPUT_ITERATOR>
908 unordered_multimap(INPUT_ITERATOR first,
909 INPUT_ITERATOR last,
910 size_type initialNumBuckets = 0,
911 const HASH& hashFunction = HASH(),
912 const EQUAL& keyEqual = EQUAL(),
913 const ALLOCATOR& basicAllocator = ALLOCATOR());
914 template <class INPUT_ITERATOR>
915 unordered_multimap(INPUT_ITERATOR first,
916 INPUT_ITERATOR last,
917 size_type initialNumBuckets,
918 const HASH& hashFunction,
919 const ALLOCATOR& basicAllocator);
920 template <class INPUT_ITERATOR>
921 unordered_multimap(INPUT_ITERATOR first,
922 INPUT_ITERATOR last,
923 size_type initialNumBuckets,
924 const ALLOCATOR& basicAllocator);
925 template <class INPUT_ITERATOR>
926 unordered_multimap(INPUT_ITERATOR first,
927 INPUT_ITERATOR last,
928 const ALLOCATOR& basicAllocator);
929
930#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
931# ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
932 template <
933 class = bsl::enable_if_t<std::is_invocable_v<HASH, const KEY &>>,
934 class = bsl::enable_if_t<
935 std::is_invocable_v<EQUAL, const KEY &, const KEY &>>,
936 class = bsl::enable_if_t< bsl::IsStdAllocator_v<ALLOCATOR>>
937 >
938# endif
940 std::initializer_list<value_type> values,
941 size_type initialNumBuckets = 0,
942 const HASH& hashFunction = HASH(),
943 const EQUAL& keyEqual = EQUAL(),
944 const ALLOCATOR& basicAllocator = ALLOCATOR());
945# ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
946 template <
947 class = bsl::enable_if_t<std::is_invocable_v<HASH, const KEY &>>,
948 class = bsl::enable_if_t< bsl::IsStdAllocator_v<ALLOCATOR>>
949 >
950# endif
951 unordered_multimap(std::initializer_list<value_type> values,
952 size_type initialNumBuckets,
953 const HASH& hashFunction,
954 const ALLOCATOR& basicAllocator);
955# ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
956 template <
957 class = bsl::enable_if_t< bsl::IsStdAllocator_v<ALLOCATOR>>
958 >
959# endif
960 unordered_multimap(std::initializer_list<value_type> values,
961 size_type initialNumBuckets,
962 const ALLOCATOR& basicAllocator);
963# ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
964 /// Create an unordered multimap and insert each `value_type` object in
965 /// the specified `values` initializer list. Optionally specify an
966 /// `initialNumBuckets` indicating the minimum initial size of the array
967 /// of buckets of this container. If `initialNumBuckets` is not
968 /// supplied, a single empty bucket is used if `values` is empty, and an
969 /// unspecified number of buckets is used otherwise. Optionally specify
970 /// a `hashFunction` used to generate the hash values for the keys
971 /// contained in this unordered multimap. If `hashFunction` is not
972 /// supplied, a default-constructed object of the (template parameter)
973 /// type `HASH` is used. Optionally specify a key-equivalence functor
974 /// `keyEqual` used to verify that two keys are equivalent. If
975 /// `keyEqual` is not supplied, a default-constructed object of the
976 /// (template parameter) type `EQUAL` is used. Optionally specify a
977 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
978 /// supplied, a default-constructed object of the (template parameter)
979 /// type `ALLOCATOR` is used. If the type `ALLOCATOR` is
980 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
981 /// installed default allocator is used to supply memory. This method
982 /// requires that the (template parameter) types `KEY` and `VALUE` both
983 /// be `copy-insertable` into this unordered multimap (see {Requirements
984 /// on `KEY` and `VALUE`}). Note that a `bslma::Allocator *` can be
985 /// supplied for `basicAllocator` if the type `ALLOCATOR` is
986 /// `bsl::allocator` (the default).
987 template <
988 class = bsl::enable_if_t< bsl::IsStdAllocator_v<ALLOCATOR>>
989 >
990# endif
991 unordered_multimap(std::initializer_list<value_type> values,
992 const ALLOCATOR& basicAllocator);
993#endif
994
995 /// Destroy this object.
997
998 // MANIPULATORS
999
1000 /// Assign to this object the value, hash function, and key-equivalence
1001 /// comparator of the specified `rhs` object, propagate to this object
1002 /// the allocator of `rhs` if the `ALLOCATOR` type has trait
1003 /// `propagate_on_container_copy_assignment`, and return a reference
1004 /// providing modifiable access to this object. If an exception is
1005 /// thrown, `*this` is left in a valid but unspecified state. This
1006 /// method requires that the (template parameter) types `KEY` and
1007 /// `VALUE` both be `copy-assignable` and `copy-insertable` into this
1008 /// unordered multimap (see {Requirements on `KEY` and `VALUE`}).
1009 unordered_multimap& operator=(const unordered_multimap& rhs);
1010
1011 /// Assign to this object the value, hash function, and key-equivalence
1012 /// comparator of the specified `rhs` object, propagate to this object
1013 /// the allocator of `rhs` if the `ALLOCATOR` type has trait
1014 /// `propagate_on_container_move_assignment`, and return a reference
1015 /// providing modifiable access to this object. The contents of `rhs`
1016 /// are moved (in constant time) to this unordered multimap if
1017 /// `get_allocator() == rhs.get_allocator()` (after accounting for the
1018 /// aforementioned trait); otherwise, all elements in this unordered
1019 /// multimap are either destroyed or move-assigned to, and each
1020 /// additional element in `rhs` is move-inserted into this unordered
1021 /// multimap. `rhs` is left in a valid but unspecified state, and if an
1022 /// exception is thrown, `*this` is left in a valid but unspecified
1023 /// state. This method requires that the (template parameter) types
1024 /// `KEY` and `VALUE` both be `move-assignable` and `move-insertable`
1025 /// into this unordered multimap (see {Requirements on `KEY` and
1026 /// `VALUE`}).
1028 operator=(BloombergLP::bslmf::MovableRef<unordered_multimap> rhs)
1030 AllocatorTraits::is_always_equal::value &&
1031 std::is_nothrow_move_assignable<HASH>::value &&
1032 std::is_nothrow_move_assignable<EQUAL>::value);
1033
1034#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1035 /// Assign to this object the value resulting from first clearing this
1036 /// unordered multimap and then inserting each `value_type` object in
1037 /// the specified `values` initializer list, and return a reference
1038 /// providing modifiable access to this object. This method requires
1039 /// that the (template parameter) types `KEY` and `VALUE` both be
1040 /// `copy-insertable` into this unordered multimap (see {Requirements on
1041 /// `KEY` and `VALUE`}).
1042 unordered_multimap& operator=(std::initializer_list<value_type> values);
1043#endif
1044
1045 /// Return an iterator providing modifiable access to the first
1046 /// `value_type` object (in the sequence of `value_type` objects)
1047 /// maintained by this unordered multimap, or the `end` iterator if this
1048 /// unordered multimap is empty.
1050
1051 /// Return an iterator providing modifiable access to the past-the-end
1052 /// position in the sequence of `value_type` objects maintained by this
1053 /// unordered multimap.
1055
1056 /// Return a local iterator providing modifiable access to the first
1057 /// `value_type` object in the sequence of `value_type` objects of the
1058 /// bucket having the specified `index` in the array of buckets
1059 /// maintained by this unordered multimap, or the `end(index)` iterator
1060 /// if the indexed bucket is empty. The behavior is undefined unless
1061 /// `index < bucket_count()`.
1062 local_iterator begin(size_type index);
1063
1064 /// Return a local iterator providing modifiable access to the
1065 /// past-the-end position in the sequence of `value_type` objects of the
1066 /// bucket having the specified `index` in the array of buckets
1067 /// maintained by this unordered multimap. The behavior is undefined
1068 /// unless `index < bucket_count()`.
1069 local_iterator end(size_type index);
1070
1071 /// Remove all entries from this unordered multimap. Note that this
1072 /// object will be empty after this call, but allocated memory may be
1073 /// retained for future use.
1075
1076 /// Return a pair of iterators providing modifiable access to the
1077 /// sequence of `value_type` objects in this unordered multimap with a
1078 /// key equivalent to the specified `key`, where the first iterator is
1079 /// positioned at the start of the sequence, and the second is
1080 /// positioned one past the end of the sequence. If this unordered
1081 /// multimap contains no `value_type` objects with a key equivalent to
1082 /// `key`, then the two returned iterators will have the same value.
1083 /// The behavior is undefined unless `key` is equivalent to the key of
1084 /// the elements of at most one equivalent-key group in this unordered
1085 /// multimap.
1086 template <class LOOKUP_KEY>
1087 typename enable_if<
1088 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
1089 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
1090 pair<iterator, iterator> >::type
1091 equal_range(const LOOKUP_KEY& key)
1092 {
1093 // Note: implemented inline due to Sun CC compilation error.
1094 typedef bsl::pair<iterator, iterator> ResultType;
1095 HashTableLink *first;
1096 HashTableLink *last;
1097 d_impl.findRange(&first, &last, key);
1098 return ResultType(iterator(first), iterator(last));
1099 }
1100
1101 /// Return a pair of iterators providing modifiable access to the
1102 /// sequence of `value_type` objects in this unordered multimap with a
1103 /// key equivalent to the specified `key`, where the first iterator is
1104 /// positioned at the start of the sequence, and the second is
1105 /// positioned one past the end of the sequence. If this unordered
1106 /// multimap contains no `value_type` objects with a key equivalent to
1107 /// `key`, then the two returned iterators will have the same value.
1108 pair<iterator, iterator> equal_range(const key_type& key);
1109
1110 /// Remove from this unordered multimap all `value_type` objects with a
1111 /// key equivalent to the specified `key`, if such exist, and return the
1112 /// number of objects erased; otherwise, if there are no `value_type`
1113 /// objects with a key equivalent to `key`, return 0 with no other
1114 /// effect. This method invalidates only iterators and references to
1115 /// the removed element and previously saved values of the `end()`
1116 /// iterator, and preserves the relative order of the elements not
1117 /// removed.
1118 size_type erase(const key_type& key);
1119
1120 iterator erase(const_iterator position);
1121 /// Remove from this unordered multimap the `value_type` object at the
1122 /// specified `position`, and return an iterator referring to the
1123 /// element immediately following the removed element, or to the
1124 /// past-the-end position if the removed element was the last element in
1125 /// the sequence of elements maintained by this unordered multimap.
1126 /// This method invalidates only iterators and references to the removed
1127 /// element and previously saved values of the `end()` iterator, and
1128 /// preserves the relative order of the elements not removed. The
1129 /// behavior is undefined unless `position` refers to a `value_type`
1130 /// object in this unordered multimap.
1131 iterator erase(iterator position);
1132
1133 /// Remove from this unordered multimap the `value_type` objects
1134 /// starting at the specified `first` position up to, but not including,
1135 /// the specified `last` position, and return `last`. This method
1136 /// invalidates only iterators and references to the removed element and
1137 /// previously saved values of the `end()` iterator, and preserves the
1138 /// relative order of the elements not removed. The behavior is
1139 /// undefined unless `first` and `last` either refer to elements in this
1140 /// unordered multimap or are the `end` iterator, and the `first`
1141 /// position is at or before the `last` position in the sequence
1142 /// provided by this container.
1144
1145 /// Return an iterator providing modifiable access to the first
1146 /// `value_type` object in the sequence of all the `value_type` objects
1147 /// of this unordered multimap with a key equivalent to the specified
1148 /// `key`, if such entries exist, and the past-the-end (`end`) iterator
1149 /// otherwise. The behavior is undefined unless `key` is equivalent to
1150 /// the key of the elements of at most one equivalent-key group in this
1151 /// unordered multimap.
1152 template <class LOOKUP_KEY>
1153 typename enable_if<
1154 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
1155 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
1156 iterator>::type
1157 find(const LOOKUP_KEY& key)
1158 {
1159 // Note: implemented inline due to Sun CC compilation error.
1160 return iterator(d_impl.find(key));
1161 }
1162
1163 /// Return an iterator providing modifiable access to the first
1164 /// `value_type` object in the sequence of all the `value_type` objects
1165 /// of this unordered multimap with a key equivalent to the specified
1166 /// `key`, if such entries exist, and the past-the-end (`end`) iterator
1167 /// otherwise.
1168 iterator find(const key_type& key);
1169
1170 /// Insert the specified `value` into this unordered multimap, and
1171 /// return an iterator referring to the newly inserted `value_type`
1172 /// object. This method requires that the (template parameter) types
1173 /// `KEY` and `VALUE` both be `copy-insertable` into this unordered
1174 /// multimap (see {Requirements on `KEY` and `VALUE`}).
1175 iterator insert(const value_type& value);
1176
1177#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
1178 template <class ALT_VALUE_TYPE>
1179 iterator
1180#elif !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
1181 template <class ALT_VALUE_TYPE>
1183 iterator>::type
1184#else
1185 /// Insert into this unordered multimap a `value_type` object created
1186 /// from the specified `value`, and return an iterator referring to the
1187 /// newly inserted `value_type` object. This method requires that the
1188 /// (template parameter) types `KEY` and `VALUE` both be
1189 /// `move-insertable` into this unordered multimap (see {Requirements on
1190 /// `KEY` and `VALUE`}), and the `value_type` be constructible from the
1191 /// (template parameter) `ALT_VALUE_TYPE`.
1192 template <class ALT_VALUE_TYPE>
1193 typename enable_if<std::is_constructible<value_type,
1194 ALT_VALUE_TYPE&&>::value,
1195 iterator>::type
1196#endif
1198 {
1199 // Note that some compilers fail when this method is defined
1200 // out-of-line.
1201
1202 return emplace(BSLS_COMPILERFEATURES_FORWARD(ALT_VALUE_TYPE, value));
1203 }
1204
1205 /// Insert the specified `value` into this unordered multimap (in
1206 /// constant time if the specified `hint` refers to an element in this
1207 /// container with a key equivalent to the key of `value`), and return
1208 /// an iterator referring to the newly inserted `value_type` object. If
1209 /// `hint` does not refer to an element in this container with a key
1210 /// equivalent to the key of `value`, this operation has worst case
1211 /// `O[N]` and average case constant-time complexity, where `N` is the
1212 /// size of this unordered multimap. This method requires that the
1213 /// (template parameter) types `KEY` and `VALUE` both be
1214 /// `copy-insertable` into this unordered multimap (see {Requirements on
1215 /// `KEY` and `VALUE`}). The behavior is undefined unless `hint` is an
1216 /// iterator in the range `[begin() .. end()]` (both endpoints
1217 /// included).
1218 iterator insert(const_iterator hint, const value_type& value);
1219
1220#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
1221 template <class ALT_VALUE_TYPE>
1222 iterator
1223#elif !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
1224 template <class ALT_VALUE_TYPE>
1226 iterator>::type
1227#else
1228 /// Insert into this unordered multimap a `value_type` object created
1229 /// from the specified `value` (in constant time if the specified `hint`
1230 /// refers to an element in this container with a key equivalent to the
1231 /// key of `value`), and return an iterator referring to the newly
1232 /// inserted `value_type` object. If `hint` does not refer to an
1233 /// element in this container with a key equivalent to the key of
1234 /// `value`, this operation has worst case `O[N]` and average case
1235 /// constant-time complexity, where `N` is the size of this unordered
1236 /// multimap. This method requires that the (template parameter) types
1237 /// `KEY` and `VALUE` both be `move-insertable` into this unordered
1238 /// multimap (see {Requirements on `KEY` and `VALUE`}), and the
1239 /// `value_type` be constructible from the (template parameter)
1240 /// `ALT_VALUE_TYPE`. The behavior is undefined unless `hint` is an
1241 /// iterator in the range `[begin() .. end()]` (both endpoints
1242 /// included).
1243 template <class ALT_VALUE_TYPE>
1244 typename enable_if<std::is_constructible<value_type,
1245 ALT_VALUE_TYPE&&>::value,
1246 iterator>::type
1247#endif
1249 BSLS_COMPILERFEATURES_FORWARD_REF(ALT_VALUE_TYPE) value)
1250 {
1251 // Note that some compilers fail when this method is defined
1252 // out-of-line.
1253
1254 return emplace_hint(hint,
1255 BSLS_COMPILERFEATURES_FORWARD(ALT_VALUE_TYPE, value));
1256 }
1257
1258 /// Insert into this unordered multimap the value of each `value_type`
1259 /// object in the range starting at the specified `first` iterator and
1260 /// ending immediately before the specified `last` iterator. The
1261 /// (template parameter) type `INPUT_ITERATOR` shall meet the
1262 /// requirements of an input iterator defined in the C++11 standard
1263 /// [24.2.3] providing access to values of a type convertible to
1264 /// `value_type`, and `value_type` must be `emplace-constructible` from
1265 /// `*i` into this unordered multimap, where `i` is a dereferenceable
1266 /// iterator in the range `[first .. last)` (see {Requirements on `KEY`
1267 /// and `VALUE`}). The behavior is undefined unless `first` and `last`
1268 /// refer to a sequence of valid values where `first` is at a position
1269 /// at or before `last`.
1270 template <class INPUT_ITERATOR>
1271 void insert(INPUT_ITERATOR first, INPUT_ITERATOR last);
1272
1273#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1274 /// Insert into this unordered multimap the value of each `value_type`
1275 /// object in the specified `values` initializer list. This method
1276 /// requires that the (template parameter) types `KEY` and `VALUE` both
1277 /// be `copy-insertable` into this unordered multimap (see {Requirements
1278 /// on `KEY` and `VALUE`}).
1279 void insert(std::initializer_list<value_type> values);
1280#endif
1281
1282#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=2
1283
1284 /// Insert into this unordered multimap a newly created `value_type`
1285 /// object, constructed by forwarding `get_allocator()` (if required)
1286 /// and the specified (variable number of) `args` to the corresponding
1287 /// constructor of `value_type`. Return an iterator referring to the
1288 /// newly created and inserted object in this unordered multimap. This
1289 /// method requires that the (template parameter) types `KEY` and
1290 /// `VALUE` both be `emplace-constructible` from `args` (see
1291 /// {Requirements on `KEY` and `VALUE`}).
1292 template <class... Args>
1293 iterator emplace(Args&&... args);
1294
1295 /// Insert into this unordered multimap a newly created `value_type`
1296 /// object, constructed by forwarding `get_allocator()` (if required)
1297 /// and the specified (variable number of) `args` to the corresponding
1298 /// constructor of `value_type` (in constant time if the specified
1299 /// `hint` refers to an element in this container with a key equivalent
1300 /// to the key of the newly created `value_type` object), and return an
1301 /// iterator referring to the newly created and inserted object. If
1302 /// `hint` does not refer to an element in this container with a key
1303 /// equivalent to the key of the newly created `value_type` object, this
1304 /// operation has worst case `O[N]` and average case constant-time
1305 /// complexity, where `N` is the size of this unordered multimap. This
1306 /// method requires that the (template parameter) types `KEY` and
1307 /// `VALUE` both be `emplace-constructible` from `args` (see
1308 /// {Requirements on `KEY` and `VALUE`}). The behavior is undefined
1309 /// unless `hint` is an iterator in the range `[begin() .. end()]` (both
1310 /// endpoints included).
1311 template <class... Args>
1312 iterator emplace_hint(const_iterator hint, Args&&... args);
1313
1314#endif
1315
1316 /// Set the maximum load factor of this container to the specified
1317 /// `newLoadFactor`.
1318 void max_load_factor(float newLoadFactor);
1319
1320 /// Change the size of the array of buckets maintained by this container
1321 /// to the specified `numBuckets`, and redistribute all the contained
1322 /// elements into the new sequence of buckets, according to their hash
1323 /// values. Note that this operation has no effect if rehashing the
1324 /// elements into `numBuckets` would cause this unordered multimap to
1325 /// exceed its `max_load_factor`.
1326 void rehash(size_type numBuckets);
1327
1328 /// Increase the number of buckets of this unordered multimap to a
1329 /// quantity such that the ratio between the specified `numElements` and
1330 /// the new number of buckets does not exceed `max_load_factor`. Note
1331 /// that this guarantees that, after the reserve, elements can be
1332 /// inserted to grow the container to `size() == numElements` without
1333 /// rehashing. Also note that memory allocations may still occur when
1334 /// growing the container to `size() == numElements`. Also note that
1335 /// this operation has no effect if `numElements <= size()`.
1336 void reserve(size_type numElements);
1337
1338 // Exchange the value, hasher, key-equality functor, and
1339 // `max_load_factor` of this object with those of the specified `other`
1340 // object; also exchange the allocator of this object with that of
1341 // `other` if the (template parameter) type `ALLOCATOR` has the
1342 // `propagate_on_container_swap` trait, and do not modify either
1343 // allocator otherwise. This method provides the no-throw
1344 // exception-safety guarantee if and only if both the (template
1345 // parameter) types `HASH` and `EQUAL` provide no-throw swap
1346 // operations; if an exception is thrown, both objects are left in
1347 // valid but unspecified states. This operation guarantees `O[1]`
1348 // complexity. The behavior is undefined unless either this object was
1349 // created with the same allocator as `other` or `ALLOCATOR` has the
1350 // `propagate_on_container_swap` trait.
1352 AllocatorTraits::is_always_equal::value &&
1353 bsl::is_nothrow_swappable<HASH>::value &&
1354 bsl::is_nothrow_swappable<EQUAL>::value);
1355
1356 // ACCESSORS
1357
1358 /// Return (a copy of) the allocator used for memory allocation by this
1359 /// unordered multimap.
1361
1363
1364 /// Return an iterator providing non-modifiable access to the first
1365 /// `value_type` object in the sequence of `value_type` objects
1366 /// maintained by this unordered multimap, or the `end` iterator if this
1367 /// unordered multimap is empty.
1369
1371
1372 /// Return an iterator providing non-modifiable access to the
1373 /// past-the-end position in the sequence of `value_type` objects
1374 /// maintained by this unordered multimap.
1376
1377 /// Return `true` if this unordered map contains an element whose key is
1378 /// equivalent to the specified `key`.
1379 bool contains(const key_type &key) const;
1380
1381 /// Return `true` if this unordered map contains an element whose key is
1382 /// equivalent to the specified `key`.
1383 template <class LOOKUP_KEY>
1384 typename enable_if<
1385 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value &&
1386 BloombergLP::bslmf::IsTransparentPredicate<EQUAL,
1387 LOOKUP_KEY>::value,
1388 bool>::type
1389 contains(const LOOKUP_KEY& key) const
1390 {
1391 // Note: implemented inline due to Sun CC compilation error
1392 return find(key) != end();
1393 }
1394
1395 /// Return `true` if this unordered multimap contains no elements, and
1396 /// `false` otherwise.
1397 bool empty() const BSLS_KEYWORD_NOEXCEPT;
1398
1399 /// Return the number of elements in this unordered multimap.
1401
1402 /// Return a theoretical upper bound on the largest number of elements
1403 /// that this unordered multimap could possibly hold. Note that there
1404 /// is no guarantee that the unordered multimap can successfully grow to
1405 /// the returned size, or even close to that size without running out of
1406 /// resources.
1408
1409 /// Return (a copy of) the key-equivalence binary functor that returns
1410 /// `true` if the value of two `key_type` objects are equivalent, and
1411 /// `false` otherwise.
1412 EQUAL key_eq() const;
1413
1414 /// Return (a copy of) the hash unary functor used by this unordered
1415 /// multimap to generate a hash value (of type `size_type`) for a
1416 /// `key_type` object.
1417 HASH hash_function() const;
1418
1419 /// Return an iterator providing modifiable access to the first
1420 /// `value_type` object in this unordered multimap whose key is
1421 /// equivalent to the specified `key`, if such an entry exists, and the
1422 /// past-the-end (`end`) iterator otherwise. The behavior is undefined
1423 /// unless `key` is equivalent to the key of the elements of at most one
1424 /// equivalent-key group in this unordered multimap.
1425 template <class LOOKUP_KEY>
1426 typename enable_if<
1427 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
1428 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
1429 const_iterator>::type
1430 find(const LOOKUP_KEY& key) const
1431 {
1432 // Note: implemented inline due to Sun CC compilation error.
1433 return const_iterator(d_impl.find(key));
1434 }
1435
1436 /// Return an iterator providing non-modifiable access to the first
1437 /// `value_type` object in the sequence of `value_type` objects of this
1438 /// unordered multimap with a key equivalent to the specified `key`, if
1439 /// such entries exist, and the past-the-end (`end`) iterator otherwise.
1440 const_iterator find(const key_type& key) const;
1441
1442 /// Return the number of `value_type` objects in this unordered multimap
1443 /// with a key equivalent to the specified `key`. The behavior is
1444 /// undefined unless `key` is equivalent to the key of the elements of
1445 /// at most one equivalent-key group in this unordered multimap.
1446 template <class LOOKUP_KEY>
1447 typename enable_if<
1448 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
1449 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
1450 size_type>::type
1451 count(const LOOKUP_KEY& key) const
1452 {
1453 // Note: implemented inline due to Sun CC compilation error.
1454 typedef ::BloombergLP::bslalg::BidirectionalNode<value_type> BNode;
1455
1456 size_type result = 0;
1457 for (HashTableLink *cursor = d_impl.find(key);
1458 cursor;
1459 ++result, cursor = cursor->nextLink())
1460 {
1461 BNode *cursorNode = static_cast<BNode *>(cursor);
1462 if (!this->key_eq()(
1463 key,
1464 ListConfiguration::extractKey(cursorNode->value()))) {
1465
1466 break;
1467 }
1468 }
1469 return result;
1470 }
1471
1472 /// Return the number of `value_type` objects in this unordered multimap
1473 /// with a key equivalent to the specified `key`.
1474 size_type count(const key_type& key) const;
1475
1476 /// Return a pair of iterators providing non-modifiable access to the
1477 /// sequence of `value_type` objects in this unordered multimap with a
1478 /// key equivalent to the specified `key`, where the first iterator is
1479 /// positioned at the start of the sequence, and the second is
1480 /// positioned one past the end of the sequence. If this unordered
1481 /// multimap contains no `value_type` objects with a key equivalent to
1482 /// `key`, then the two returned iterators will have the same value.
1483 /// The behavior is undefined unless `key` is equivalent to the key of
1484 /// the elements of at most one equivalent-key group in this unordered
1485 /// multimap.
1486 template <class LOOKUP_KEY>
1487 typename enable_if<
1488 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
1489 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
1491 equal_range(const LOOKUP_KEY& key) const
1492 {
1493 // Note: implemented inline due to Sun CC compilation error.
1495 HashTableLink *first;
1496 HashTableLink *last;
1497 d_impl.findRange(&first, &last, key);
1498 return ResultType(const_iterator(first), const_iterator(last));
1499 }
1500
1501 /// Return a pair of iterators providing non-modifiable access to the
1502 /// sequence of `value_type` objects in this unordered multimap with a
1503 /// key equivalent to the specified `key`, where the first iterator is
1504 /// positioned at the start of the sequence, and the second is
1505 /// positioned one past the end of the sequence. If this unordered
1506 /// multimap contains no `value_type` objects with a key equivalent to
1507 /// `key`, then the two returned iterators will have the same value.
1509 const key_type& key) const;
1510
1512
1513 /// Return a local iterator providing non-modifiable access to the first
1514 /// `value_type` object (in the sequence of `value_type` objects) of the
1515 /// bucket having the specified `index` in the array of buckets
1516 /// maintained by this unordered multimap, or the `end(index)` iterator
1517 /// if the indexed bucket is empty. The behavior is undefined unless
1518 /// `index < bucket_count()`.
1520
1521 const_local_iterator end(size_type index) const;
1522
1523 /// Return a local iterator providing non-modifiable access to the
1524 /// past-the-end position (in the sequence of `value_type` objects) of
1525 /// the bucket having the specified `index` in the array of buckets
1526 /// maintained by this unordered multimap. The behavior is undefined
1527 /// unless `index < bucket_count()`.
1528 const_local_iterator cend(size_type index) const;
1529
1530 /// Return the index of the bucket, in the array of buckets of this
1531 /// container, where a value with a key equivalent to the specified
1532 /// `key` would be inserted.
1533 size_type bucket(const key_type& key) const;
1534
1535 /// Return the number of buckets in the array of buckets maintained by
1536 /// this unordered multimap.
1538
1539 /// Return a theoretical upper bound on the largest number of buckets
1540 /// that this container could possibly manage. Note that there is no
1541 /// guarantee that the unordered multimap can successfully grow to the
1542 /// returned size, or even close to that size without running out of
1543 /// resources.
1545
1546 /// Return the number of elements contained in the bucket at the
1547 /// specified `index` in the array of buckets maintained by this
1548 /// container. The behavior is undefined unless
1549 /// `index < bucket_count()`.
1550 size_type bucket_size(size_type index) const;
1551
1552 /// Return the current ratio between the `size` of this container and
1553 /// the number of buckets. The load factor is a measure of how full the
1554 /// container is, and a higher load factor typically leads to an
1555 /// increased number of collisions, thus resulting in a loss of
1556 /// performance.
1557 float load_factor() const BSLS_KEYWORD_NOEXCEPT;
1558
1559 /// Return the maximum load factor allowed for this container. Note
1560 /// that if an insert operation would cause the load factor to exceed
1561 /// the `max_load_factor`, that same insert operation will increase the
1562 /// number of buckets and rehash the elements of the container into
1563 /// those buckets (see `rehash`).
1565};
1566
1567#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1568// CLASS TEMPLATE DEDUCTION GUIDES
1569
1570/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1571/// of the iterators supplied to the constructor of @ref unordered_multimap .
1572/// Deduce the template parameters `HASH`, `EQUAL` and `ALLOCATOR` from the
1573/// other parameters passed to the constructor of @ref unordered_multimap .
1574/// This deduction guide does not participate unless the supplied allocator
1575/// meets the requirements of a standard allocator.
1576template <
1577 class INPUT_ITERATOR,
1578 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1579 class VALUE =
1580 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1581 class HASH = bsl::hash<KEY>,
1582 class EQUAL = bsl::equal_to<KEY>,
1583 class ALLOCATOR = bsl::allocator<pair<const KEY, VALUE>>,
1584 class = bsl::enable_if_t<std::is_invocable_v<HASH, const KEY &>>,
1585 class = bsl::enable_if_t<
1586 std::is_invocable_v<EQUAL, const KEY &, const KEY &>>,
1587 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1588 >
1589unordered_multimap(INPUT_ITERATOR,
1590 INPUT_ITERATOR,
1591 typename bsl::allocator_traits<ALLOCATOR>::size_type = 0,
1592 HASH = HASH(),
1593 EQUAL = EQUAL(),
1594 ALLOCATOR = ALLOCATOR())
1595-> unordered_multimap<KEY, VALUE, HASH, EQUAL, ALLOCATOR>;
1596
1597/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1598/// of the iterators supplied to the constructor of @ref unordered_multimap .
1599/// Deduce the template parameters `HASH` and "EQUAL' from the other
1600/// parameters passed to the constructor of @ref unordered_multimap . This
1601/// deduction guide does not participate unless the supplied allocator is
1602/// convertible to `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1603template <
1604 class INPUT_ITERATOR,
1605 class HASH,
1606 class EQUAL,
1607 class ALLOC,
1608 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1609 class VALUE =
1610 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1611 class DEFAULT_ALLOCATOR = bsl::allocator<pair<const KEY, VALUE>>,
1612 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1613 >
1615 INPUT_ITERATOR,
1616 INPUT_ITERATOR,
1617 typename bsl::allocator_traits<DEFAULT_ALLOCATOR>::size_type,
1618 HASH,
1619 EQUAL,
1620 ALLOC *)
1621-> unordered_multimap<KEY, VALUE, HASH, EQUAL>;
1622
1623/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1624/// of the iterators supplied to the constructor of @ref unordered_multimap .
1625/// Deduce the template parameters `HASH` and `ALLOCATOR` from the other
1626/// parameters passed to the constructor of @ref unordered_multimap . This
1627/// deduction guide does not participate unless the supplied hash is
1628/// invokable with a `KEY`, and the supplied allocator meets the
1629/// requirements of a standard allocator.
1630template <
1631 class INPUT_ITERATOR,
1632 class HASH,
1633 class ALLOCATOR,
1634 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1635 class VALUE =
1636 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1637 class = bsl::enable_if_t<std::is_invocable_v<HASH, const KEY &>>,
1638 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1639 >
1640unordered_multimap(INPUT_ITERATOR,
1641 INPUT_ITERATOR,
1642 typename bsl::allocator_traits<ALLOCATOR>::size_type,
1643 HASH,
1644 ALLOCATOR)
1645-> unordered_multimap<KEY, VALUE, HASH, bsl::equal_to<KEY>, ALLOCATOR>;
1646
1647/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1648/// of the iterators supplied to the constructor of @ref unordered_multimap .
1649/// Deduce the template parameter `HASH` from the other parameters passed to
1650/// the constructor of @ref unordered_multimap . This deduction guide does not
1651/// participate unless the supplied allocator is convertible to
1652/// `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1653template <
1654 class INPUT_ITERATOR,
1655 class HASH,
1656 class ALLOC,
1657 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1658 class VALUE =
1659 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1660 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1661 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1662 >
1664 INPUT_ITERATOR,
1665 INPUT_ITERATOR,
1666 typename bsl::allocator_traits<DEFAULT_ALLOCATOR>::size_type,
1667 HASH,
1668 ALLOC *)
1669-> unordered_multimap<KEY, VALUE, HASH>;
1670
1671/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1672/// of the iterators supplied to the constructor of @ref unordered_multimap .
1673/// This deduction guide does not participate unless the supplied allocator
1674/// meets the requirements of a standard allocator.
1675template <
1676 class INPUT_ITERATOR,
1677 class ALLOCATOR,
1678 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1679 class VALUE =
1680 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1681 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1682 >
1683unordered_multimap(INPUT_ITERATOR,
1684 INPUT_ITERATOR,
1685 typename bsl::allocator_traits<ALLOCATOR>::size_type,
1686 ALLOCATOR)
1687-> unordered_multimap<KEY,
1688 VALUE,
1689 bsl::hash<KEY>,
1690 bsl::equal_to<KEY>,
1691 ALLOCATOR>;
1692
1693/// of the iterators supplied to the constructor of @ref unordered_multimap .
1694/// Deduce the template parameter `ALLOCATOR` from the other parameter
1695/// passed to the constructor of @ref unordered_multimap . This deduction guide
1696/// does not participate unless the supplied allocator meets the
1697/// requirements of a standard allocator.
1698template <
1699 class INPUT_ITERATOR,
1700 class ALLOC,
1701 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1702 class VALUE =
1703 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1704 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1705 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1706 >
1708 INPUT_ITERATOR,
1709 INPUT_ITERATOR,
1710 typename bsl::allocator_traits<DEFAULT_ALLOCATOR>::size_type,
1711 ALLOC *)
1712-> unordered_multimap<KEY, VALUE>;
1713
1714/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1715/// of the iterators supplied to the constructor of @ref unordered_multimap .
1716/// Deduce the template parameter `ALLOCATOR` from the other parameter
1717/// passed to the constructor of @ref unordered_multimap . This deduction guide
1718/// does not participate unless the supplied allocator meets the
1719/// requirements of a standard allocator.
1720template <
1721 class INPUT_ITERATOR,
1722 class ALLOCATOR,
1723 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1724 class VALUE =
1725 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1726 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1727 >
1728unordered_multimap(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR)
1729-> unordered_multimap<KEY,
1730 VALUE,
1731 bsl::hash<KEY>,
1732 bsl::equal_to<KEY>,
1733 ALLOCATOR>;
1734
1735/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1736/// of the iterators supplied to the constructor of @ref unordered_multimap .
1737/// This deduction guide does not participate unless the supplied allocator
1738/// is convertible to `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1739template <
1740 class INPUT_ITERATOR,
1741 class ALLOC,
1742 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1743 class VALUE =
1744 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1745 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1746 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1747 >
1748unordered_multimap(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
1749-> unordered_multimap<KEY, VALUE>;
1750
1751/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1752/// of the initializer_list supplied to the constructor of
1753/// @ref unordered_multimap . Deduce the template parameters `HASH`, `EQUAL`
1754/// and `ALLOCATOR` from the other parameters supplied to the constructor of
1755/// @ref unordered_multimap . This deduction guide does not participate unless:
1756/// (1) the supplied `HASH` is invokable with a `KEY`, (2) the supplied
1757/// `EQUAL` is invokable with two `KEY`s, and (3) the supplied allocator
1758/// meets the requirements of a standard allocator.
1759template <
1760 class KEY,
1761 class VALUE,
1762 class HASH = bsl::hash<KEY>,
1763 class EQUAL = bsl::equal_to<KEY>,
1764 class ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1765 class = bsl::enable_if_t<std::is_invocable_v<HASH, const KEY &>>,
1766 class = bsl::enable_if_t<
1767 std::is_invocable_v<EQUAL, const KEY &, const KEY &>>,
1768 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1769 >
1770unordered_multimap(std::initializer_list<bsl::pair<const KEY, VALUE>>,
1771 typename bsl::allocator_traits<ALLOCATOR>::size_type = 0,
1772 HASH = HASH(),
1773 EQUAL = EQUAL(),
1774 ALLOCATOR = ALLOCATOR())
1775-> unordered_multimap<KEY, VALUE, HASH, EQUAL, ALLOCATOR>;
1776
1777/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1778/// of the initializer_list supplied to the constructor of
1779/// @ref unordered_multimap . Deduce the template parameters `HASH`, `EQUAL`
1780/// and `ALLOCATOR` from the other parameters supplied to the constructor of
1781/// @ref unordered_multimap . This deduction guide does not participate unless
1782/// the supplied allocator is convertible to
1783/// `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1784template <
1785 class KEY,
1786 class VALUE,
1787 class HASH,
1788 class EQUAL,
1789 class ALLOC,
1790 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1791 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1792 >
1794 std::initializer_list<bsl::pair<const KEY, VALUE>>,
1795 typename bsl::allocator_traits<DEFAULT_ALLOCATOR>::size_type,
1796 HASH,
1797 EQUAL,
1798 ALLOC *)
1799-> unordered_multimap<KEY, VALUE, HASH, EQUAL>;
1800
1801/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1802/// of the initializer_list supplied to the constructor of
1803/// @ref unordered_multimap . Deduce the template parameters `HASH` and
1804/// `ALLOCATOR` from the other parameters supplied to the constructor of
1805/// @ref unordered_multimap . This deduction guide does not participate unless
1806/// the supplied `HASH` is invokable with a `KEY`, and the supplied
1807/// allocator meets the requirements of a standard allocator.
1808template <
1809 class KEY,
1810 class VALUE,
1811 class HASH,
1812 class ALLOCATOR,
1813 class = bsl::enable_if_t<std::is_invocable_v<HASH, const KEY &>>,
1814 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1815 >
1816unordered_multimap(std::initializer_list<bsl::pair<const KEY, VALUE>>,
1817 typename bsl::allocator_traits<ALLOCATOR>::size_type,
1818 HASH,
1819 ALLOCATOR)
1820-> unordered_multimap<KEY, VALUE, HASH, bsl::equal_to<KEY>, ALLOCATOR>;
1821
1822/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1823/// of the initializer_list supplied to the constructor of
1824/// @ref unordered_multimap . Deduce the template parameter `HASH` from the
1825/// other parameters supplied to the constructor of @ref unordered_multimap .
1826/// This deduction guide does not participate unless the supplied allocator
1827/// is convertible to `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1828template <
1829 class KEY,
1830 class VALUE,
1831 class HASH,
1832 class ALLOC,
1833 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1834 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1835 >
1837 std::initializer_list<bsl::pair<const KEY, VALUE>>,
1838 typename bsl::allocator_traits<DEFAULT_ALLOCATOR>::size_type,
1839 HASH,
1840 ALLOC *)
1841-> unordered_multimap<KEY, VALUE, HASH>;
1842
1843/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1844/// of the initializer_list supplied to the constructor of
1845/// @ref unordered_multimap . This deduction guide does not participate unless
1846/// the supplied allocator meets the requirements of a standard allocator.
1847template <
1848 class KEY,
1849 class VALUE,
1850 class ALLOCATOR,
1851 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1852 >
1853unordered_multimap(std::initializer_list<bsl::pair<const KEY, VALUE>>,
1854 typename bsl::allocator_traits<ALLOCATOR>::size_type,
1855 ALLOCATOR)
1856-> unordered_multimap<KEY,
1857 VALUE,
1858 bsl::hash<KEY>,
1859 bsl::equal_to<KEY>,
1860 ALLOCATOR>;
1861
1862/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1863/// of the initializer_list supplied to the constructor of
1864/// @ref unordered_multimap . This deduction guide does not participate unless
1865/// the supplied allocator is convertible to
1866/// `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1867template <
1868 class KEY,
1869 class VALUE,
1870 class ALLOC,
1871 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1872 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1873 >
1875 std::initializer_list<bsl::pair<const KEY, VALUE>>,
1876 typename bsl::allocator_traits<DEFAULT_ALLOCATOR>::size_type,
1877 ALLOC *)
1878-> unordered_multimap<KEY, VALUE>;
1879
1880/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1881/// of the initializer_list supplied to the constructor of
1882/// @ref unordered_multimap . Deduce the template parameter `ALLOCATOR` from
1883/// the other parameters supplied to the constructor of
1884/// @ref unordered_multimap . This deduction guide does not participate unless
1885/// the supplied allocator meets the requirements of a standard allocator.
1886template <
1887 class KEY,
1888 class VALUE,
1889 class ALLOCATOR,
1890 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1891 >
1892unordered_multimap(std::initializer_list<bsl::pair<const KEY, VALUE>>,
1893 ALLOCATOR)
1894-> unordered_multimap<KEY,
1895 VALUE,
1896 bsl::hash<KEY>,
1897 bsl::equal_to<KEY>,
1898 ALLOCATOR>;
1899
1900/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1901/// of the initializer_list supplied to the constructor of
1902/// @ref unordered_multimap . This deduction guide does not participate unless
1903/// the supplied allocator is convertible to
1904/// `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1905template <
1906 class KEY,
1907 class VALUE,
1908 class ALLOC,
1909 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1910 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1911 >
1912unordered_multimap(std::initializer_list<bsl::pair<const KEY, VALUE>>, ALLOC *)
1913-> unordered_multimap<KEY, VALUE>;
1914#endif
1915
1916// FREE OPERATORS
1917
1918/// Return `true` if the specified `lhs` and `rhs` objects have the same
1919/// value, and `false` otherwise. Two @ref unordered_multimap objects have the
1920/// same value if they have the same number of key-value pairs, and each
1921/// key-value pair that is contained in one of the objects is also contained
1922/// in the other object. This method requires that the (template parameter)
1923/// types `KEY` and `VALUE` both be `equality-comparable` (see {Requirements
1924/// on `KEY` and `VALUE`}).
1925template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
1926bool operator==(
1927 const unordered_multimap<KEY, VALUE, HASH, EQUAL, ALLOCATOR>& lhs,
1928 const unordered_multimap<KEY, VALUE, HASH, EQUAL, ALLOCATOR>& rhs);
1929
1930#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1931template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
1932bool operator!=(
1933 const unordered_multimap<KEY, VALUE, HASH, EQUAL, ALLOCATOR>& lhs,
1934 const unordered_multimap<KEY, VALUE, HASH, EQUAL, ALLOCATOR>& rhs);
1935 // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the
1936 // same value, and 'false' otherwise. Two @ref unordered_multimap objects do
1937 // not have the same value if they do not have the same number of key-value
1938 // pairs, or some key-value pair that is contained in one of the objects is
1939 // not also contained in the other object. This method requires that the
1940 // (template parameter) types 'KEY' and 'VALUE' both be
1941 // 'equality-comparable' (see {Requirements on 'KEY' and 'VALUE'}).
1942#endif
1943
1944// FREE FUNCTIONS
1945
1946/// Exchange the value, hasher, key-equality functor, and `max_load_factor`
1947/// of the specified `a` object with those of the specified `b` object; also
1948/// exchange the allocator of `a` with that of `b` if the (template
1949/// parameter) type `ALLOCATOR` has the `propagate_on_container_swap` trait,
1950/// and do not modify either allocator otherwise. This function provides
1951/// the no-throw exception-safety guarantee if and only if both the
1952/// (template parameter) types `HASH` and `EQUAL` provide no-throw swap
1953/// operations; if an exception is thrown, both objects are left in valid
1954/// but unspecified states. This operation guarantees `O[1]` complexity.
1955/// The behavior is undefined unless either `a` was created with the same
1956/// allocator as `b` or `ALLOCATOR` has the `propagate_on_container_swap`
1957/// trait.
1958template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
1959void swap(unordered_multimap<KEY, VALUE, HASH, EQUAL, ALLOCATOR>& a,
1960 unordered_multimap<KEY, VALUE, HASH, EQUAL, ALLOCATOR>& b)
1962
1963// ============================================================================
1964// TEMPLATE AND INLINE FUNCTION DEFINITIONS
1965// ============================================================================
1966
1967 //-------------------------
1968 // class unordered_multimap
1969 //-------------------------
1970
1971// CREATORS
1972template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
1973inline
1974unordered_multimap<KEY, VALUE, HASH, EQUAL, ALLOCATOR>::unordered_multimap()
1975: d_impl(HASH(), EQUAL(), 0, 1.0f, ALLOCATOR())
1976{
1977}
1978
1979template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
1980inline
1982 size_type initialNumBuckets,
1983 const HASH& hashFunction,
1984 const EQUAL& keyEqual,
1985 const ALLOCATOR& basicAllocator)
1986: d_impl(hashFunction, keyEqual, initialNumBuckets, 1.0f, basicAllocator)
1987{
1988}
1989
1990template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
1991inline
1993 size_type initialNumBuckets,
1994 const HASH& hashFunction,
1995 const ALLOCATOR& basicAllocator)
1996: d_impl(hashFunction, EQUAL(), initialNumBuckets, 1.0f, basicAllocator)
1997{
1998}
1999
2000template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2001inline
2003 size_type initialNumBuckets,
2004 const ALLOCATOR& basicAllocator)
2005: d_impl(HASH(), EQUAL(), initialNumBuckets, 1.0f, basicAllocator)
2006{
2007}
2008
2009template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2010inline
2012 const ALLOCATOR& basicAllocator)
2013: d_impl(basicAllocator)
2014{
2015}
2016
2017template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2018inline
2020 const unordered_multimap& original)
2021: d_impl(original.d_impl,
2022 AllocatorTraits::select_on_container_copy_construction(
2023 original.get_allocator()))
2024{
2025}
2026
2027template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2028inline
2030 BloombergLP::bslmf::MovableRef<unordered_multimap> original)
2031: d_impl(MoveUtil::move(MoveUtil::access(original).d_impl))
2032{
2033}
2034
2035template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2036inline
2038 const unordered_multimap& original,
2039 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2040: d_impl(original.d_impl, basicAllocator)
2041{
2042}
2043
2044template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2045inline
2047 BloombergLP::bslmf::MovableRef<unordered_multimap> original,
2048 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2049: d_impl(MoveUtil::move(MoveUtil::access(original).d_impl), basicAllocator)
2050{
2051}
2052
2053template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2054template <class INPUT_ITERATOR>
2055inline
2057 INPUT_ITERATOR first,
2058 INPUT_ITERATOR last,
2059 size_type initialNumBuckets,
2060 const HASH& hashFunction,
2061 const EQUAL& keyEqual,
2062 const ALLOCATOR& basicAllocator)
2063: d_impl(hashFunction, keyEqual, initialNumBuckets, 1.0f, basicAllocator)
2064{
2065 this->insert(first, last);
2066}
2067
2068template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2069template <class INPUT_ITERATOR>
2070inline
2072 INPUT_ITERATOR first,
2073 INPUT_ITERATOR last,
2074 size_type initialNumBuckets,
2075 const HASH& hashFunction,
2076 const ALLOCATOR& basicAllocator)
2077: d_impl(hashFunction, EQUAL(), initialNumBuckets, 1.0f, basicAllocator)
2078{
2079 this->insert(first, last);
2080}
2081
2082template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2083template <class INPUT_ITERATOR>
2084inline
2086 INPUT_ITERATOR first,
2087 INPUT_ITERATOR last,
2088 size_type initialNumBuckets,
2089 const ALLOCATOR& basicAllocator)
2090: d_impl(HASH(), EQUAL(), initialNumBuckets, 1.0f, basicAllocator)
2091{
2092 this->insert(first, last);
2093}
2094
2095template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2096template <class INPUT_ITERATOR>
2097inline
2099 INPUT_ITERATOR first,
2100 INPUT_ITERATOR last,
2101 const ALLOCATOR& basicAllocator)
2102: d_impl(HASH(), EQUAL(), 0, 1.0f, basicAllocator)
2103{
2104 this->insert(first, last);
2105}
2106
2107#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2108template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2109# ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
2110template <class, class, class>
2111# endif
2112inline
2114 std::initializer_list<value_type> values,
2115 size_type initialNumBuckets,
2116 const HASH& hashFunction,
2117 const EQUAL& keyEqual,
2118 const ALLOCATOR& basicAllocator)
2119: unordered_multimap(values.begin(),
2120 values.end(),
2121 initialNumBuckets,
2122 hashFunction,
2123 keyEqual,
2124 basicAllocator)
2125{
2126}
2127
2128template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2129# ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
2130template <class, class>
2131# endif
2132inline
2134 std::initializer_list<value_type> values,
2135 size_type initialNumBuckets,
2136 const HASH& hashFunction,
2137 const ALLOCATOR& basicAllocator)
2138: unordered_multimap(values.begin(),
2139 values.end(),
2140 initialNumBuckets,
2141 hashFunction,
2142 EQUAL(),
2143 basicAllocator)
2144{
2145}
2146
2147template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2148# ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
2149template <class>
2150# endif
2151inline
2153 std::initializer_list<value_type> values,
2154 size_type initialNumBuckets,
2155 const ALLOCATOR& basicAllocator)
2156: unordered_multimap(values.begin(),
2157 values.end(),
2158 initialNumBuckets,
2159 HASH(),
2160 EQUAL(),
2161 basicAllocator)
2162{
2163}
2164
2165template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2166# ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
2167template <class>
2168# endif
2169inline
2171 std::initializer_list<value_type> values,
2172 const ALLOCATOR& basicAllocator)
2173: unordered_multimap(values.begin(),
2174 values.end(),
2175 0,
2176 HASH(),
2177 EQUAL(),
2178 basicAllocator)
2179{
2180}
2181#endif // defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2182
2183template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2185{
2186 // All memory management is handled by the base 'd_impl' member.
2187}
2188
2189// MANIPULATORS
2190template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2193 const unordered_multimap& rhs)
2194{
2195 // Note that we have delegated responsibility for correct handling of
2196 // allocator propagation to the 'HashTable' implementation.
2197
2198 d_impl = rhs.d_impl;
2199
2200 return *this;
2201}
2202
2203template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2204inline
2207 BloombergLP::bslmf::MovableRef<unordered_multimap> rhs)
2209 AllocatorTraits::is_always_equal::value &&
2210 std::is_nothrow_move_assignable<HASH>::value &&
2211 std::is_nothrow_move_assignable<EQUAL>::value)
2212{
2213 // Note that we have delegated responsibility for correct handling of
2214 // allocator propagation to the 'HashTable' implementation.
2215
2216 unordered_multimap& lvalue = rhs;
2217
2218 d_impl = MoveUtil::move(lvalue.d_impl);
2219
2220 return *this;
2221}
2222
2223#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2224template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2225inline
2226unordered_multimap<KEY, VALUE, HASH, EQUAL, ALLOCATOR>&
2228 std::initializer_list<value_type> values)
2229{
2230 unordered_multimap tmp(values.begin(), values.end(), d_impl.allocator());
2231
2232 d_impl.swap(tmp.d_impl);
2233
2234 return *this;
2235}
2236#endif
2237
2238#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2239template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2240template <class... Args>
2241inline
2244{
2245 return iterator(d_impl.emplace(
2246 BSLS_COMPILERFEATURES_FORWARD(Args, args)...));
2247
2248}
2249
2250template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2251template <class... Args>
2252inline
2255 const_iterator hint,
2256 Args&&... args)
2257{
2258 return iterator(d_impl.emplaceWithHint(hint.node(),
2259 BSLS_COMPILERFEATURES_FORWARD(Args, args)...));
2260}
2261#endif
2262
2263template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2264inline
2271
2272template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2273inline
2280
2281template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2282inline
2285{
2286 BSLS_ASSERT_SAFE(index < this->bucket_count());
2287
2288 return local_iterator(&d_impl.bucketAtIndex(index));
2289}
2290
2291template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2292inline
2295{
2296 BSLS_ASSERT_SAFE(index < this->bucket_count());
2297
2298 return local_iterator(0, &d_impl.bucketAtIndex(index));
2299}
2300
2301
2302template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2303inline
2309
2310template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2311inline
2313 const key_type& key) const
2314{
2315 return find(key) != end();
2316}
2317
2318template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2319inline
2322 const key_type& key)
2323{
2324 return iterator(d_impl.find(key));
2325}
2326
2327template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2328bsl::pair<
2332 const key_type& key)
2333{
2334 HashTableLink *first;
2335 HashTableLink *last;
2336 d_impl.findRange(&first, &last, key);
2337 return bsl::pair<iterator, iterator>(iterator(first), iterator(last));
2338}
2339
2340template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2341inline
2344 const_iterator position)
2345{
2346 BSLS_ASSERT(position != this->end());
2347
2348 return iterator(d_impl.remove(position.node()));
2349}
2350
2351template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2352inline
2359
2360template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2363 const key_type& key)
2364{ // As an alternative implementation, the table could return an extracted
2365 // "slice" list from the underlying table, and now need merely:
2366 // iterate each node, destroying the associated value
2367 // reclaim each node (potentially returning to a node-pool)
2368
2369 typedef ::BloombergLP::bslalg::BidirectionalNode<value_type> BNode;
2370
2371 if (HashTableLink *target = d_impl.find(key)) {
2372 target = d_impl.remove(target);
2373 size_type result = 1;
2374 while (target &&
2375 this->key_eq()(key, ListConfiguration::extractKey(
2376 static_cast<BNode *>(target)->value()))) {
2377 target = d_impl.remove(target);
2378 ++result;
2379 }
2380 return result; // RETURN
2381 }
2382
2383 return 0;
2384}
2385
2386template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2389 const_iterator first,
2390 const_iterator last)
2391{
2392#if defined BDE_BUILD_TARGET_SAFE_2
2393 if (first != last) {
2394 iterator it = this->begin();
2395 const iterator end = this->end();
2396 for (; it != first; ++it) {
2397 BSLS_ASSERT(last != it);
2398 BSLS_ASSERT(end != it);
2399 }
2400 for (; it != last; ++it) {
2401 BSLS_ASSERT(end != it);
2402 }
2403 }
2404#endif
2405
2406 while (first != last) {
2407 first = this->erase(first);
2408 }
2409
2410 return iterator(first.node()); // convert from const_iterator
2411}
2412
2413template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2414inline
2417 const value_type& value)
2418{
2419 return iterator(d_impl.insert(value));
2420}
2421
2422template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2423inline
2426 const_iterator hint,
2427 const value_type& value)
2428{
2429 return iterator(d_impl.insert(value, hint.node()));
2430}
2431
2432template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2433template <class INPUT_ITERATOR>
2435 INPUT_ITERATOR first,
2436 INPUT_ITERATOR last)
2437{
2438 difference_type maxInsertions =
2439 ::BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
2440 if (0 < maxInsertions) {
2441 this->reserve(this->size() + maxInsertions);
2442 }
2443 else {
2444 BSLS_ASSERT_SAFE(0 == maxInsertions);
2445 }
2446
2447 while (first != last) {
2448 d_impl.emplace(*first);
2449 ++first;
2450 }
2451}
2452
2453#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2454template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2455inline
2457 std::initializer_list<value_type> values)
2458{
2459 insert(values.begin(), values.end());
2460}
2461#endif
2462
2463template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2464inline
2466 float newLoadFactor)
2467{
2468 d_impl.setMaxLoadFactor(newLoadFactor);
2469}
2470
2471template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2472inline
2474 size_type numBuckets)
2475{
2476 d_impl.rehashForNumBuckets(numBuckets);
2477}
2478
2479template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2480inline
2482 size_type numElements)
2483{
2484 d_impl.reserveForNumElements(numElements);
2485}
2486
2487template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2488inline
2490 unordered_multimap& other)
2492 AllocatorTraits::is_always_equal::value &&
2493 bsl::is_nothrow_swappable<HASH>::value &&
2494 bsl::is_nothrow_swappable<EQUAL>::value)
2495{
2496 d_impl.swap(other.d_impl);
2497}
2498
2499// ACCESSORS
2500template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2501inline
2502ALLOCATOR
2505{
2506 return d_impl.allocator();
2507}
2508
2509template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2516
2517template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2518inline
2525
2526template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2533
2534template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2535inline
2542
2543template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2544inline
2546 const_local_iterator
2548 size_type index) const
2549{
2550 BSLS_ASSERT_SAFE(index < this->bucket_count());
2551
2552 return const_local_iterator(&d_impl.bucketAtIndex(index));
2553}
2554
2555template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2556inline
2557typename
2560 size_type index) const
2561{
2562 BSLS_ASSERT_SAFE(index < this->bucket_count());
2563
2564 return const_local_iterator(0, &d_impl.bucketAtIndex(index));
2565}
2566
2567template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2568inline
2569typename
2572 size_type index) const
2573{
2574 BSLS_ASSERT_SAFE(index < this->bucket_count());
2575
2576 return const_local_iterator(&d_impl.bucketAtIndex(index));
2577}
2578
2579template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2580inline
2582 const_local_iterator
2584 size_type index) const
2585{
2586 BSLS_ASSERT_SAFE(index < this->bucket_count());
2587
2588 return const_local_iterator(0, &d_impl.bucketAtIndex(index));
2589}
2590
2591template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2592inline
2595 const key_type& key) const
2596{
2597 return d_impl.bucketIndexForKey(key);
2598}
2599
2600template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2601inline
2608
2609template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2610inline
2613 size_type index) const
2614{
2615 BSLS_ASSERT_SAFE(index < this->bucket_count());
2616
2617 return d_impl.countElementsInBucket(index);
2618}
2619
2620template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2623 const key_type& key) const
2624{
2625 typedef ::BloombergLP::bslalg::BidirectionalNode<value_type> BNode;
2626
2627 size_type result = 0;
2628 for (HashTableLink *cursor = d_impl.find(key);
2629 cursor;
2630 ++result, cursor = cursor->nextLink())
2631 {
2632 BNode *cursorNode = static_cast<BNode *>(cursor);
2633 if (!this->key_eq()(key,
2634 ListConfiguration::extractKey(cursorNode->value()))) {
2635
2636 break;
2637 }
2638 }
2639 return result;
2640}
2641
2642template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2643inline
2646 const key_type& key) const
2647{
2648 return const_iterator(d_impl.find(key));
2649}
2650
2651
2652template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2653inline
2656{
2657 return 0 == d_impl.size();
2658}
2659
2660template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2661inline
2668
2669template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2670inline
2674{
2675 return AllocatorTraits::max_size(get_allocator());
2676}
2677
2678template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2679inline
2682{
2683 return d_impl.hasher();
2684}
2685
2686template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2687inline
2690{
2691 return d_impl.comparator();
2692}
2693
2694template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2695bsl::pair<typename unordered_multimap<KEY,
2696 VALUE,
2697 HASH,
2698 EQUAL,
2699 ALLOCATOR>::const_iterator,
2700 typename unordered_multimap<KEY,
2701 VALUE,
2702 HASH,
2703 EQUAL,
2704 ALLOCATOR>::const_iterator>
2706 const key_type& key) const
2707{
2708 HashTableLink *first;
2709 HashTableLink *last;
2710 d_impl.findRange(&first, &last, key);
2712 const_iterator(last));
2713}
2714
2715template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2716inline
2719 const
2721{
2722 return d_impl.maxNumBuckets();
2723}
2724
2725template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2726inline
2728 const
2730{
2731 return d_impl.loadFactor();
2732}
2733
2734template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2735inline
2737 const
2739{
2740 return d_impl.maxLoadFactor();
2741}
2742
2743} // close namespace bsl
2744
2745// FREE OPERATORS
2746template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2747inline
2748bool bsl::operator==(
2751{
2752 return lhs.d_impl == rhs.d_impl;
2753}
2754
2755#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2756template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2757inline
2758bool bsl::operator!=(
2761{
2762 return !(lhs == rhs);
2763}
2764#endif
2765
2766// FREE FUNCTIONS
2767template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2768inline
2772{
2773 a.swap(b);
2774}
2775
2776// ============================================================================
2777// TYPE TRAITS
2778// ============================================================================
2779
2780// Type traits for STL *unordered* *associative* containers:
2781//: o An unordered associative container defines STL iterators.
2782//: o An unordered associative container is bitwise movable if both functors
2783//: and the allocator are bitwise movable.
2784//: o An unordered associative container uses 'bslma' allocators if the
2785//: (template parameter) type 'ALLOCATOR' is convertible from
2786//: 'bslma::Allocator*'.
2787
2788
2789
2790namespace bslalg {
2791
2792template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2793struct HasStlIterators<bsl::unordered_multimap<KEY,
2794 VALUE,
2795 HASH,
2796 EQUAL,
2797 ALLOCATOR> >
2799{};
2800
2801} // close namespace bslalg
2802
2803namespace bslma {
2804
2805template <class KEY, class VALUE, class HASH, class EQUAL, class ALLOCATOR>
2806struct UsesBslmaAllocator<bsl::unordered_multimap<KEY,
2807 VALUE,
2808 HASH,
2809 EQUAL,
2810 ALLOCATOR> >
2811: bsl::is_convertible<Allocator*, ALLOCATOR>::type
2812{};
2813
2814} // close namespace bslma
2815
2816namespace bslmf {
2817
2818template <class KEY, class MAPPED, class HASH, class EQUAL, class ALLOCATOR>
2820 bsl::unordered_multimap<KEY, MAPPED, HASH, EQUAL, ALLOCATOR> >
2821 : ::BloombergLP::bslmf::IsBitwiseMoveable<BloombergLP::bslstl::HashTable<
2822 ::BloombergLP::bslstl::
2823 UnorderedMapKeyConfiguration<KEY, bsl::pair<const KEY, MAPPED> >,
2824 HASH,
2825 EQUAL,
2826 ALLOCATOR> >::type
2827{};
2828
2829}
2830
2831
2832#endif // End C++11 code
2833
2834#endif
2835
2836// ----------------------------------------------------------------------------
2837// Copyright 2013 Bloomberg Finance L.P.
2838//
2839// Licensed under the Apache License, Version 2.0 (the "License");
2840// you may not use this file except in compliance with the License.
2841// You may obtain a copy of the License at
2842//
2843// http://www.apache.org/licenses/LICENSE-2.0
2844//
2845// Unless required by applicable law or agreed to in writing, software
2846// distributed under the License is distributed on an "AS IS" BASIS,
2847// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2848// See the License for the specific language governing permissions and
2849// limitations under the License.
2850// ----------------------------- END-OF-FILE ----------------------------------
2851
2852/** @} */
2853/** @} */
2854/** @} */
Definition bslma_bslallocator.h:580
Definition bslstl_pair.h:1210
Definition bslstl_unorderedmultimap.h:707
float max_load_factor() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2736
friend bool operator==(const unordered_multimap< KEY2, VALUE2, HASH2, EQUAL2, ALLOCATOR2 > &, const unordered_multimap< KEY2, VALUE2, HASH2, EQUAL2, ALLOCATOR2 > &)
enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, pair< iterator, iterator > >::type equal_range(const LOOKUP_KEY &key)
Definition bslstl_unorderedmultimap.h:1091
unordered_multimap()
Definition bslstl_unorderedmultimap.h:1974
bool empty() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2654
const value_type & const_reference
Definition bslstl_unorderedmultimap.h:763
EQUAL key_eq() const
Definition bslstl_unorderedmultimap.h:2689
float load_factor() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2727
KEY key_type
Definition bslstl_unorderedmultimap.h:755
ALLOCATOR allocator_type
Definition bslstl_unorderedmultimap.h:760
AllocatorTraits::const_pointer const_pointer
Definition bslstl_unorderedmultimap.h:768
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2275
size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2672
void reserve(size_type numElements)
Definition bslstl_unorderedmultimap.h:2481
HASH hash_function() const
Definition bslstl_unorderedmultimap.h:2681
enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, pair< const_iterator, const_iterator > >::type equal_range(const LOOKUP_KEY &key) const
Definition bslstl_unorderedmultimap.h:1491
::BloombergLP::bslstl::HashTableIterator< value_type, difference_type > iterator
Definition bslstl_unorderedmultimap.h:771
enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, iterator >::type find(const LOOKUP_KEY &key)
Definition bslstl_unorderedmultimap.h:1157
unordered_multimap &operator=(BloombergLP::bslmf::MovableRef< unordered_multimap > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2266
size_type bucket(const key_type &key) const
Definition bslstl_unorderedmultimap.h:2594
value_type & reference
Definition bslstl_unorderedmultimap.h:762
HASH hasher
Definition bslstl_unorderedmultimap.h:758
const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2528
void swap(unordered_multimap &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:1360
const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2537
enable_if< is_convertible< ALT_VALUE_TYPE, value_type >::value, iterator >::type insert(BSLS_COMPILERFEATURES_FORWARD_REF(ALT_VALUE_TYPE) value)
Definition bslstl_unorderedmultimap.h:1197
unordered_multimap & operator=(const unordered_multimap &rhs)
Definition bslstl_unorderedmultimap.h:2192
enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, size_type >::type count(const LOOKUP_KEY &key) const
Definition bslstl_unorderedmultimap.h:1451
::BloombergLP::bslstl::HashTableIterator< const value_type, difference_type > const_iterator
Definition bslstl_unorderedmultimap.h:774
EQUAL key_equal
Definition bslstl_unorderedmultimap.h:759
size_type max_bucket_count() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2718
size_type bucket_count() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2603
iterator insert(const value_type &value)
Definition bslstl_unorderedmultimap.h:2416
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this unordered multimap.
Definition bslstl_unorderedmultimap.h:2663
size_type erase(const key_type &key)
Definition bslstl_unorderedmultimap.h:2362
bool contains(const key_type &key) const
Definition bslstl_unorderedmultimap.h:2312
::BloombergLP::bslstl::HashTableBucketIterator< const value_type, difference_type > const_local_iterator
Definition bslstl_unorderedmultimap.h:780
AllocatorTraits::difference_type difference_type
Definition bslstl_unorderedmultimap.h:766
iterator emplace_hint(const_iterator hint, Args &&... args)
Definition bslstl_unorderedmultimap.h:2254
::BloombergLP::bslstl::HashTableBucketIterator< value_type, difference_type > local_iterator
Definition bslstl_unorderedmultimap.h:777
AllocatorTraits::pointer pointer
Definition bslstl_unorderedmultimap.h:767
bsl::pair< const KEY, VALUE > value_type
Definition bslstl_unorderedmultimap.h:757
AllocatorTraits::size_type size_type
Definition bslstl_unorderedmultimap.h:765
void rehash(size_type numBuckets)
Definition bslstl_unorderedmultimap.h:2473
iterator emplace(Args &&... args)
Definition bslstl_unorderedmultimap.h:2243
size_type bucket_size(size_type index) const
Definition bslstl_unorderedmultimap.h:2612
void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmultimap.h:2304
~unordered_multimap()
Destroy this object.
Definition bslstl_unorderedmultimap.h:2184
VALUE mapped_type
Definition bslstl_unorderedmultimap.h:756
enable_if< is_convertible< ALT_VALUE_TYPE, value_type >::value, iterator >::type insert(const_iterator hint, BSLS_COMPILERFEATURES_FORWARD_REF(ALT_VALUE_TYPE) value)
Definition bslstl_unorderedmultimap.h:1248
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2012
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:634
Definition bdlb_printmethods.h:283
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
deque< VALUE_TYPE, ALLOCATOR >::size_type erase(deque< VALUE_TYPE, ALLOCATOR > &deq, const BDE_OTHER_TYPE &value)
Definition bslstl_deque.h:4126
T::iterator begin(T &container)
Definition bslstl_iterator.h:1495
BSLS_KEYWORD_CONSTEXPR size_t size(const TYPE(&)[DIMENSION]) BSLS_KEYWORD_NOEXCEPT
Return the dimension of the specified array argument.
Definition bslstl_iterator.h:1331
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
bool operator!=(const memory_resource &a, const memory_resource &b)
Definition bdlc_flathashmap.h:1805
Definition balxml_encoderoptions.h:68
Definition bdlbb_blob.h:576
Definition bdldfp_decimal.h:5188
Definition bslma_allocatortraits.h:1061
BloombergLP::bslma::AllocatorTraits_ConstPointerType< ALLOCATOR >::type const_pointer
Definition bslma_allocatortraits.h:1152
BloombergLP::bslma::AllocatorTraits_SizeType< ALLOCATOR >::type size_type
Definition bslma_allocatortraits.h:1165
BloombergLP::bslma::AllocatorTraits_PointerType< ALLOCATOR >::type pointer
Definition bslma_allocatortraits.h:1149
BloombergLP::bslma::AllocatorTraits_DifferenceType< ALLOCATOR >::type difference_type
Definition bslma_allocatortraits.h:1162
Definition bslmf_enableif.h:525
Definition bslstl_equalto.h:311
Definition bslstl_hash.h:498
Definition bslmf_isconvertible.h:867
t_TYPE type
Definition bslmf_typeidentity.h:216
Definition bslalg_hasstliterators.h:99
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_isbitwisemoveable.h:718