BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_multimap.h
Go to the documentation of this file.
1/// @file bslstl_multimap.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_multimap.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_MULTIMAP
9#define INCLUDED_BSLSTL_MULTIMAP
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_multimap bslstl_multimap
15/// @brief Provide an STL-compliant multimap class.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_multimap
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_multimap-purpose"> Purpose</a>
25/// * <a href="#bslstl_multimap-classes"> Classes </a>
26/// * <a href="#bslstl_multimap-description"> Description </a>
27/// * <a href="#bslstl_multimap-requirements-on-key-and-value"> Requirements on KEY and VALUE </a>
28/// * <a href="#bslstl_multimap-memory-allocation"> Memory Allocation </a>
29/// * <a href="#bslstl_multimap-bslma-style-allocators"> bslma-Style Allocators </a>
30/// * <a href="#bslstl_multimap-operations"> Operations </a>
31/// * <a href="#bslstl_multimap-usage"> Usage </a>
32/// * <a href="#bslstl_multimap-example-1-creating-a-phone-book"> Example 1: Creating a Phone Book </a>
33///
34/// # Purpose {#bslstl_multimap-purpose}
35/// Provide an STL-compliant multimap class.
36///
37/// # Classes {#bslstl_multimap-classes}
38///
39/// - bsl::multimap: STL-compatible multimap template
40///
41/// **Canonical header:** bsl_map.h
42///
43/// @see bslstl_map, bslstl_multiset
44///
45/// # Description {#bslstl_multimap-description}
46/// This component defines a single class template,
47/// `bsl::multimap`, implementing the standard container holding an ordered
48/// sequence of key-value pairs (possibly having duplicate keys), and presenting
49/// a mapping from the keys (of a template parameter type, `KEY`) to their
50/// associated values (of another template parameter type, `VALUE`).
51///
52/// An instantiation of `multimap` is an allocator-aware, value-semantic type
53/// whose salient attributes are its size (number of key-value pairs) and the
54/// ordered sequence of key-value pairs the multimap contains. If `multimap` is
55/// instantiated with either a key type or mapped-value type that is not itself
56/// value-semantic, then it will not retain all of its value-semantic qualities.
57/// In particular, if either the key or value type cannot be tested for
58/// equality, then a `multimap` containing that type cannot be tested for
59/// equality. It is even possible to instantiate `multimap` with a key or
60/// mapped-value type that does not have a copy-constructor, in which case the
61/// `multimap` will not be copyable.
62///
63/// A multimap meets the requirements of an associative container with
64/// bidirectional iterators in the C++ standard [23.2.4]. The `multimap`
65/// implemented here adheres to the C++11 standard when compiled with a C++11
66/// compiler, and makes the best approximation when compiled with a C++03
67/// compiler. In particular, for C++03 we emulate move semantics, but limit
68/// forwarding (in `emplace`) to `const` lvalues, and make no effort to emulate
69/// `noexcept` or initializer-lists.
70///
71/// ## Requirements on KEY and VALUE {#bslstl_multimap-requirements-on-key-and-value}
72///
73///
74/// A `multimap` is a fully "Value-Semantic Type" (see @ref bsldoc_glossary ) only
75/// if the supplied `KEY` and `VALUE` template parameters are themselves fully
76/// value-semantic. It is possible to instantiate a `multimap` with `KEY` and
77/// `VALUE` parameter arguments that do not provide a full set of value-semantic
78/// operations, but then some methods of the container may not be instantiable.
79/// The following terminology, adopted from the C++11 standard, is used in the
80/// function documentation of `multimap` to describe a function's requirements
81/// for the `KEY` and `VALUE` template parameters. These terms are also defined
82/// in section [17.6.3.1] of the C++11 standard. Note that, in the context of a
83/// `multimap` instantiation, the requirements apply specifically to the
84/// multimap's entry type, `value_type`, which is an alias for 'pair<const KEY,
85/// VALUE>'.
86///
87/// @code
88/// Legend
89/// ------
90/// 'X' - denotes an allocator-aware container type (e.g., 'multimap')
91/// 'T' - 'value_type' associated with 'X'
92/// 'A' - type of the allocator used by 'X'
93/// 'm' - lvalue of type 'A' (allocator)
94/// 'p', - address ('T *') of uninitialized storage for a 'T' within an 'X'
95/// 'rv' - rvalue of type (non-'const') 'T'
96/// 'v' - rvalue or lvalue of type (possibly 'const') 'T'
97/// 'args' - 0 or more arguments
98/// @endcode
99///
100/// The following terms are used to more precisely specify the requirements on
101/// template parameter types in function-level documentation.
102///
103/// *default-insertable*: `T` has a default constructor. More precisely, `T`
104/// is `default-insertable` into `X` means that the following expression is
105/// well-formed:
106/// `allocator_traits<A>::construct(m, p)`
107///
108/// *move-insertable*: `T` provides a constructor that takes an rvalue of type
109/// (non-`const`) `T`. More precisely, `T` is `move-insertable` into `X`
110/// means that the following expression is well-formed:
111/// `allocator_traits<A>::construct(m, p, rv)`
112///
113/// *copy-insertable*: `T` provides a constructor that takes an lvalue or
114/// rvalue of type (possibly `const`) `T`. More precisely, `T` is
115/// `copy-insertable` into `X` means that the following expression is
116/// well-formed:
117/// `allocator_traits<A>::construct(m, p, v)`
118///
119/// *move-assignable*: `T` provides an assignment operator that takes an rvalue
120/// of type (non-`const`) `T`.
121///
122/// *copy-assignable*: `T` provides an assignment operator that takes an lvalue
123/// or rvalue of type (possibly `const`) `T`.
124///
125/// *emplace-constructible*: `T` is `emplace-constructible` into `X` from
126/// `args` means that the following expression is well-formed:
127///
128/// `allocator_traits<A>::construct(m, p, args)`
129///
130/// *erasable*: `T` provides a destructor. More precisely, `T` is `erasable`
131/// from `X` means that the following expression is well-formed:
132/// `allocator_traits<A>::destroy(m, p)`
133///
134/// *equality-comparable*: The type provides an equality-comparison operator
135/// that defines an equivalence relationship and is both reflexive and
136/// transitive.
137///
138/// ## Memory Allocation {#bslstl_multimap-memory-allocation}
139///
140///
141/// The type supplied as a multimap's `ALLOCATOR` template parameter determines
142/// how that multimap will allocate memory. The `multimap` template supports
143/// allocators meeting the requirements of the C++11 standard [17.6.3.5]. In
144/// addition, it supports scoped-allocators derived from the `bslma::Allocator`
145/// memory allocation protocol. Clients intending to use `bslma`-style
146/// allocators should use the template's default `ALLOCATOR` type. The default
147/// type for the `ALLOCATOR` template parameter, `bsl::allocator`, provides a
148/// C++11 standard-compatible adapter for a `bslma::Allocator` object.
149///
150/// ### bslma-Style Allocators {#bslstl_multimap-bslma-style-allocators}
151///
152///
153/// If the (template parameter) type `ALLOCATOR` of a `multimap` instantiation
154/// is `bsl::allocator`, then objects of that multimap type will conform to the
155/// standard behavior of a `bslma`-allocator-enabled type. Such a multimap
156/// accepts an optional `bslma::Allocator` argument at construction. If the
157/// address of a `bslma::Allocator` object is explicitly supplied at
158/// construction, it is used to supply memory for the multimap throughout its
159/// lifetime; otherwise, the multimap will use the default allocator installed
160/// at the time of the multimap's construction (see @ref bslma_default ). In
161/// addition to directly allocating memory from the indicated
162/// `bslma::Allocator`, a multimap supplies that allocator's address to the
163/// constructors of contained objects of the (template parameter) types `KEY`
164/// and `VALUE`, if respectively, the types define the
165/// `bslma::UsesBslmaAllocator` trait.
166///
167/// ## Operations {#bslstl_multimap-operations}
168///
169///
170/// This section describes the run-time complexity of operations on instances
171/// of `multimap`:
172/// @code
173/// Legend
174/// ------
175/// 'K' - (template parameter) type 'KEY' of the 'multimap'
176/// 'V' - (template parameter) type 'VALUE' of the 'multimap'
177/// 'a', 'b' - two distinct objects of type 'multimap<K, V>'
178/// 'rv' - modifiable rvalue of type 'multimap<K, V>'
179/// 'n', 'm' - number of elements in 'a' and 'b', respectively
180/// 'value_type' - 'pair<const K, V>'
181/// 'c' - comparator providing an ordering for objects of type 'K'
182/// 'al' - STL-style memory allocator
183/// 'i1', 'i2' - two iterators defining a sequence of 'value_type' objects
184/// 'k' - object of type 'K'
185/// 'v' - object of type 'V'
186/// 'vt' - object of type 'value_type'
187/// 'rvt' - modifiable rvalue of type 'value_type'
188/// 'p1', 'p2' - two 'const_iterator's belonging to 'a'
189/// distance(i1,i2) - number of elements in the range '[i1 .. i2)'
190///
191/// +----------------------------------------------------+--------------------+
192/// | Operation | Complexity |
193/// +====================================================+====================+
194/// | multimap<K, V> a; (default construction) | O[1] |
195/// | multimap<K, V> a(al); | |
196/// | multimap<K, V> a(c, al); | |
197/// +----------------------------------------------------+--------------------+
198/// | multimap<K, V> a(rv); (move construction) | O[1] if 'a' and |
199/// | multimap<K, V> a(rv, al); | 'rv' use the same |
200/// | | allocator, |
201/// | | O[n] otherwise |
202/// +----------------------------------------------------+--------------------+
203/// | multimap<K, V> a(b); (copy construction) | O[n] |
204/// | multimap<K, V> a(b, al); | |
205/// +----------------------------------------------------+--------------------+
206/// | multimap<K, V> a(i1, i2); | O[N] if [i1, i2) |
207/// | multimap<K, V> a(i1, i2, al); | is sorted with |
208/// | multimap<K, V> a(i1, i2, c, al); | 'a.value_comp()', |
209/// | | O[N * log(N)] |
210/// | | otherwise, where N |
211/// | | is distance(i1,i2) |
212/// +----------------------------------------------------+--------------------+
213/// | a.~multimap<K, V>(); (destruction) | O[n] |
214/// +----------------------------------------------------+--------------------+
215/// | a = rv; (move assignment) | O[1] if 'a' and |
216/// | | 'rv' use the same |
217/// | | allocator, |
218/// | | O[n] otherwise |
219/// +----------------------------------------------------+--------------------+
220/// | a = b; (copy assignment) | O[n] |
221/// +----------------------------------------------------+--------------------+
222/// | a.begin(), a.end(), a.cbegin(), a.cend(), | O[1] |
223/// | a.rbegin(), a.rend(), a.crbegin(), a.crend() | |
224/// +----------------------------------------------------+--------------------+
225/// | a == b, a != b | O[n] |
226/// +----------------------------------------------------+--------------------+
227/// | a < b, a <= b, a > b, a >= b | O[n] |
228/// +----------------------------------------------------+--------------------+
229/// | a.swap(b), swap(a, b) | O[1] if 'a' and |
230/// | | 'b' use the same |
231/// | | allocator, |
232/// | | O[n + m] otherwise |
233/// +----------------------------------------------------+--------------------+
234/// | a.size() | O[1] |
235/// +----------------------------------------------------+--------------------+
236/// | a.max_size() | O[1] |
237/// +----------------------------------------------------+--------------------+
238/// | a.empty() | O[1] |
239/// +----------------------------------------------------+--------------------+
240/// | get_allocator() | O[1] |
241/// +----------------------------------------------------+--------------------+
242/// | a.insert(vt) | O[log(n)] |
243/// | a.insert(rvt) | |
244/// | a.emplace(Args&&...) | |
245/// +----------------------------------------------------+--------------------+
246/// | a.insert(p1, vt) | amortized constant |
247/// | a.insert(p1, rvt) | if the value is |
248/// | a.emplace(p1, Args&&...) | inserted right |
249/// | | before p1, |
250/// | | O[log(n)] |
251/// | | otherwise |
252/// +----------------------------------------------------+--------------------+
253/// | a.insert(i1, i2) | O[log(N) * |
254/// | | distance(i1,i2)] |
255/// | | |
256/// | | where N is |
257/// | | n + distance(i1,i2)|
258/// +----------------------------------------------------+--------------------+
259/// | a.erase(p1) | amortized constant |
260/// +----------------------------------------------------+--------------------+
261/// | a.erase(k) | O[log(n) + |
262/// | | a.count(k)] |
263/// +----------------------------------------------------+--------------------+
264/// | a.erase(p1, p2) | O[log(n) + |
265/// | | distance(p1, p2)] |
266/// +----------------------------------------------------+--------------------+
267/// | a.erase(p1, p2) | O[log(n) + |
268/// | | distance(p1, p2)] |
269/// +----------------------------------------------------+--------------------+
270/// | a.clear() | O[n] |
271/// +----------------------------------------------------+--------------------+
272/// | a.contains(k) | O[log(n)] |
273/// +----------------------------------------------------+--------------------+
274/// | a.key_comp() | O[1] |
275/// +----------------------------------------------------+--------------------+
276/// | a.value_comp() | O[1] |
277/// +----------------------------------------------------+--------------------+
278/// | a.find(k) | O[log(n)] |
279/// +----------------------------------------------------+--------------------+
280/// | a.count(k) | O[log(n) + |
281/// | | a.count(k)] |
282/// +----------------------------------------------------+--------------------+
283/// | a.lower_bound(k) | O[log(n)] |
284/// +----------------------------------------------------+--------------------+
285/// | a.upper_bound(k) | O[log(n)] |
286/// +----------------------------------------------------+--------------------+
287/// | a.equal_range(k) | O[log(n)] |
288/// +----------------------------------------------------+--------------------+
289/// @endcode
290///
291/// ## Usage {#bslstl_multimap-usage}
292///
293///
294/// In this section we show intended use of this component.
295///
296/// ### Example 1: Creating a Phone Book {#bslstl_multimap-example-1-creating-a-phone-book}
297///
298///
299/// In this example, we will define a class `PhoneBook`, that provides a mapping
300/// of names to phone numbers. The `PhoneBook` class will be implemented using
301/// a `bsl::multimap`, and will supply manipulators, allowing a client to add or
302/// remove entries from the phone book, as well as accessors, allowing clients
303/// to efficiently lookup entries by name, and to iterate over the entries in
304/// the phone book in sorted order.
305///
306/// Note that this example uses a type `string` that is based on the standard
307/// type `string` (see @ref bslstl_string ). For the sake of brevity, the
308/// implementation of `string` is not explored here.
309///
310/// First, we define an alias for a pair of `string` objects that we will use to
311/// represent names in the phone book:
312/// @code
313/// typedef bsl::pair<string, string> FirstAndLastName;
314/// // This 'typedef' provides an alias for a pair of 'string' objects,
315/// // whose 'first' and 'second' elements refer to the first and last
316/// // names of a person, respectively.
317/// @endcode
318/// Then, we define a comparison functor for `FirstAndLastName` objects (note
319/// that this comparator is required because we intend for the last name to
320/// take precedence over the first name in the ordering of entries maintained
321/// by the phone book, which differs from the behavior supplied by `operator<`
322/// for `bsl::pair`):
323/// @code
324/// struct FirstAndLastNameLess {
325/// // This 'struct' defines an ordering on 'FirstAndLastName' values,
326/// // allowing them to be included in sorted containers such as
327/// // 'bsl::multimap'. Note that last name (the 'second' member of a
328/// // 'FirstAndLastName' value) takes precedence over first name in the
329/// // ordering defined by this functor.
330///
331/// bool operator()(const FirstAndLastName& lhs,
332/// const FirstAndLastName& rhs) const
333/// // Return 'true' if the value of the specified 'lhs' is less than
334/// // (ordered before) the value of the specified 'rhs', and 'false'
335/// // otherwise. The 'lhs' value is considered less than the 'rhs'
336/// // value if the second value in the 'lhs' pair (the last name) is
337/// // less than the second value in the 'rhs' pair or, if the second
338/// // values are equal, if the first value in the 'lhs' pair (the
339/// // first name) is less than the first value in the 'rhs' pair.
340/// {
341/// int cmp = std::strcmp(lhs.second.c_str(), rhs.second.c_str());
342/// if (0 == cmp) {
343/// cmp = std::strcmp(lhs.first.c_str(), rhs.first.c_str());
344/// }
345/// return cmp < 0;
346/// }
347/// };
348/// @endcode
349/// Next, we define the public interface for `PhoneBook`:
350/// @code
351/// class PhoneBook {
352/// // This class provides a mapping of a person's name to their phone
353/// // number. Names within a 'PhoneBook' are represented using a using
354/// // 'FirstAndLastName' object, and phone numbers are represented using a
355/// // 'bsls::Types::Uint64' value.
356/// @endcode
357/// Here, we create a type alias, `NameToNumberMap`, for a `bsl::multimap` that
358/// will serve as the data member for a `PhoneBook`. A `NameToNumberMap` has
359/// keys of type `FirstAndLastName`, mapped-values of type
360/// `bsls::Types::Uint64`, and a comparator of type `FirstAndLastNameLess`. We
361/// use the default `ALLOCATOR` template parameter as we intend to use
362/// `PhoneBook` with `bslma` style allocators:
363/// @code
364/// // PRIVATE TYPES
365/// typedef bsl::multimap<FirstAndLastName,
366/// bsls::Types::Uint64,
367/// FirstAndLastNameLess> NameToNumberMap;
368/// // This 'typedef' is an alias for a mapping between names and phone
369/// // numbers.
370///
371/// // DATA
372/// NameToNumberMap d_nameToNumber; // mapping of names to phone numbers
373///
374/// // FRIENDS
375/// friend bool operator==(const PhoneBook& lhs, const PhoneBook& rhs);
376///
377/// public:
378/// // PUBLIC TYPES
379/// typedef bsls::Types::Uint64 PhoneNumber;
380/// // This 'typedef' provides an alias for the type of an unsigned
381/// // integers used to represent phone-numbers in a 'PhoneBook'.
382///
383/// typedef NameToNumberMap::const_iterator ConstIterator;
384/// // This 'typedef' provides an alias for the type of an iterator
385/// // providing non-modifiable access to the entries in a 'PhoneBook'.
386///
387/// // CREATORS
388/// PhoneBook(bslma::Allocator *basicAllocator = 0);
389/// // Create an empty 'PhoneBook' object. Optionally specify a
390/// // 'basicAllocator' used to supply memory. If 'basicAllocator' is
391/// // 0, the currently installed default allocator is used.
392///
393/// PhoneBook(const PhoneBook& original,
394/// bslma::Allocator *basicAllocator = 0);
395/// // Create a 'PhoneBook' object having the same value as the
396/// // specified 'original' object. Optionally specify a
397/// // 'basicAllocator' used to supply memory. If 'basicAllocator' is
398/// // 0, the currently installed default allocator is used.
399///
400/// //! ~PhoneBook() = default;
401/// // Destroy this object.
402///
403/// // MANIPULATORS
404/// PhoneBook& operator=(const PhoneBook& rhs);
405/// // Assign to this object the value of the specified 'rhs' object,
406/// // and return a reference providing modifiable access to this
407/// // object.
408///
409/// void addEntry(const FirstAndLastName& name, PhoneNumber number);
410/// // Add an entry to this phone book having the specified 'name' and
411/// // 'number'. The behavior is undefined unless 'name.first' and
412/// // 'name.end' are non-empty strings.
413///
414/// int removeEntry(const FirstAndLastName& name, PhoneNumber number);
415/// // Remove the entries from this phone book having the specified
416/// // 'name' and 'number', if they exists, and return the number of
417/// // removed entries; otherwise, return 0 with no other effects.
418///
419/// // ACCESSORS
420/// bsl::pair<ConstIterator, ConstIterator> lookupByName(
421/// const FirstAndLastName& name) const;
422/// // Return a pair of iterators to the ordered sequence of entries
423/// // held in this phone book having the specified 'name', where the
424/// // first iterator is position at the start of the sequence, and the
425/// // second is positioned one past the last entry in the sequence.
426/// // If 'name' does not exist in this phone book, then the two
427/// // returned iterators will have the same value.
428///
429/// ConstIterator begin() const;
430/// // Return an iterator providing non-modifiable access to the first
431/// // entry in the ordered sequence of entries held in this phone
432/// // book, or the past-the-end iterator if this phone book is empty.
433///
434/// ConstIterator end() const;
435/// // Return an iterator providing non-modifiable access to the
436/// // past-the-end entry in the ordered sequence of entries maintained
437/// // by this phone book.
438///
439/// size_t numEntries() const;
440/// // Return the number of entries contained in this phone book.
441/// };
442/// @endcode
443/// Then, we declare the free operators for `PhoneBook`:
444/// @code
445/// inline
446/// bool operator==(const PhoneBook& lhs, const PhoneBook& rhs);
447/// // Return 'true' if the specified 'lhs' and 'rhs' objects have the same
448/// // value, and 'false' otherwise. Two 'PhoneBook' objects have the
449/// // same value if they have the same number of entries, and each
450/// // corresponding entry, in their respective ordered sequence of
451/// // entries, is the same.
452///
453/// inline
454/// bool operator!=(const PhoneBook& lhs, const PhoneBook& rhs);
455/// // Return 'true' if the specified 'lhs' and 'rhs' objects do not have
456/// // the same value, and 'false' otherwise. Two 'PhoneBook' objects do
457/// // not have the same value if they either differ in their number of
458/// // contained entries, or if any of the corresponding entries, in their
459/// // respective ordered sequences of entries, is not the same.
460/// @endcode
461/// Now, we define the implementations methods of the `PhoneBook` class:
462/// @code
463/// // CREATORS
464/// inline
465/// PhoneBook::PhoneBook(bslma::Allocator *basicAllocator)
466/// : d_nameToNumber(FirstAndLastNameLess(), basicAllocator)
467/// {
468/// }
469/// @endcode
470/// Notice that, on construction, we pass the contained `bsl::multimap`
471/// (`d_nameToNumber`), a default constructed `FirstAndLastNameLess` object that
472/// it will use to perform comparisons, and the allocator supplied to
473/// `PhoneBook` at construction'.
474/// @code
475/// inline
476/// PhoneBook::PhoneBook(const PhoneBook& original,
477/// bslma::Allocator *basicAllocator)
478/// : d_nameToNumber(original.d_nameToNumber, basicAllocator)
479/// {
480/// }
481///
482/// // MANIPULATORS
483/// inline
484/// PhoneBook& PhoneBook::operator=(const PhoneBook& rhs)
485/// {
486/// d_nameToNumber = rhs.d_nameToNumber;
487/// return *this;
488/// }
489///
490/// inline
491/// void PhoneBook::addEntry(const FirstAndLastName& name, PhoneNumber number)
492/// {
493/// BSLS_ASSERT(!name.first.empty());
494/// BSLS_ASSERT(!name.second.empty());
495///
496/// d_nameToNumber.insert(NameToNumberMap::value_type(name, number));
497/// }
498///
499/// inline
500/// int PhoneBook::removeEntry(const FirstAndLastName& name,
501/// PhoneNumber number)
502/// {
503/// bsl::pair<NameToNumberMap::iterator, NameToNumberMap::iterator> range =
504/// d_nameToNumber.equal_range(name);
505///
506/// NameToNumberMap::iterator it = range.first;
507///
508/// int numRemovedEntries = 0;
509///
510/// while (it != range.second) {
511/// if (it->second == number) {
512/// it = d_nameToNumber.erase(it);
513/// ++numRemovedEntries;
514/// }
515/// else {
516/// ++it;
517/// }
518/// }
519///
520/// return numRemovedEntries;
521/// }
522///
523/// // ACCESSORS
524/// inline
525/// bsl::pair<PhoneBook::ConstIterator, PhoneBook::ConstIterator>
526/// PhoneBook::lookupByName(const FirstAndLastName& name) const
527/// {
528/// return d_nameToNumber.equal_range(name);
529/// }
530///
531/// inline
532/// PhoneBook::ConstIterator PhoneBook::begin() const
533/// {
534/// return d_nameToNumber.begin();
535/// }
536///
537/// inline
538/// PhoneBook::ConstIterator PhoneBook::end() const
539/// {
540/// return d_nameToNumber.end();
541/// }
542///
543/// inline
544/// size_t PhoneBook::numEntries() const
545/// {
546/// return d_nameToNumber.size();
547/// }
548/// @endcode
549/// Finally, we implement the free operators for `PhoneBook`:
550/// @code
551/// inline
552/// bool operator==(const PhoneBook& lhs, const PhoneBook& rhs)
553/// {
554/// return lhs.d_nameToNumber == rhs.d_nameToNumber;
555/// }
556///
557/// inline
558/// bool operator!=(const PhoneBook& lhs, const PhoneBook& rhs)
559/// {
560/// return !(lhs == rhs);
561/// }
562/// @endcode
563/// @}
564/** @} */
565/** @} */
566
567/** @addtogroup bsl
568 * @{
569 */
570/** @addtogroup bslstl
571 * @{
572 */
573/** @addtogroup bslstl_multimap
574 * @{
575 */
576
577#include <bslscm_version.h>
578
579#include <bslstl_algorithm.h>
580#include <bslstl_iteratorutil.h>
581#include <bslstl_mapcomparator.h>
582#include <bslstl_pair.h>
583#include <bslstl_stdexceptutil.h>
584#include <bslstl_treeiterator.h>
585#include <bslstl_treenode.h>
586#include <bslstl_treenodepool.h>
587
588#include <bslalg_rangecompare.h>
589#include <bslalg_rbtreeanchor.h>
590#include <bslalg_rbtreenode.h>
591#include <bslalg_rbtreeutil.h>
592#include <bslalg_swaputil.h>
595
596#include <bslma_isstdallocator.h>
597#include <bslma_bslallocator.h>
599
600#include <bslmf_enableif.h>
601#include <bslmf_isconvertible.h>
603#include <bslmf_movableref.h>
604#include <bslmf_typeidentity.h>
605#include <bslmf_util.h> // 'forward(V)'
606
607#include <bsls_assert.h>
609#include <bsls_keyword.h>
610#include <bsls_performancehint.h>
611#include <bsls_platform.h>
612#include <bsls_util.h> // 'forward<T>(V)'
613
614#include <functional>
615
616#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
617# include <initializer_list>
618#endif
619
620#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
621#include <bsls_nativestd.h>
622#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
623
624#ifdef BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
625#include <type_traits> // 'std::is_constructible'
626 #ifndef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
627 #error Rvalue references curiously absent despite native 'type_traits'.
628 #endif
629#endif
630
631#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
632// Include version that can be compiled with C++03
633// Generated on Thu Oct 21 10:11:37 2021
634// Command line: sim_cpp11_features.pl bslstl_multimap.h
635# define COMPILING_BSLSTL_MULTIMAP_H
636# include <bslstl_multimap_cpp03.h>
637# undef COMPILING_BSLSTL_MULTIMAP_H
638#else
639
640namespace bsl {
641
642 // ==============
643 // class multimap
644 // ==============
645
646/// This class template implements a value-semantic container type holding
647/// an ordered sequence of key-value pairs having possibly duplicate keys
648/// that provide a mapping from keys (of the template parameter type, `KEY`)
649/// to their associated values (of another template parameter type,
650/// `VALUE`).
651///
652/// This class:
653/// * supports a complete set of *value-semantic* operations
654/// - except for BDEX serialization
655/// * is *exception-neutral*
656/// * is *alias-safe*
657/// * is `const` *thread-safe*
658/// For terminology see @ref bsldoc_glossary .
659///
660/// See @ref bslstl_multimap
661template <class KEY,
662 class VALUE,
663 class COMPARATOR = std::less<KEY>,
664 class ALLOCATOR = allocator<pair<const KEY, VALUE> > >
665class multimap {
666
667 // PRIVATE TYPES
668
669 /// This typedef is an alias for the type of key-value pair objects
670 /// maintained by this multimap.
672
673 /// This typedef is an alias for the comparator used internally by this
674 /// multimap.
675 typedef BloombergLP::bslstl::MapComparator<KEY, VALUE, COMPARATOR>
676 Comparator;
677
678 /// This typedef is an alias for the type of nodes held by the tree (of
679 /// nodes) used to implement this multimap.
680 typedef BloombergLP::bslstl::TreeNode<ValueType> Node;
681
682 /// This typedef is an alias for the factory type used to create and
683 /// destroy `Node` objects.
684 typedef BloombergLP::bslstl::TreeNodePool<ValueType, ALLOCATOR>
685 NodeFactory;
686
687 /// This typedef is an alias for the allocator traits type associated
688 /// with this container.
690
691 /// This typedef is a convenient alias for the utility associated with
692 /// movable references.
693 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
694
695 /// This class is a wrapper around the comparator and allocator data
696 /// members. It takes advantage of the empty-base optimization (EBO) so
697 /// that if the comparator is stateless, it takes up no space.
698 ///
699 /// TBD: This class should eventually be replaced by the use of a
700 /// general EBO-enabled component that provides a `pair`-like interface
701 /// or a `tuple`.
702 ///
703 /// See @ref bslstl_multimap
704 class DataWrapper : public Comparator {
705
706 // DATA
707 NodeFactory d_pool; // pool of 'Node' objects
708
709 private:
710 // NOT IMPLEMENTED
711 DataWrapper(const DataWrapper&);
712 DataWrapper& operator=(const DataWrapper&);
713
714 public:
715 // CREATORS
716
717 /// Create a data wrapper using a copy of the specified `comparator`
718 /// to order key-value pairs and a copy of the specified
719 /// `basicAllocator` to supply memory.
720 DataWrapper(const COMPARATOR& comparator,
721 const ALLOCATOR& basicAllocator);
722
723 /// Create a data wrapper initialized to the contents of the `pool`
724 /// associated with the specified `original` data wrapper. The
725 /// comparator and allocator associated with `original` are
726 /// propagated to the new data wrapper. `original` is left in a
727 /// valid but unspecified state.
728 DataWrapper(
729 BloombergLP::bslmf::MovableRef<DataWrapper> original);// IMPLICIT
730
731 // MANIPULATORS
732
733 /// Return a reference providing modifiable access to the node
734 /// factory associated with this data wrapper.
735 NodeFactory& nodeFactory();
736
737 // ACCESSORS
738
739 /// Return a reference providing non-modifiable access to the node
740 /// factory associated with this data wrapper.
741 const NodeFactory& nodeFactory() const;
742 };
743
744 // DATA
745 DataWrapper d_compAndAlloc;
746 // comparator and pool of 'Node'
747 // objects
748
749 BloombergLP::bslalg::RbTreeAnchor d_tree; // balanced tree of 'Node'
750 // objects
751
752 public:
753 // PUBLIC TYPES
754 typedef KEY key_type;
755 typedef VALUE mapped_type;
757 typedef COMPARATOR key_compare;
758 typedef ALLOCATOR allocator_type;
761
766
767 typedef BloombergLP::bslstl::TreeIterator<value_type,
768 Node,
770
771 typedef BloombergLP::bslstl::TreeIterator<const value_type,
772 Node,
774
775 typedef bsl::reverse_iterator<iterator> reverse_iterator;
776 typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;
777
778 /// This nested class defines a mechanism for comparing two objects of
779 /// `value_type` by adapting an object of (template parameter) type
780 /// `COMPARATOR`, which compares two objects of (template parameter)
781 /// type `KEY` . Note that this class exactly matches its definition in
782 /// the C++11 standard [23.4.4.1]; otherwise, we would have implemented
783 /// it as a separate component-local class.
784 ///
785 /// See @ref bslstl_multimap
787
788 // FRIENDS
789 friend class multimap;
790
791 protected:
792 // PROTECTED DATA
793 COMPARATOR comp; // we would not have elected to make this data
794 // member 'protected'
795
796 // PROTECTED CREATORS
797
798 /// Create a @ref value_compare object that uses the specified
799 /// `comparator`.
800 value_compare(COMPARATOR comparator); // IMPLICIT
801
802 public:
803 // PUBLIC TYPES
804
805 /// This `typedef` is an alias for the result type of a call to the
806 /// overload of `operator()` (the comparison function) provided by a
807 /// `multimap::value_compare` object.
808 typedef bool result_type;
809
810 /// This `typedef` is an alias for the type of the first parameter
811 /// of the overload of `operator()` (the comparison function)
812 /// provided by a `multimap::value_compare` object.
814
815 /// This `typedef` is an alias for the type of the second parameter
816 /// of the overload of `operator()` (the comparison function)
817 /// provided by a `multimap::value_compare` object.
819
820 // CREATORS
821 value_compare(const value_compare& original) = default;
822 // Create a @ref value_compare object having the same value as the
823 // specified 'original' object.
824
825 ~value_compare() = default;
826 // Destroy this object.
827
828 // MANIPULATORS
829 value_compare& operator=(const value_compare& rhs) = default;
830 // Assign to this object the value of the specified 'rhs' object,
831 // and return a reference providing modifiable access to this
832 // object.
833
834 // ACCESSORS
835
836 /// Return `true` if the specified `x` object is ordered before the
837 /// specified `y` object, as determined by the comparator supplied
838 /// at construction, and `false` otherwise.
839 bool operator()(const value_type& x, const value_type& y) const;
840 };
841
842 private:
843 // PRIVATE CLASS METHODS
844
845 /// Return an address providing modifiable access to the specified
846 /// `node`. The behavior is undefined unless `node` is the address of a
847 /// `Node` object.
848 static Node *toNode(BloombergLP::bslalg::RbTreeNode *node);
849
850 /// Return an address providing non-modifiable access to the specified
851 /// `node`. The behavior is undefined unless `node` is the address of a
852 /// `Node` object.
853 static const Node *toNode(const BloombergLP::bslalg::RbTreeNode *node);
854
855 // PRIVATE MANIPULATORS
856
857 /// Return a reference providing modifiable access to the comparator for
858 /// this multimap.
859 Comparator& comparator();
860
861 /// Return a reference providing modifiable access to the node allocator
862 /// for this multimap.
863 NodeFactory& nodeFactory();
864
865 /// Efficiently exchange the value, comparator, and allocator of this
866 /// object with the value, comparator, and allocator of the specified
867 /// `other` object. This method provides the no-throw exception-safety
868 /// guarantee, *unless* swapping the (user-supplied) comparator or
869 /// allocator objects can throw.
870 void quickSwapExchangeAllocators(multimap& other);
871
872 /// Efficiently exchange the value and comparator of this object with
873 /// the value and comparator of the specified `other` object. This
874 /// method provides the no-throw exception-safety guarantee, *unless*
875 /// swapping the (user-supplied) comparator objects can throw. The
876 /// behavior is undefined unless this object was created with the same
877 /// allocator as `other`.
878 void quickSwapRetainAllocators(multimap& other);
879
880 // PRIVATE ACCESSORS
881
882 /// Return a reference providing non-modifiable access to the comparator
883 /// for this multimap.
884 const Comparator& comparator() const;
885
886 /// Return a reference providing non-modifiable access to the node
887 /// allocator for this multimap.
888 const NodeFactory& nodeFactory() const;
889
890 public:
891 // CREATORS
892
893 multimap();
894 /// Create an empty multimap. Optionally specify a `comparator` used to
895 /// order key-value pairs contained in this object. If `comparator` is
896 /// not supplied, a default-constructed object of the (template
897 /// parameter) type `COMPARATOR` is used. Optionally specify a
898 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
899 /// supplied, a default-constructed object of the (template parameter)
900 /// type `ALLOCATOR` is used. If the type `ALLOCATOR` is
901 /// `bsl::allocator` (the default), then `basicAllocator`, if supplied,
902 /// shall be convertible to `bslma::Allocator *`. If the type
903 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
904 /// supplied, the currently installed default allocator is used.
905 explicit multimap(const COMPARATOR& comparator,
906 const ALLOCATOR& basicAllocator = ALLOCATOR())
907 : d_compAndAlloc(comparator, basicAllocator)
908 , d_tree()
909 {
910 // The implementation is placed here in the class definition to work
911 // around an AIX compiler bug, where the constructor can fail to
912 // compile because it is unable to find the definition of the default
913 // argument. This occurs when a parameterized class wraps around the
914 // container and the comparator is defined after the new class.
915 }
916
917 /// Create an empty multimap that uses the specified `basicAllocator` to
918 /// supply memory. Use a default-constructed object of the (template
919 /// parameter) type `COMPARATOR` to order the key-value pairs contained
920 /// in this multimap. Note that a `bslma::Allocator *` can be supplied
921 /// for `basicAllocator` if the (template parameter) `ALLOCATOR` is
922 /// `bsl::allocator` (the default).
923 explicit multimap(const ALLOCATOR& basicAllocator);
924
925 /// Create a multimap having the same value as the specified `original`
926 /// object. Use a copy of `original.key_comp()` to order the key-value
927 /// pairs contained in this multimap. Use the allocator returned by
928 /// 'bsl::allocator_traits<ALLOCATOR>::
929 /// select_on_container_copy_construction(original.get_allocator())' to
930 /// allocate memory. This method requires that the (template parameter)
931 /// types `KEY` and `VALUE` both be `copy-insertable` into this multimap
932 /// (see {Requirements on `KEY` and `VALUE`}).
933 multimap(const multimap& original);
934
935 /// Create a multimap having the same value as the specified `original`
936 /// object by moving (in constant time) the contents of `original` to
937 /// the new multimap. Use a copy of `original.key_comp()` to order the
938 /// key-value pairs contained in this multimap. The allocator
939 /// associated with `original` is propagated for use in the
940 /// newly-created multimap. `original` is left in a valid but
941 /// unspecified state.
942 multimap(BloombergLP::bslmf::MovableRef<multimap> original); // IMPLICIT
943
944 /// Create a multimap having the same value as the specified `original`
945 /// object that uses the specified `basicAllocator` to supply memory.
946 /// Use a copy of `original.key_comp()` to order the key-value pairs
947 /// contained in this multimap. This method requires that the (template
948 /// parameter) types `KEY` and `VALUE` both be `copy-insertable` into
949 /// this multimap (see {Requirements on `KEY` and `VALUE`}). Note that
950 /// a `bslma::Allocator *` can be supplied for `basicAllocator` if the
951 /// (template parameter) `ALLOCATOR` is `bsl::allocator` (the default).
952 multimap(const multimap& original,
953 const typename type_identity<ALLOCATOR>::type& basicAllocator);
954
955 /// Create a multimap having the same value as the specified `original`
956 /// object that uses the specified `basicAllocator` to supply memory.
957 /// The contents of `original` are moved (in constant time) to the new
958 /// multimap if `basicAllocator == original.get_allocator()`, and are
959 /// move-inserted (in linear time) using `basicAllocator` otherwise.
960 /// `original` is left in a valid but unspecified state. Use a copy of
961 /// `original.key_comp()` to order the key-value pairs contained in this
962 /// multimap. This method requires that the (template parameter) types
963 /// `KEY` and `VALUE` both be `move-insertable` into this multimap (see
964 /// {Requirements on `KEY` and `VALUE`}). Note that a 'bslma::Allocator
965 /// *` can be supplied for `basicAllocator' if the (template parameter)
966 /// `ALLOCATOR` is `bsl::allocator` (the default).
967 multimap(BloombergLP::bslmf::MovableRef<multimap> original,
968 const typename type_identity<ALLOCATOR>::type& basicAllocator);
969
970 /// Create a multimap, and insert each `value_type` object in the
971 /// sequence starting at the specified `first` element, and ending
972 /// immediately before the specified `last` element. Optionally specify
973 /// a `comparator` used to order key-value pairs contained in this
974 /// object. If `comparator` is not supplied, a default-constructed
975 /// object of the (template parameter) type `COMPARATOR` is used.
976 /// Optionally specify a `basicAllocator` used to supply memory. If
977 /// `basicAllocator` is not supplied, a default-constructed object of
978 /// the (template parameter) type `ALLOCATOR` is used. If the type
979 /// `ALLOCATOR` is `bsl::allocator` (the default), then
980 /// `basicAllocator`, if supplied, shall be convertible to
981 /// `bslma::Allocator *`. If the type `ALLOCATOR` is `bsl::allocator`
982 /// and `basicAllocator` is not supplied, the currently installed
983 /// default allocator is used. If the sequence `first` to `last` is
984 /// ordered according to `comparator`, then this operation has `O[N]`
985 /// complexity, where `N` is the number of elements between `first` and
986 /// `last`; otherwise, this operation has `O[N * log(N)]` complexity.
987 /// The (template parameter) type `INPUT_ITERATOR` shall meet the
988 /// requirements of an input iterator defined in the C++11 standard
989 /// [24.2.3] providing access to values of a type convertible to
990 /// `value_type`, and `value_type` must be `emplace-constructible` from
991 /// `*i` into this multimap, where `i` is a dereferenceable iterator in
992 /// the range `[first .. last)` (see {Requirements on `KEY` and
993 /// `VALUE`}). The behavior is undefined unless `first` and `last`
994 /// refer to a sequence of valid values where `first` is at a position
995 /// at or before `last`.
996 template <class INPUT_ITERATOR>
997 multimap(INPUT_ITERATOR first,
998 INPUT_ITERATOR last,
999 const COMPARATOR& comparator = COMPARATOR(),
1000 const ALLOCATOR& basicAllocator = ALLOCATOR());
1001 template <class INPUT_ITERATOR>
1002 multimap(INPUT_ITERATOR first,
1003 INPUT_ITERATOR last,
1004 const ALLOCATOR& basicAllocator);
1005
1006#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1007 multimap(std::initializer_list<value_type> values,
1008 const COMPARATOR& comparator = COMPARATOR(),
1009 const ALLOCATOR& basicAllocator = ALLOCATOR());
1010 /// Create a multimap and insert each `value_type` object in the
1011 /// specified `values` initializer list. Optionally specify a
1012 /// `comparator` used to order keys contained in this object. If
1013 /// `comparator` is not supplied, a default-constructed object of the
1014 /// (template parameter) type `COMPARATOR` is used. Optionally specify
1015 /// a `basicAllocator` used to supply memory. If `basicAllocator` is
1016 /// not supplied, a default-constructed object of the (template
1017 /// parameter) type `ALLOCATOR` is used. If the type `ALLOCATOR` is
1018 /// `bsl::allocator` (the default), then `basicAllocator`, if supplied,
1019 /// shall be convertible to `bslma::Allocator *`. If the type
1020 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
1021 /// supplied, the currently installed default allocator is used. If
1022 /// `values` is ordered according to `comparator`, then this operation
1023 /// has `O[N]` complexity, where `N` is the number of elements in
1024 /// `values`; otherwise, this operation has `O[N * log(N)]` complexity.
1025 /// This method requires that the (template parameter) types `KEY` and
1026 /// `VALUE` both be `copy-insertable` into this multimap (see
1027 /// {Requirements on `KEY` and `VALUE`}).
1028 multimap(std::initializer_list<value_type> values,
1029 const ALLOCATOR& basicAllocator);
1030#endif
1031
1032 /// Destroy this object.
1033 ~multimap();
1034
1035 // MANIPULATORS
1036
1037 /// Assign to this object the value and comparator of the specified
1038 /// `rhs` object, propagate to this object the allocator of `rhs` if the
1039 /// `ALLOCATOR` type has trait `propagate_on_container_copy_assignment`,
1040 /// and return a reference providing modifiable access to this object.
1041 /// If an exception is thrown, `*this` is left in a valid but
1042 /// unspecified state. This method requires that the (template
1043 /// parameter) types `KEY` and `VALUE` both be `copy-assignable` and
1044 /// `copy-insertable` into this multimap (see {Requirements on `KEY` and
1045 /// `VALUE`}).
1046 multimap& operator=(const multimap& rhs);
1047
1048 multimap& operator=(BloombergLP::bslmf::MovableRef<multimap> rhs)
1050 AllocatorTraits::is_always_equal::value &&
1051 std::is_nothrow_move_assignable<COMPARATOR>::value);
1052 // Assign to this object the value and comparator of the specified
1053 // 'rhs' object, propagate to this object the allocator of 'rhs' if the
1054 // 'ALLOCATOR' type has trait 'propagate_on_container_move_assignment',
1055 // and return a reference providing modifiable access to this object.
1056 // The contents of 'rhs' are moved (in constant time) to this multimap
1057 // if 'get_allocator() == rhs.get_allocator()' (after accounting for
1058 // the aforementioned trait); otherwise, all elements in this multimap
1059 // are either destroyed or move-assigned to and each additional element
1060 // in 'rhs' is move-inserted into this multimap. 'rhs' is left in a
1061 // valid but unspecified state, and if an exception is thrown, '*this'
1062 // is left in a valid but unspecified state. This method requires that
1063 // the (template parameter) types 'KEY' and 'VALUE' both be
1064 // 'move-assignable' and 'move-insertable' into this multimap (see
1065 // {Requirements on 'KEY' and 'VALUE'}).
1066
1067#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1068 /// Assign to this object the value resulting from first clearing this
1069 /// multimap and then inserting each `value_type` object in the
1070 /// specified `values` initializer list, and return a reference
1071 /// providing modifiable access to this object. This method requires
1072 /// that the (template parameter) types `KEY` and `VALUE` both be
1073 /// `copy-insertable` into this multimap (see {Requirements on `KEY` and
1074 /// `VALUE`}).
1075 multimap& operator=(std::initializer_list<value_type> values);
1076#endif
1077
1078 /// Return an iterator providing modifiable access to the first
1079 /// `value_type` object in the ordered sequence of `value_type` objects
1080 /// maintained by this multimap, or the `end` iterator if this multimap
1081 /// is empty.
1083
1084 /// Return an iterator providing modifiable access to the past-the-end
1085 /// element in the ordered sequence of `value_type` objects maintained
1086 /// by this multimap.
1088
1089 /// Return a reverse iterator providing modifiable access to the last
1090 /// `value_type` object in the ordered sequence of `value_type` objects
1091 /// maintained by this multimap, or `rend` if this multimap is empty.
1093
1094 /// Return a reverse iterator providing modifiable access to the
1095 /// prior-to-the-beginning element in the ordered sequence of
1096 /// `value_type` objects maintained by this multimap.
1098
1099 /// Insert the specified `value` into this multimap. If a range
1100 /// containing elements equivalent to `value` already exists, insert the
1101 /// `value` at the end of that range. Return an iterator referring to
1102 /// the newly inserted `value_type` object. This method requires that
1103 /// the (template parameter) types `KEY` and `VALUE` both be
1104 /// `copy-insertable` into this multimap (see {Requirements on `KEY` and
1105 /// `VALUE`}).
1106 iterator insert(const value_type& value);
1107
1108#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
1109 template <class ALT_VALUE_TYPE>
1110 iterator
1111#elif !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
1112 template <class ALT_VALUE_TYPE>
1114 iterator>::type
1115#else
1116 /// Insert into this multimap a `value_type` object created from the
1117 /// specified `value`. If a range containing elements equivalent to
1118 /// `value_type` object already exists, insert the `value_type` object
1119 /// at the end of that range. Return an iterator referring to the newly
1120 /// inserted `value_type` object. This method requires that the
1121 /// (template parameter) types `KEY` and `VALUE` both be
1122 /// `move-insertable` into this multimap (see {Requirements on `KEY` and
1123 /// `VALUE`}), and the `value_type` be constructible from the (template
1124 /// parameter) `ALT_VALUE_TYPE`.
1125 template <class ALT_VALUE_TYPE>
1126 typename enable_if<std::is_constructible<value_type,
1127 ALT_VALUE_TYPE&&>::value,
1128 iterator>::type
1129#endif
1131 {
1132 // Note that some compilers fail when this method is defined
1133 // out-of-line.
1134
1135 return emplace(BSLS_COMPILERFEATURES_FORWARD(ALT_VALUE_TYPE, value));
1136 }
1137
1138 /// Insert the specified `value` into this multimap (in amortized
1139 /// constant time if the specified `hint` is a valid immediate successor
1140 /// to the key of `value`). Return an iterator referring to the newly
1141 /// inserted `value_type` object. If `hint` is not a valid immediate
1142 /// successor to the key of `value`, this operation has `O[log(N)]`
1143 /// complexity, where `N` is the size of this multimap. This method
1144 /// requires that the (template parameter) types `KEY` and `VALUE` both
1145 /// be `copy-insertable` into this multimap (see {Requirements on `KEY`
1146 /// and `VALUE`}). The behavior is undefined unless `hint` is an
1147 /// iterator in the range `[begin() .. end()]` (both endpoints
1148 /// included).
1149 iterator insert(const_iterator hint, const value_type& value);
1150
1151#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
1152 template <class ALT_VALUE_TYPE>
1153 iterator
1154#elif !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
1155 template <class ALT_VALUE_TYPE>
1157 iterator>::type
1158#else
1159 /// Insert into this multimap a `value_type` object created from the
1160 /// specified `value` (in amortized constant time if the specified
1161 /// `hint` is a valid immediate successor to the object created from
1162 /// `value`). Return an iterator referring to the newly inserted
1163 /// `value_type` object in this multimap. If `hint` is not a valid
1164 /// immediate successor to the object created from `value`, this
1165 /// operation has `O[log(N)]` complexity, where `N` is the size of this
1166 /// multimap. This method requires that the (template parameter) types
1167 /// `KEY` and `VALUE` both be `move-insertable` into this multimap (see
1168 /// {Requirements on `KEY` and `VALUE`}), and the `value_type` be
1169 /// constructible from the (template parameter) `ALT_VALUE_TYPE`. The
1170 /// behavior is undefined unless `hint` is an iterator in the range
1171 /// `[begin() .. end()]` (both endpoints included).
1172 template <class ALT_VALUE_TYPE>
1173 typename enable_if<std::is_constructible<value_type,
1174 ALT_VALUE_TYPE&&>::value,
1175 iterator>::type
1176#endif
1178 BSLS_COMPILERFEATURES_FORWARD_REF(ALT_VALUE_TYPE) value)
1179 {
1180 // Note that some compilers fail when this method is defined
1181 // out-of-line.
1182
1183 return emplace_hint(hint,
1184 BSLS_COMPILERFEATURES_FORWARD(ALT_VALUE_TYPE, value));
1185 }
1186
1187 /// Insert into this multimap the value of each `value_type` object in
1188 /// the range starting at the specified `first` iterator and ending
1189 /// immediately before the specified `last` iterator. The (template
1190 /// parameter) type `INPUT_ITERATOR` shall meet the requirements of an
1191 /// input iterator defined in the C++11 standard [24.2.3] providing
1192 /// access to values of a type convertible to `value_type`, and
1193 /// `value_type` must be `emplace-constructible` from `*i` into this
1194 /// multimap, where `i` is a dereferenceable iterator in the range
1195 /// `[first .. last)` (see {Requirements on `KEY` and `VALUE`}). The
1196 /// behavior is undefined unless `first` and `last` refer to a sequence
1197 /// of valid values where `first` is at a position at or before `last`.
1198 template <class INPUT_ITERATOR>
1199 void insert(INPUT_ITERATOR first, INPUT_ITERATOR last);
1200
1201#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
1202 void insert(const_iterator first, const_iterator last);
1203 // This method is provided only on Sun to work around a bug in the Sun
1204 // Studio 12.3 compiler, which prevents us from disabling (at compile
1205 // time) the overload of 'insert' taking a 'const_iterator' and a
1206 // forwarding reference if the second argument is not convertible to
1207 // the value type associated with the map. Without such a check, in
1208 // certain cases, the same compiler complains of ambiguity between
1209 // the 'insert' method taking two input iterators and the 'insert'
1210 // method taking a 'const_iterator' and a forwarding reference; such
1211 // an ambiguity is resolved by providing this method, which is
1212 // equivalent to the 'insert' method (above) taking two input iterators
1213 // of template parameter type.
1214#endif
1215
1216#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1217 /// Insert into this multimap the value of each `value_type` object in
1218 /// the specified `values` initializer list. This method requires that
1219 /// the (template parameter) types `KEY` and `VALUE` both be
1220 /// `copy-insertable` into this multimap (see {Requirements on `KEY` and
1221 /// `VALUE`}).
1222 void insert(std::initializer_list<value_type> values);
1223#endif
1224
1225#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=2
1226
1227 /// Insert into this multimap a newly-created `value_type` object,
1228 /// constructed by forwarding `get_allocator()` (if required) and the
1229 /// specified (variable number of) `args` to the corresponding
1230 /// constructor of `value_type`. Return an iterator referring to the
1231 /// newly created and inserted object in this multimap. This method
1232 /// requires that the (template parameter) types `KEY` and `VALUE` both
1233 /// be `emplace-constructible` from `args` (see {Requirements on `KEY`
1234 /// and `VALUE`}).
1235 template <class... Args>
1236 iterator emplace(Args&&... args);
1237
1238 /// Insert into this multimap a newly-created `value_type` object,
1239 /// constructed by forwarding `get_allocator()` (if required) and the
1240 /// specified (variable number of) `args` to the corresponding
1241 /// constructor of `value_type` (in amortized constant time if the
1242 /// specified `hint` is a valid immediate successor to the `value_type`
1243 /// object constructed from `args`). Return an iterator referring to
1244 /// the newly created and inserted object in this multimap. If `hint`
1245 /// is not a valid immediate successor to the `value_type` object
1246 /// implied by `args`, this operation has `O[log(N)]` complexity where
1247 /// `N` is the size of this multimap. This method requires that the
1248 /// (template parameter) types `KEY` and `VALUE` both be
1249 /// `emplace-constructible` from `args` (see {Requirements on `KEY` and
1250 /// `VALUE`}). The behavior is undefined unless `hint` is an iterator
1251 /// in the range `[begin() .. end()]` (both endpoints included).
1252 template <class... Args>
1253 iterator emplace_hint(const_iterator hint, Args&&... args);
1254#endif
1255
1256 iterator erase(const_iterator position);
1257 /// Remove from this multimap the `value_type` object at the specified
1258 /// `position`, and return an iterator referring to the element
1259 /// immediately following the removed element, or to the past-the-end
1260 /// position if the removed element was the last element in the sequence
1261 /// of elements maintained by this multimap. This method invalidates
1262 /// only iterators and references to the removed element and previously
1263 /// saved values of the `end()` iterator. The behavior is undefined
1264 /// unless `position` refers to a `value_type` object in this multimap.
1265 iterator erase(iterator position);
1266
1267 /// Remove from this multimap all `value_type` objects whose keys are
1268 /// equivalent to the specified `key`, if such entries exist, and return
1269 /// the number of erased objects; otherwise, if there is no `value_type`
1270 /// objects having an equivalent key, return 0 with no other effect.
1271 /// This method invalidates only iterators and references to the removed
1272 /// element and previously saved values of the `end()` iterator.
1273 size_type erase(const key_type& key);
1274
1276 /// Remove from this multimap the `value_type` objects starting at the
1277 /// specified `first` position up to, but including the specified `last`
1278 /// position, and return `last`. This method invalidates only
1279 /// iterators and references to the removed element and previously saved
1280 /// values of the `end()` iterator. The behavior is undefined unless
1281 /// `first` and `last` either refer to elements in this multimap or are
1282 /// the `end` iterator, and the `first` position is at or before the
1283 /// `last` position in the ordered sequence provided by this container.
1284
1286 AllocatorTraits::is_always_equal::value &&
1287 bsl::is_nothrow_swappable<COMPARATOR>::value);
1288 // Exchange the value and comparator of this object with those of the
1289 // specified 'other' object; also exchange the allocator of this object
1290 // with that of 'other' if the (template parameter) type 'ALLOCATOR'
1291 // has the 'propagate_on_container_swap' trait, and do not modify
1292 // either allocator otherwise. This method provides the no-throw
1293 // exception-safety guarantee if and only if the (template parameter)
1294 // type 'COMPARATOR' provides a no-throw swap operation, and provides
1295 // the basic exception-safety guarantee otherwise; if an exception is
1296 // thrown, both objects are left in valid but unspecified states. This
1297 // operation has 'O[1]' complexity if either this object was created
1298 // with the same allocator as 'other' or 'ALLOCATOR' has the
1299 // 'propagate_on_container_swap' trait; otherwise, it has 'O[n + m]'
1300 // complexity, where 'n' and 'm' are the number of elements in this
1301 // object and 'other', respectively. Note that this method's support
1302 // for swapping objects created with different allocators when
1303 // 'ALLOCATOR' does not have the 'propagate_on_container_swap' trait is
1304 // a departure from the C++ Standard.
1305
1306 /// Remove all entries from this multimap. Note that the multimap is
1307 /// empty after this call, but allocated memory may be retained for
1308 /// future use.
1310
1311 // Turn off complaints about necessarily class-defined methods.
1312 // BDE_VERIFY pragma: push
1313 // BDE_VERIFY pragma: -CD01
1314
1315 /// Return an iterator providing modifiable access to the first
1316 /// `value_type` object in this multimap whose key is equivalent to the
1317 /// specified `key`, if such an entry exists, and the past-the-end
1318 /// (`end`) iterator otherwise.
1319 ///
1320 /// Note: implemented inline due to Sun CC compilation error.
1321 iterator find(const key_type& key)
1322 {
1323 return iterator(BloombergLP::bslalg::RbTreeUtil::find(
1324 d_tree, this->comparator(), key));
1325 }
1326
1327 /// Return an iterator providing modifiable access to the first
1328 /// `value_type` object in this multimap whose key is equivalent to the
1329 /// specified `key`, if such an entry exists, and the past-the-end
1330 /// (`end`) iterator otherwise.
1331 ///
1332 /// Note: implemented inline due to Sun CC compilation error.
1333 template <class LOOKUP_KEY>
1334 typename bsl::enable_if<
1335 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1336 LOOKUP_KEY>::value,
1337 iterator>::type
1338 find(const LOOKUP_KEY& key)
1339 {
1340 return iterator(BloombergLP::bslalg::RbTreeUtil::find(
1341 d_tree, this->comparator(), key));
1342 }
1343
1344 /// Return an iterator providing modifiable access to the first (i.e.,
1345 /// ordered least) `value_type` object in this multimap whose key is
1346 /// greater-than or equal-to the specified `key`, and the past-the-end
1347 /// iterator if this multimap does not contain a `value_type` object
1348 /// whose key is greater-than or equal-to `key`. Note that this
1349 /// function returns the *first* position before which a `value_type`
1350 /// object having an equivalent key could be inserted into the ordered
1351 /// sequence maintained by this multimap, while preserving its ordering.
1352 ///
1353 /// Note: implemented inline due to Sun CC compilation error.
1355 {
1356 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1357 d_tree, this->comparator(), key));
1358 }
1359
1360 /// Return an iterator providing modifiable access to the first (i.e.,
1361 /// ordered least) `value_type` object in this multimap whose key is
1362 /// greater-than or equal-to the specified `key`, and the past-the-end
1363 /// iterator if this multimap does not contain a `value_type` object
1364 /// whose key is greater-than or equal-to `key`. Note that this
1365 /// function returns the *first* position before which a `value_type`
1366 /// object having an equivalent key could be inserted into the ordered
1367 /// sequence maintained by this multimap, while preserving its ordering.
1368 ///
1369 /// Note: implemented inline due to Sun CC compilation error.
1370 template <class LOOKUP_KEY>
1371 typename bsl::enable_if<
1372 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1373 LOOKUP_KEY>::value,
1374 iterator>::type
1375 lower_bound(const LOOKUP_KEY& key)
1376 {
1377 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1378 d_tree, this->comparator(), key));
1379 }
1380
1381 /// Return an iterator providing modifiable access to the first (i.e.,
1382 /// ordered least) `value_type` object in this multimap whose key is
1383 /// greater than the specified `key`, and the past-the-end iterator if
1384 /// this multimap does not contain a `value_type` object whose key is
1385 /// greater-than `key`. Note that this function returns the *last*
1386 /// position before which a `value_type` object having an equivalent key
1387 /// could be inserted into the ordered sequence maintained by this
1388 /// multimap, while preserving its ordering.
1389 ///
1390 /// Note: implemented inline due to Sun CC compilation error.
1392 {
1393 return iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1394 d_tree, this->comparator(), key));
1395 }
1396
1397 /// Return an iterator providing modifiable access to the first (i.e.,
1398 /// ordered least) `value_type` object in this multimap whose key is
1399 /// greater than the specified `key`, and the past-the-end iterator if
1400 /// this multimap does not contain a `value_type` object whose key is
1401 /// greater-than `key`. Note that this function returns the *last*
1402 /// position before which a `value_type` object having an equivalent key
1403 /// could be inserted into the ordered sequence maintained by this
1404 /// multimap, while preserving its ordering.
1405 ///
1406 /// Note: implemented inline due to Sun CC compilation error.
1407 template <class LOOKUP_KEY>
1408 typename bsl::enable_if<
1409 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1410 LOOKUP_KEY>::value,
1411 iterator>::type
1412 upper_bound(const LOOKUP_KEY& key)
1413 {
1414 return iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1415 d_tree, this->comparator(), key));
1416 }
1417
1418 /// Return a pair of iterators providing modifiable access to the
1419 /// sequence of `value_type` objects in this multimap whose keys are
1420 /// equivalent to the specified `key`, where the first iterator is
1421 /// positioned at the start of the sequence and the second is positioned
1422 /// one past the end of the sequence. The first returned iterator will
1423 /// be `lower_bound(key)`, the second returned iterator will be
1424 /// `upper_bound(key)`, and, if this multimap contains no `value_type`
1425 /// object with an equivalent key, then the two returned iterators will
1426 /// have the same value.
1427 ///
1428 /// Note: implemented inline due to Sun CC compilation error.
1430 {
1431 iterator startIt = lower_bound(key);
1432 iterator endIt = startIt;
1433 if (endIt != end() && !comparator()(key, *endIt.node())) {
1434 endIt = upper_bound(key);
1435 }
1436 return bsl::pair<iterator, iterator>(startIt, endIt);
1437 }
1438
1439 /// Return a pair of iterators providing modifiable access to the
1440 /// sequence of `value_type` objects in this multimap whose keys are
1441 /// equivalent to the specified `key`, where the first iterator is
1442 /// positioned at the start of the sequence and the second is positioned
1443 /// one past the end of the sequence. The first returned iterator will
1444 /// be `lower_bound(key)`, the second returned iterator will be
1445 /// `upper_bound(key)`, and, if this multimap contains no `value_type`
1446 /// object with an equivalent key, then the two returned iterators will
1447 /// have the same value.
1448 ///
1449 /// Note: implemented inline due to Sun CC compilation error.
1450 template <class LOOKUP_KEY>
1451 typename bsl::enable_if<
1452 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1453 LOOKUP_KEY>::value,
1455 equal_range(const LOOKUP_KEY& key)
1456 {
1457 iterator startIt = lower_bound(key);
1458 iterator endIt = startIt;
1459 if (endIt != end() && !comparator()(key, *endIt.node())) {
1460 endIt = upper_bound(key);
1461 }
1462 return pair<iterator, iterator>(startIt, endIt);
1463 }
1464
1465 // BDE_VERIFY pragma: pop
1466
1467 // ACCESSORS
1468
1469 /// Return (a copy of) the allocator used for memory allocation by this
1470 /// multimap.
1472
1473 /// Return an iterator providing non-modifiable access to the first
1474 /// `value_type` object in the ordered sequence of `value_type` objects
1475 /// maintained by this multimap, or the `end` iterator if this multimap
1476 /// is empty.
1478
1479 /// Return an iterator providing non-modifiable access to the
1480 /// past-the-end element in the ordered sequence of `value_type` objects
1481 /// maintained by this multimap.
1483
1484 /// Return a reverse iterator providing non-modifiable access to the
1485 /// last `value_type` object in the ordered sequence of `value_type`
1486 /// objects maintained by this multimap, or `rend` if this multimap is
1487 /// empty.
1489
1490 /// Return a reverse iterator providing non-modifiable access to the
1491 /// prior-to-the-beginning element in the ordered sequence of
1492 /// `value_type` objects maintained by this multimap.
1494
1495 /// Return an iterator providing non-modifiable access to the first
1496 /// `value_type` object in the ordered sequence of `value_type` objects
1497 /// maintained by this multimap, or the `cend` iterator if this multimap
1498 /// is empty.
1500
1501 /// Return an iterator providing non-modifiable access to the
1502 /// past-the-end element in the ordered sequence of `value_type` objects
1503 /// maintained by this multimap.
1505
1506 /// Return a reverse iterator providing non-modifiable access to the
1507 /// last `value_type` object in the ordered sequence of `value_type`
1508 /// objects maintained by this multimap, or `rend` if this multimap is
1509 /// empty.
1511
1512 /// Return a reverse iterator providing non-modifiable access to the
1513 /// prior-to-the-beginning element in the ordered sequence of
1514 /// `value_type` objects maintained by this multimap.
1516
1517 /// Return `true` if this multimap contains an element whose key is
1518 /// equivalent to the specified `key`.
1519 bool contains(const key_type &key) const;
1520
1521 /// Return `true` if this multimap contains an element whose key is
1522 /// equivalent to the specified `key`.
1523 ///
1524 /// Note: implemented inline due to Sun CC compilation error
1525 template <class LOOKUP_KEY>
1526 typename bsl::enable_if<
1527 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1528 LOOKUP_KEY>::value,
1529 bool>::type
1530 contains(const LOOKUP_KEY& key) const
1531 {
1532 return find(key) != end();
1533 }
1534
1535 /// Return `true` if this multimap contains no elements, and `false`
1536 /// otherwise.
1537 bool empty() const BSLS_KEYWORD_NOEXCEPT;
1538
1539 /// Return the number of elements in this multimap.
1541
1542 /// Return a theoretical upper bound on the largest number of elements
1543 /// that this multimap could possibly hold. Note that there is no
1544 /// guarantee that the multimap can successfully grow to the returned
1545 /// size, or even close to that size without running out of resources.
1547
1548 /// Return the key-comparison functor (or function pointer) used by this
1549 /// multimap; if a comparator was supplied at construction, return its
1550 /// value, otherwise return a default constructed @ref key_compare object.
1551 /// Note that this comparator compares objects of type `KEY`, which is
1552 /// the key part of the `value_type` objects contained in this multimap.
1553 key_compare key_comp() const;
1554
1555 /// Return a functor for comparing two `value_type` objects by comparing
1556 /// their respective keys using `key_comp()`. Note that this
1557 /// comparator compares objects of type `value_type` (i.e., 'pair<const
1558 /// KEY, VALUE>').
1559 value_compare value_comp() const;
1560
1561 // Turn off complaints about necessarily class-defined methods.
1562 // BDE_VERIFY pragma: push
1563 // BDE_VERIFY pragma: -CD01
1564
1565 /// Return an iterator providing non-modifiable access to the first
1566 /// `value_type` object having the specified `key` in the ordered
1567 /// sequence maintained by this multimap, if such an object exists, and
1568 /// the past-the-end (`end`) iterator otherwise.
1569 ///
1570 /// Note: implemented inline due to Sun CC compilation error.
1571 const_iterator find(const key_type& key) const
1572 {
1573 return const_iterator(BloombergLP::bslalg::RbTreeUtil::find(
1574 d_tree, this->comparator(), key));
1575 }
1576
1577 /// Return an iterator providing non-modifiable access to the first
1578 /// `value_type` object having the specified `key` in the ordered
1579 /// sequence maintained by this multimap, if such an object exists, and
1580 /// the past-the-end (`end`) iterator otherwise.
1581 ///
1582 /// Note: implemented inline due to Sun CC compilation error.
1583 template <class LOOKUP_KEY>
1584 typename bsl::enable_if<
1585 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1586 LOOKUP_KEY>::value,
1587 const_iterator>::type
1588 find(const LOOKUP_KEY& key) const
1589 {
1590 return const_iterator(BloombergLP::bslalg::RbTreeUtil::find(
1591 d_tree, this->comparator(), key));
1592 }
1593
1594 /// Return the number of `value_type` objects within this multimap whose
1595 /// keys are equivalent to the specified `key`.
1596 ///
1597 /// Note: implemented inline due to Sun CC compilation error.
1598 size_type count(const key_type& key) const
1599 {
1600 int count = 0;
1601 const_iterator it = lower_bound(key);
1602
1603 while (it != end() && !comparator()(key, *it.node())) {
1604 ++it;
1605 ++count;
1606 }
1607 return count;
1608 }
1609
1610 /// Return the number of `value_type` objects within this multimap whose
1611 /// keys are equivalent to the specified `key`.
1612 ///
1613 /// Note: implemented inline due to Sun CC compilation error.
1614 template <class LOOKUP_KEY>
1615 typename bsl::enable_if<
1616 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1617 LOOKUP_KEY>::value,
1618 size_type>::type
1619 count(const LOOKUP_KEY& key) const
1620 {
1621 int count = 0;
1622 const_iterator it = lower_bound(key);
1623
1624 while (it != end() && !comparator()(key, *it.node())) {
1625 ++it;
1626 ++count;
1627 }
1628 return count;
1629 }
1630
1631 /// Return an iterator providing non-modifiable access to the first
1632 /// (i.e., ordered least) `value_type` object in this multimap whose key
1633 /// is greater-than or equal-to the specified `key`, and the
1634 /// past-the-end iterator if this multimap does not contain a
1635 /// `value_type` object whose key is greater-than or equal-to `key`.
1636 /// Note that this function returns the *first* position before which a
1637 /// `value_type` object having an equivalent key could be inserted into
1638 /// the ordered sequence maintained by this multimap, while preserving
1639 /// its ordering.
1640 ///
1641 /// Note: implemented inline due to Sun CC compilation error.
1643 {
1644 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1645 d_tree, this->comparator(), key));
1646 }
1647
1648 /// Return an iterator providing non-modifiable access to the first
1649 /// (i.e., ordered least) `value_type` object in this multimap whose key
1650 /// is greater-than or equal-to the specified `key`, and the
1651 /// past-the-end iterator if this multimap does not contain a
1652 /// `value_type` object whose key is greater-than or equal-to `key`.
1653 /// Note that this function returns the *first* position before which a
1654 /// `value_type` object having an equivalent key could be inserted into
1655 /// the ordered sequence maintained by this multimap, while preserving
1656 /// its ordering.
1657 ///
1658 /// Note: implemented inline due to Sun CC compilation error.
1659 template <class LOOKUP_KEY>
1660 typename bsl::enable_if<
1661 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1662 LOOKUP_KEY>::value,
1663 const_iterator>::type
1664 lower_bound(const LOOKUP_KEY& key) const
1665 {
1666 return const_iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1667 d_tree, this->comparator(), key));
1668 }
1669
1670 /// Return an iterator providing non-modifiable access to the first
1671 /// (i.e., ordered least) `value_type` object in this multimap whose key
1672 /// is greater than the specified `key`, and the past-the-end iterator
1673 /// if this multimap does not contain a `value_type` object whose key is
1674 /// greater-than `key`. Note that this function returns the *last*
1675 /// position before which a `value_type` object having an equivalent key
1676 /// could be inserted into the ordered sequence maintained by this
1677 /// multimap, while preserving its ordering.
1678 ///
1679 /// Note: implemented inline due to Sun CC compilation error.
1681 {
1682 return const_iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1683 d_tree, this->comparator(), key));
1684 }
1685
1686 /// Return an iterator providing non-modifiable access to the first
1687 /// (i.e., ordered least) `value_type` object in this multimap whose key
1688 /// is greater than the specified `key`, and the past-the-end iterator
1689 /// if this multimap does not contain a `value_type` object whose key is
1690 /// greater-than `key`. Note that this function returns the *last*
1691 /// position before which a `value_type` object having an equivalent key
1692 /// could be inserted into the ordered sequence maintained by this
1693 /// multimap, while preserving its ordering.
1694 ///
1695 /// Note: implemented inline due to Sun CC compilation error.
1696 template <class LOOKUP_KEY>
1697 typename bsl::enable_if<
1698 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1699 LOOKUP_KEY>::value,
1700 const_iterator>::type
1701 upper_bound(const LOOKUP_KEY& key) const
1702 {
1703 return const_iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1704 d_tree, this->comparator(), key));
1705 }
1706
1707 /// Return a pair of iterators providing non-modifiable access to the
1708 /// sequence of `value_type` objects in this multimap whose keys are
1709 /// equivalent to the specified `key`, where the first iterator is
1710 /// positioned at the start of the sequence and the second iterator is
1711 /// positioned one past the end of the sequence. The first returned
1712 /// iterator will be `lower_bound(key)`, the second returned iterator
1713 /// will be `upper_bound(key)`, and, if this multimap contains no
1714 /// `value_type` objects having keys equivalent to `key`, then the two
1715 /// returned iterators will have the same value.
1716 ///
1717 /// Note: implemented inline due to Sun CC compilation error.
1719 {
1720 const_iterator startIt = lower_bound(key);
1721 const_iterator endIt = startIt;
1722 if (endIt != end() && !comparator()(key, *endIt.node())) {
1723 endIt = upper_bound(key);
1724 }
1725 return bsl::pair<const_iterator, const_iterator>(startIt, endIt);
1726 }
1727
1728 /// Return a pair of iterators providing non-modifiable access to the
1729 /// sequence of `value_type` objects in this multimap whose keys are
1730 /// equivalent to the specified `key`, where the first iterator is
1731 /// positioned at the start of the sequence and the second iterator is
1732 /// positioned one past the end of the sequence. The first returned
1733 /// iterator will be `lower_bound(key)`, the second returned iterator
1734 /// will be `upper_bound(key)`, and, if this multimap contains no
1735 /// `value_type` objects having keys equivalent to `key`, then the two
1736 /// returned iterators will have the same value.
1737 ///
1738 /// Note: implemented inline due to Sun CC compilation error.
1739 template <class LOOKUP_KEY>
1740 typename bsl::enable_if<
1741 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1742 LOOKUP_KEY>::value,
1744 equal_range(const LOOKUP_KEY& key) const
1745 {
1746 const_iterator startIt = lower_bound(key);
1747 const_iterator endIt = startIt;
1748 if (endIt != end() && !comparator()(key, *endIt.node())) {
1749 endIt = upper_bound(key);
1750 }
1751 return pair<const_iterator, const_iterator>(startIt, endIt);
1752 }
1753
1754 // BDE_VERIFY pragma: pop
1755};
1756
1757#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1758// CLASS TEMPLATE DEDUCTION GUIDES
1759
1760/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1761/// of the iterators supplied to the constructor of `multimap`. Deduce the
1762/// template parameters `COMPARATOR` and `ALLOCATOR` from the other
1763/// parameters passed to the constructor. This deduction guide does not
1764/// participate unless the supplied allocator meets the requirements of a
1765/// standard allocator.
1766template <
1767 class INPUT_ITERATOR,
1768 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1769 class VALUE =
1770 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1771 class COMPARATOR = std::less<KEY>,
1772 class ALLOCATOR = bsl::allocator<
1773 BloombergLP::bslstl::IteratorUtil::IterToAlloc_t<INPUT_ITERATOR>>,
1774 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<COMPARATOR>>,
1775 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1776 >
1777multimap(INPUT_ITERATOR,
1778 INPUT_ITERATOR,
1779 COMPARATOR = COMPARATOR(),
1780 ALLOCATOR = ALLOCATOR())
1781-> multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>;
1782
1783/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1784/// of the iterators supplied to the constructor of `multimap`. Deduce the
1785/// template parameter `COMPARATOR` from the other parameter passed to the
1786/// constructor. This deduction guide does not participate unless the
1787/// supplied allocator is convertible to
1788/// `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1789template <
1790 class INPUT_ITERATOR,
1791 class COMPARATOR,
1792 class ALLOC,
1793 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1794 class VALUE =
1795 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1796 class DEFAULT_ALLOCATOR = bsl::allocator<pair<const KEY, VALUE>>,
1797 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1798 >
1799multimap(INPUT_ITERATOR, INPUT_ITERATOR, COMPARATOR, ALLOC *)
1800-> multimap<KEY, VALUE, COMPARATOR>;
1801
1802/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1803/// of the iterators supplied to the constructor of `multimap`. This
1804/// deduction guide does not participate unless the supplied allocator meets
1805/// the requirements of a standard allocator.
1806template <
1807 class INPUT_ITERATOR,
1808 class ALLOCATOR,
1809 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1810 class VALUE =
1811 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1812 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1813 >
1814multimap(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR)
1815-> multimap<KEY, VALUE, std::less<KEY>, ALLOCATOR>;
1816
1817/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1818/// of the iterators supplied to the constructor of `multimap`. This
1819/// deduction guide does not participate unless the supplied allocator is
1820/// convertible to `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1821template <
1822 class INPUT_ITERATOR,
1823 class ALLOC,
1824 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1825 class VALUE =
1826 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1827 class DEFAULT_ALLOCATOR = bsl::allocator<pair<const KEY, VALUE>>,
1828 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1829 >
1830multimap(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
1831-> multimap<KEY, VALUE>;
1832
1833/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1834/// of the initializer_list supplied to the constructor of `multimap`.
1835/// Deduce the template parameters `COMPARATOR` and `ALLOCATOR` from the
1836/// other parameters passed to the constructor. This deduction guide does
1837/// not participate unless the supplied allocator meets the requirements of
1838/// a standard allocator.
1839template <
1840 class KEY,
1841 class VALUE,
1842 class COMPARATOR = std::less<KEY>,
1843 class ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1844 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<COMPARATOR>>,
1845 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1846 >
1847multimap(std::initializer_list<pair<const KEY, VALUE>>,
1848 COMPARATOR = COMPARATOR(),
1849 ALLOCATOR = ALLOCATOR())
1850-> multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>;
1851
1852/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1853/// of the initializer_list supplied to the constructor of `multimap`.
1854/// Deduce the template parameter `COMPARATOR` from the other parameters
1855/// passed to the constructor. This deduction guide does not participate
1856/// unless the supplied allocator is convertible to
1857/// `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1858template <
1859 class KEY,
1860 class VALUE,
1861 class COMPARATOR,
1862 class ALLOC,
1863 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1864 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1865 >
1866multimap(std::initializer_list<pair<const KEY, VALUE>>, COMPARATOR, ALLOC *)
1867-> multimap<KEY, VALUE, COMPARATOR>;
1868
1869/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1870/// of the initializer_list supplied to the constructor of `multimap`.
1871/// Deduce the template parameter `ALLOCATOR` from the other parameter
1872/// passed to the constructor. This deduction guide does not participate
1873/// unless the supplied allocator meets the requirements of a standard
1874/// allocator.
1875template <
1876 class KEY,
1877 class VALUE,
1878 class ALLOCATOR,
1879 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1880 >
1881multimap(std::initializer_list<pair<const KEY, VALUE>>, ALLOCATOR)
1882-> multimap<KEY, VALUE, std::less<KEY>, ALLOCATOR>;
1883
1884/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1885/// of the initializer_list supplied to the constructor of `multimap`. This
1886/// deduction guide does not participate unless the supplied allocator is
1887/// convertible to `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1888template <
1889 class KEY,
1890 class VALUE,
1891 class ALLOC,
1892 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1893 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1894 >
1895multimap(std::initializer_list<pair<const KEY, VALUE>>, ALLOC *)
1896-> multimap<KEY, VALUE>;
1897#endif
1898
1899// FREE OPERATORS
1900
1901/// Return `true` if the specified `lhs` and `rhs` objects have the same
1902/// value, and `false` otherwise. Two `multimap` objects `lhs` and `rhs`
1903/// have the same value if they have the same number of key-value pairs, and
1904/// each element in the ordered sequence of key-value pairs of `lhs` has the
1905/// same value as the corresponding element in the ordered sequence of
1906/// key-value pairs of `rhs`. This method requires that the (template
1907/// parameter) types `KEY` and `VALUE` both be `equality-comparable` (see
1908/// {Requirements on `KEY` and `VALUE`}).
1909template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1910bool operator==(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1911 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1912
1913#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1914template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1915bool operator!=(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1916 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1917 // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the
1918 // same value, and 'false' otherwise. Two 'multimap' objects 'lhs' and
1919 // 'rhs' do not have the same value if they do not have the same number of
1920 // key-value pairs, or some element in the ordered sequence of key-value
1921 // pairs of 'lhs' does not have the same value as the corresponding element
1922 // in the ordered sequence of key-value pairs of 'rhs'. This method
1923 // requires that the (template parameter) types 'KEY' and 'VALUE' both be
1924 // 'equality-comparable' (see {Requirements on 'KEY' and 'VALUE'}).
1925#endif
1926
1927#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1928
1929/// Perform a lexicographic three-way comparison of the specified `lhs` and
1930/// the specified `rhs` maps by using the comparison operators of
1931/// `bsl::pair<const KEY, VALUE>` on each element; return the result of that
1932/// comparison.
1933template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1934BloombergLP::bslalg::SynthThreeWayUtil::Result<pair<const KEY, VALUE>>
1935operator<=>(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1936 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1937
1938#else
1939
1940template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1941bool operator<(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1942 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1943 // Return 'true' if the value of the specified 'lhs' multimap is
1944 // lexicographically less than that of the specified 'rhs' multimap, and
1945 // 'false' otherwise. Given iterators 'i' and 'j' over the respective
1946 // sequences '[lhs.begin() .. lhs.end())' and '[rhs.begin() .. rhs.end())',
1947 // the value of multimap 'lhs' is lexicographically less than that of
1948 // multimap 'rhs' if 'true == *i < *j' for the first pair of corresponding
1949 // iterator positions where '*i < *j' and '*j < *i' are not both 'false'.
1950 // If no such corresponding iterator position exists, the value of 'lhs' is
1951 // lexicographically less than that of 'rhs' if 'lhs.size() < rhs.size()'.
1952 // This method requires that 'operator<', inducing a total order, be
1953 // defined for 'value_type'.
1954
1955template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1956bool operator>(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1957 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1958 // Return 'true' if the value of the specified 'lhs' multimap is
1959 // lexicographically greater than that of the specified 'rhs' multimap, and
1960 // 'false' otherwise. The value of multimap 'lhs' is lexicographically
1961 // greater than that of multimap 'rhs' if 'rhs' is lexicographically less
1962 // than 'lhs' (see 'operator<'). This method requires that 'operator<',
1963 // inducing a total order, be defined for 'value_type'. Note that this
1964 // operator returns 'rhs < lhs'.
1965
1966template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1967bool operator<=(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1968 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1969 // Return 'true' if the value of the specified 'lhs' multimap is
1970 // lexicographically less than or equal to that of the specified 'rhs'
1971 // multimap, and 'false' otherwise. The value of multimap 'lhs' is
1972 // lexicographically less than or equal to that of multimap 'rhs' if 'rhs'
1973 // is not lexicographically less than 'lhs' (see 'operator<'). This method
1974 // requires that 'operator<', inducing a total order, be defined for
1975 // 'value_type'. Note that this operator returns '!(rhs < lhs)'.
1976
1977template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1978bool operator>=(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1979 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1980 // Return 'true' if the value of the specified 'lhs' multimap is
1981 // lexicographically greater than or equal to that of the specified 'rhs'
1982 // multimap, and 'false' otherwise. The value of multimap 'lhs' is
1983 // lexicographically greater than or equal to that of multimap 'rhs' if
1984 // 'lhs' is not lexicographically less than 'rhs' (see 'operator<'). This
1985 // method requires that 'operator<', inducing a total order, be defined for
1986 // 'value_type'. Note that this operator returns '!(lhs < rhs)'.
1987
1988#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1989
1990// FREE FUNCTIONS
1991
1992/// Exchange the value and comparator of the specified `a` object with those
1993/// of the specified `b` object; also exchange the allocator of `a` with
1994/// that of `b` if the (template parameter) type `ALLOCATOR` has the
1995/// `propagate_on_container_swap` trait, and do not modify either allocator
1996/// otherwise. This function provides the no-throw exception-safety
1997/// guarantee if and only if the (template parameter) type `COMPARATOR`
1998/// provides a no-throw swap operation, and provides the basic
1999/// exception-safety guarantee otherwise; if an exception is thrown, both
2000/// objects are left in valid but unspecified states. This operation has
2001/// `O[1]` complexity if either `a` was created with the same allocator as
2002/// `b` or `ALLOCATOR` has the `propagate_on_container_swap` trait;
2003/// otherwise, it has `O[n + m]` complexity, where `n` and `m` are the
2004/// number of elements in `a` and `b`, respectively. Note that this
2005/// function's support for swapping objects created with different
2006/// allocators when `ALLOCATOR` does not have the
2007/// `propagate_on_container_swap` trait is a departure from the C++
2008/// Standard.
2009template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2010void swap(multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& a,
2011 multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& b)
2013
2014// ============================================================================
2015// INLINE FUNCTION DEFINITIONS
2016// ============================================================================
2017
2018 // -----------------
2019 // class DataWrapper
2020 // -----------------
2021
2022// CREATORS
2023template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2024inline
2025multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::DataWrapper(
2026 const COMPARATOR& comparator,
2027 const ALLOCATOR& basicAllocator)
2028: ::bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator(comparator)
2029, d_pool(basicAllocator)
2030{
2031}
2032
2033template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2034inline
2035multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::DataWrapper(
2036 BloombergLP::bslmf::MovableRef<DataWrapper> original)
2037: ::bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator(
2038 MoveUtil::access(original).keyComparator())
2039, d_pool(MoveUtil::move(MoveUtil::access(original).d_pool))
2040{
2041}
2042
2043// MANIPULATORS
2044template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2045inline
2046typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
2047multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::nodeFactory()
2048{
2049 return d_pool;
2050}
2051
2052// ACCESSORS
2053template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2054inline
2055const typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
2056multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::nodeFactory() const
2057{
2058 return d_pool;
2059}
2060
2061 // -----------------------------
2062 // class multimap::value_compare
2063 // -----------------------------
2064
2065template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2066inline
2068 COMPARATOR comparator)
2069: comp(comparator)
2070{
2071}
2072
2073template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2074inline
2076 const value_type& x,
2077 const value_type& y) const
2078{
2079 return comp(x.first, y.first);
2080}
2081
2082 // --------------
2083 // class multimap
2084 // --------------
2085
2086// PRIVATE MANIPULATORS
2087template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2088inline
2089typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator&
2091{
2092 return d_compAndAlloc;
2093}
2094
2095template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2096inline
2097typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
2099{
2100 return d_compAndAlloc.nodeFactory();
2101}
2102
2103template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2104inline
2105void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::quickSwapExchangeAllocators(
2106 multimap& other)
2107{
2108 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &other.d_tree);
2109 nodeFactory().swapExchangeAllocators(other.nodeFactory());
2110
2111 // 'DataWrapper' contains a 'NodeFactory' object and inherits from
2112 // 'Comparator'. If the empty-base-class optimization has been applied to
2113 // 'Comparator', then we must not call 'swap' on it because
2114 // 'sizeof(Comparator) > 0' and, therefore, we will incorrectly swap bytes
2115 // of the 'NodeFactory' members!
2116
2117 if (sizeof(NodeFactory) != sizeof(DataWrapper)) {
2118 comparator().swap(other.comparator());
2119 }
2120}
2121
2122template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2123inline
2124void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::quickSwapRetainAllocators(
2125 multimap& other)
2126{
2127 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &other.d_tree);
2128 nodeFactory().swapRetainAllocators(other.nodeFactory());
2129
2130 // See 'quickSwapExchangeAllocators' (above).
2131
2132 if (sizeof(NodeFactory) != sizeof(DataWrapper)) {
2133 comparator().swap(other.comparator());
2134 }
2135}
2136
2137// PRIVATE ACCESSORS
2138template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2139inline
2140const typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator&
2141multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::comparator() const
2142{
2143 return d_compAndAlloc;
2144}
2145
2146template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2147inline
2148const typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
2149multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::nodeFactory() const
2150{
2151 return d_compAndAlloc.nodeFactory();
2152}
2153
2154// CREATORS
2155template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2156inline
2158: d_compAndAlloc(COMPARATOR(), ALLOCATOR())
2159, d_tree()
2160{
2161}
2162
2163template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2164inline
2166 const ALLOCATOR& basicAllocator)
2167: d_compAndAlloc(COMPARATOR(), basicAllocator)
2168, d_tree()
2169{
2170}
2171
2172template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2173inline
2175: d_compAndAlloc(original.comparator().keyComparator(),
2176 AllocatorTraits::select_on_container_copy_construction(
2177 original.nodeFactory().allocator()))
2178, d_tree()
2179{
2180 if (0 < original.size()) {
2181 nodeFactory().reserveNodes(original.size());
2182 BloombergLP::bslalg::RbTreeUtil::copyTree(&d_tree,
2183 original.d_tree,
2184 &nodeFactory());
2185 }
2186}
2187
2188template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2189inline
2191 BloombergLP::bslmf::MovableRef<multimap> original)
2192: d_compAndAlloc(MoveUtil::move(MoveUtil::access(original).d_compAndAlloc))
2193, d_tree()
2194{
2195 multimap& lvalue = original;
2196 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &lvalue.d_tree);
2197}
2198
2199template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2200inline
2202 const multimap& original,
2203 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2204: d_compAndAlloc(original.comparator().keyComparator(), basicAllocator)
2205, d_tree()
2206{
2207 if (0 < original.size()) {
2208 nodeFactory().reserveNodes(original.size());
2209 BloombergLP::bslalg::RbTreeUtil::copyTree(&d_tree,
2210 original.d_tree,
2211 &nodeFactory());
2212 }
2213}
2214
2215template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2216inline
2218 BloombergLP::bslmf::MovableRef<multimap> original,
2219 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2220: d_compAndAlloc(MoveUtil::access(original).comparator().keyComparator(),
2221 basicAllocator)
2222, d_tree()
2223{
2224 multimap& lvalue = original;
2225
2227 nodeFactory().allocator() == lvalue.nodeFactory().allocator())) {
2228 d_compAndAlloc.nodeFactory().adopt(
2229 MoveUtil::move(lvalue.d_compAndAlloc.nodeFactory()));
2230 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &lvalue.d_tree);
2231 }
2232 else {
2233 if (0 < lvalue.size()) {
2234 nodeFactory().reserveNodes(lvalue.size());
2235 BloombergLP::bslalg::RbTreeUtil::moveTree(&d_tree,
2236 &lvalue.d_tree,
2237 &nodeFactory(),
2238 &lvalue.nodeFactory());
2239 }
2240 }
2241}
2242
2243template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2244template <class INPUT_ITERATOR>
2245inline
2247 INPUT_ITERATOR first,
2248 INPUT_ITERATOR last,
2249 const COMPARATOR& comparator,
2250 const ALLOCATOR& basicAllocator)
2251: d_compAndAlloc(comparator, basicAllocator)
2252, d_tree()
2253{
2254 if (first != last) {
2255
2256 size_type numElements =
2257 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
2258
2259 if (0 < numElements) {
2260 nodeFactory().reserveNodes(numElements);
2261 }
2262
2263 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
2264 &d_tree,
2265 &nodeFactory());
2266
2267 // The following loop guarantees amortized linear time to insert an
2268 // ordered sequence of values (as required by the standard). If the
2269 // values are in sorted order, we are guaranteed the next node can be
2270 // inserted as the right child of the previous node, and can call
2271 // 'insertAt'.
2272
2273 insert(*first);
2274 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
2275 while (++first != last) {
2276 // The values are not in order, so insert them normally.
2277
2278 const value_type& value = *first;
2279 if (this->comparator()(value.first, *prevNode)) {
2280 insert(value);
2281 insert(++first, last);
2282 break;
2283 }
2284 BloombergLP::bslalg::RbTreeNode *node =
2285 nodeFactory().emplaceIntoNewNode(value);
2286 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2287 prevNode,
2288 false,
2289 node);
2290 prevNode = node;
2291 }
2292 proctor.release();
2293 }
2294}
2295
2296template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2297template <class INPUT_ITERATOR>
2298inline
2300 INPUT_ITERATOR first,
2301 INPUT_ITERATOR last,
2302 const ALLOCATOR& basicAllocator)
2303: d_compAndAlloc(COMPARATOR(), basicAllocator)
2304, d_tree()
2305{
2306 if (first != last) {
2307
2308 size_type numElements =
2309 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
2310
2311 if (0 < numElements) {
2312 nodeFactory().reserveNodes(numElements);
2313 }
2314
2315 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
2316 &d_tree,
2317 &nodeFactory());
2318
2319 // The following loop guarantees amortized linear time to insert an
2320 // ordered sequence of values (as required by the standard). If the
2321 // values are in sorted order, we are guaranteed the next node can be
2322 // inserted as the right child of the previous node, and can call
2323 // 'insertAt'.
2324
2325 insert(*first);
2326 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
2327 while (++first != last) {
2328 // The values are not in order, so insert them normally.
2329
2330 const value_type& value = *first;
2331 if (this->comparator()(value.first, *prevNode)) {
2332 insert(value);
2333 insert(++first, last);
2334 break;
2335 }
2336 BloombergLP::bslalg::RbTreeNode *node =
2337 nodeFactory().emplaceIntoNewNode(value);
2338 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2339 prevNode,
2340 false,
2341 node);
2342 prevNode = node;
2343 }
2344 proctor.release();
2345 }
2346}
2347
2348#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2349template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2350inline
2352 std::initializer_list<value_type> values,
2353 const COMPARATOR& comparator,
2354 const ALLOCATOR& basicAllocator)
2355: multimap(values.begin(), values.end(), comparator, basicAllocator)
2356{
2357}
2358
2359template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2360inline
2362 std::initializer_list<value_type> values,
2363 const ALLOCATOR& basicAllocator)
2364: multimap(values.begin(), values.end(), COMPARATOR(), basicAllocator)
2365{
2366}
2367#endif
2368
2369template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2370inline
2375
2376// MANIPULATORS
2377template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2378inline
2381{
2382 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &rhs)) {
2383 if (AllocatorTraits::propagate_on_container_copy_assignment::value) {
2384 multimap other(rhs, rhs.nodeFactory().allocator());
2385 quickSwapExchangeAllocators(other);
2386 }
2387 else {
2388 multimap other(rhs, nodeFactory().allocator());
2389 quickSwapRetainAllocators(other);
2390 }
2391 }
2392 return *this;
2393}
2394
2395template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2396inline
2399 BloombergLP::bslmf::MovableRef<multimap> rhs)
2401 AllocatorTraits::is_always_equal::value &&
2402 std::is_nothrow_move_assignable<COMPARATOR>::value)
2403{
2404 multimap& lvalue = rhs;
2405
2406 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &lvalue)) {
2407 if (nodeFactory().allocator() == lvalue.nodeFactory().allocator()) {
2408 multimap other(MoveUtil::move(lvalue));
2409 quickSwapRetainAllocators(other);
2410 }
2411 else if (
2412 AllocatorTraits::propagate_on_container_move_assignment::value) {
2413 multimap other(MoveUtil::move(lvalue));
2414 quickSwapExchangeAllocators(other);
2415 }
2416 else {
2417 multimap other(MoveUtil::move(lvalue), nodeFactory().allocator());
2418 quickSwapRetainAllocators(other);
2419 }
2420 }
2421 return *this;
2422}
2423
2424#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2425template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2426inline
2427multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>&
2429 std::initializer_list<value_type> values)
2430{
2431 clear();
2432 insert(values.begin(), values.end());
2433 return *this;
2434}
2435#endif
2436
2437template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2438inline
2444
2445template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2446inline
2452
2453template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2454inline
2460
2461template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2462inline
2468
2469template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2470inline
2473{
2474 bool leftChild;
2475
2476 BloombergLP::bslalg::RbTreeNode *insertLocation =
2477 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2478 &d_tree,
2479 this->comparator(),
2480 value.first);
2481
2482 BloombergLP::bslalg::RbTreeNode *node =
2483 nodeFactory().emplaceIntoNewNode(value);
2484
2485 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2486 insertLocation,
2487 leftChild,
2488 node);
2489 return iterator(node);
2490}
2491
2492template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2493template <class INPUT_ITERATOR>
2494inline
2496 INPUT_ITERATOR last)
2497{
2498 ///Implementation Notes
2499 ///--------------------
2500 // First, consume currently held free nodes. Tf those nodes are
2501 // insufficient *and* one can calculate the remaining number of elements,
2502 // then reserve exactly that many free nodes. There is no more than one
2503 // call to 'reserveNodes' per invocation of this method, hence the use of
2504 // 'BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY'.
2505
2506 const bool canCalculateInsertDistance =
2507 is_convertible<typename
2508 iterator_traits<INPUT_ITERATOR>::iterator_category,
2509 forward_iterator_tag>::value;
2510
2511 while (first != last) {
2512 if (canCalculateInsertDistance
2514 !nodeFactory().hasFreeNodes())) {
2515 const size_type numElements =
2516 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
2517
2518 nodeFactory().reserveNodes(numElements);
2519 }
2520 insert(*first);
2521 ++first;
2522 }
2523}
2524
2525#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
2526template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2527inline
2529 const_iterator last)
2530{
2531 while (first != last) {
2532 insert(*first);
2533 ++first;
2534 }
2535}
2536#endif
2537
2538template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2539inline
2542 const value_type& value)
2543{
2544 bool leftChild;
2545
2546 BloombergLP::bslalg::RbTreeNode *hintNode =
2547 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2548
2549 BloombergLP::bslalg::RbTreeNode *insertLocation =
2550 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2551 &d_tree,
2552 this->comparator(),
2553 value.first,
2554 hintNode);
2555
2556 BloombergLP::bslalg::RbTreeNode *node =
2557 nodeFactory().emplaceIntoNewNode(value);
2558
2559 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2560 insertLocation,
2561 leftChild,
2562 node);
2563 return iterator(node);
2564}
2565
2566#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2567template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2568inline
2570 std::initializer_list<value_type> values)
2571{
2572 insert(values.begin(), values.end());
2573}
2574#endif
2575
2576#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2577template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2578template <class... Args>
2579inline
2582{
2583 bool leftChild;
2584
2585 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2586 BSLS_COMPILERFEATURES_FORWARD(Args, args)...);
2587
2588 BloombergLP::bslalg::RbTreeNode *insertLocation =
2589 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2590 &leftChild,
2591 &d_tree,
2592 this->comparator(),
2593 static_cast<const Node *>(node)->value().first);
2594
2595 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2596 insertLocation,
2597 leftChild,
2598 node);
2599 return iterator(node);
2600}
2601
2602template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2603template <class... Args>
2604inline
2607 Args&&... args)
2608{
2609 bool leftChild;
2610
2611 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2612 BSLS_COMPILERFEATURES_FORWARD(Args, args)...);
2613
2614 BloombergLP::bslalg::RbTreeNode *hintNode =
2615 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2616
2617 BloombergLP::bslalg::RbTreeNode *insertLocation =
2618 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2619 &leftChild,
2620 &d_tree,
2621 this->comparator(),
2622 static_cast<const Node *>(node)->value().first,
2623 hintNode);
2624
2625 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2626 insertLocation,
2627 leftChild,
2628 node);
2629 return iterator(node);
2630}
2631
2632#endif
2633
2634template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2635inline
2638{
2639 BSLS_ASSERT_SAFE(position != end());
2640
2641 BloombergLP::bslalg::RbTreeNode *node =
2642 const_cast<BloombergLP::bslalg::RbTreeNode *>(position.node());
2643 BloombergLP::bslalg::RbTreeNode *result =
2644 BloombergLP::bslalg::RbTreeUtil::next(node);
2645 BloombergLP::bslalg::RbTreeUtil::remove(&d_tree, node);
2646 nodeFactory().deleteNode(node);
2647 return iterator(result);
2648}
2649
2650template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2651inline
2657
2658template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2659inline
2662{
2663 size_type count = 0;
2664 const_iterator first = find(key);
2665
2666 if (first != end()) {
2667 const_iterator last = upper_bound(key);
2668 while (first != last) {
2669 first = erase(first);
2670 ++count;
2671 }
2672 }
2673 return count;
2674}
2675
2676template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2677inline
2680 const_iterator last)
2681{
2682 while (first != last) {
2683 first = erase(first);
2684 }
2685 return iterator(last.node());
2686}
2687
2688template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2689inline
2692 AllocatorTraits::is_always_equal::value &&
2693 bsl::is_nothrow_swappable<COMPARATOR>::value)
2694{
2695 if (AllocatorTraits::propagate_on_container_swap::value) {
2696 quickSwapExchangeAllocators(other);
2697 }
2698 else {
2699 // C++11 behavior for member 'swap': undefined for unequal allocators.
2700 // BSLS_ASSERT(allocator() == other.allocator());
2701
2703 nodeFactory().allocator() == other.nodeFactory().allocator())) {
2704 quickSwapRetainAllocators(other);
2705 }
2706 else {
2708
2709 multimap toOtherCopy(MoveUtil::move(*this),
2710 other.nodeFactory().allocator());
2711 multimap toThisCopy( MoveUtil::move(other),
2712 nodeFactory().allocator());
2713
2714 this->quickSwapRetainAllocators(toThisCopy);
2715 other.quickSwapRetainAllocators(toOtherCopy);
2716 }
2717 }
2718}
2719
2720template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2721inline
2723{
2724 BSLS_ASSERT_SAFE(d_tree.firstNode());
2725
2726 if (d_tree.rootNode()) {
2727 BSLS_ASSERT_SAFE(0 < d_tree.numNodes());
2728 BSLS_ASSERT_SAFE(d_tree.firstNode() != d_tree.sentinel());
2729
2730 BloombergLP::bslalg::RbTreeUtil::deleteTree(&d_tree, &nodeFactory());
2731 }
2732#if defined(BSLS_ASSERT_SAFE_IS_USED)
2733 else {
2734 BSLS_ASSERT_SAFE(0 == d_tree.numNodes());
2735 BSLS_ASSERT_SAFE(d_tree.firstNode() == d_tree.sentinel());
2736 }
2737#endif
2738}
2739
2740// ACCESSORS
2741template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2742inline
2746{
2747 return nodeFactory().allocator();
2748}
2749
2750template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2751inline
2758
2759
2760template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2761inline
2767
2768
2769template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2770inline
2777
2778template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2779inline
2785
2786template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2787inline
2791{
2792 return const_iterator(d_tree.firstNode());
2793}
2794
2795template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2796inline
2802
2803template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2804inline
2811
2812template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2813inline
2820
2821template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2822inline
2824 const key_type& key) const
2825{
2826 return find(key) != end();
2827}
2828
2829// capacity:
2830template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2831inline
2834{
2835 return 0 == d_tree.numNodes();
2836}
2837
2838template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2839inline
2842{
2843 return d_tree.numNodes();
2844}
2845
2846template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2847inline
2851{
2852 return AllocatorTraits::max_size(get_allocator());
2853}
2854
2855template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2856inline
2859{
2860 return comparator().keyComparator();
2861}
2862
2863template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2864inline
2870
2871} // close namespace bsl
2872
2873// FREE OPERATORS
2874template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2875inline
2876bool bsl::operator==(
2879{
2880 return BloombergLP::bslalg::RangeCompare::equal(lhs.begin(),
2881 lhs.end(),
2882 lhs.size(),
2883 rhs.begin(),
2884 rhs.end(),
2885 rhs.size());
2886}
2887
2888#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2889template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2890inline
2891bool bsl::operator!=(
2894{
2895 return !(lhs == rhs);
2896}
2897#endif
2898
2899#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2900
2901template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2902inline
2903BloombergLP::bslalg::SynthThreeWayUtil::Result<bsl::pair<const KEY, VALUE>>
2904bsl::operator<=>(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
2905 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs)
2906{
2907 return bsl::lexicographical_compare_three_way(
2908 lhs.begin(),
2909 lhs.end(),
2910 rhs.begin(),
2911 rhs.end(),
2912 BloombergLP::bslalg::SynthThreeWayUtil::compare);
2913}
2914
2915#else
2916
2917template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2918inline
2919bool bsl::operator<(
2922{
2923 return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.begin(),
2924 lhs.end(),
2925 lhs.size(),
2926 rhs.begin(),
2927 rhs.end(),
2928 rhs.size());
2929}
2930
2931template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2932inline
2933bool bsl::operator>(
2936{
2937 return rhs < lhs;
2938}
2939
2940template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2941inline
2942bool bsl::operator<=(
2945{
2946 return !(rhs < lhs);
2947}
2948
2949
2950template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2951inline
2952bool bsl::operator>=(
2955{
2956 return !(lhs < rhs);
2957}
2958
2959#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2960
2961// FREE FUNCTIONS
2962template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2963inline
2967{
2968 a.swap(b);
2969}
2970
2971// ============================================================================
2972// TYPE TRAITS
2973// ============================================================================
2974
2975// Type traits for STL *ordered* containers:
2976//: o An ordered container defines STL iterators.
2977//: o An ordered container uses 'bslma' allocators if the (template parameter)
2978//: type 'ALLOCATOR' is convertible from 'bslma::Allocator *'.
2979
2980
2981
2982namespace bslalg {
2983
2984template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2985struct HasStlIterators<bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR> >
2987{
2988};
2989
2990} // close namespace bslalg
2991
2992namespace bslma {
2993
2994template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2995struct UsesBslmaAllocator<bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR> >
2996 : bsl::is_convertible<Allocator*, ALLOCATOR>
2997{};
2998
2999} // close namespace bslma
3000
3001
3002
3003#endif // End C++11 code
3004
3005#endif
3006
3007// ----------------------------------------------------------------------------
3008// Copyright 2019 Bloomberg Finance L.P.
3009//
3010// Licensed under the Apache License, Version 2.0 (the "License");
3011// you may not use this file except in compliance with the License.
3012// You may obtain a copy of the License at
3013//
3014// http://www.apache.org/licenses/LICENSE-2.0
3015//
3016// Unless required by applicable law or agreed to in writing, software
3017// distributed under the License is distributed on an "AS IS" BASIS,
3018// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3019// See the License for the specific language governing permissions and
3020// limitations under the License.
3021// ----------------------------- END-OF-FILE ----------------------------------
3022
3023/** @} */
3024/** @} */
3025/** @} */
Definition bslma_bslallocator.h:580
Definition bslstl_multimap.h:786
COMPARATOR comp
Definition bslstl_multimap.h:793
value_compare & operator=(const value_compare &rhs)=default
bool operator()(const value_type &x, const value_type &y) const
Definition bslstl_multimap.h:2075
value_type first_argument_type
Definition bslstl_multimap.h:813
bool result_type
Definition bslstl_multimap.h:808
value_type second_argument_type
Definition bslstl_multimap.h:818
value_compare(const value_compare &original)=default
Definition bslstl_multimap.h:665
void swap(multimap &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:1309
AllocatorTraits::difference_type difference_type
Definition bslstl_multimap.h:763
pair< const KEY, VALUE > value_type
Definition bslstl_multimap.h:756
bool contains(const key_type &key) const
Definition bslstl_multimap.h:2823
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, pair< const_iterator, const_iterator > >::type equal_range(const LOOKUP_KEY &key) const
Definition bslstl_multimap.h:1744
const_iterator upper_bound(const key_type &key) const
Definition bslstl_multimap.h:1680
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_multimap.h:776
size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2849
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this multimap.
Definition bslstl_multimap.h:2841
bsl::pair< iterator, iterator > equal_range(const key_type &key)
Definition bslstl_multimap.h:1429
const value_type & const_reference
Definition bslstl_multimap.h:760
COMPARATOR key_compare
Definition bslstl_multimap.h:757
iterator emplace(Args &&... args)
Definition bslstl_multimap.h:2581
AllocatorTraits::const_pointer const_pointer
Definition bslstl_multimap.h:765
AllocatorTraits::size_type size_type
Definition bslstl_multimap.h:762
iterator insert(const value_type &value)
Definition bslstl_multimap.h:2472
BloombergLP::bslstl::TreeIterator< const value_type, Node, difference_type > const_iterator
Definition bslstl_multimap.h:773
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, const_iterator >::type find(const LOOKUP_KEY &key) const
Definition bslstl_multimap.h:1588
const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2806
enable_if< is_convertible< ALT_VALUE_TYPE, value_type >::value, iterator >::type insert(BSLS_COMPILERFEATURES_FORWARD_REF(ALT_VALUE_TYPE) value)
Definition bslstl_multimap.h:1130
iterator erase(const_iterator position)
Definition bslstl_multimap.h:2637
BloombergLP::bslstl::TreeIterator< value_type, Node, difference_type > iterator
Definition bslstl_multimap.h:769
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, iterator >::type find(const LOOKUP_KEY &key)
Definition bslstl_multimap.h:1338
const_iterator lower_bound(const key_type &key) const
Definition bslstl_multimap.h:1642
multimap & operator=(const multimap &rhs)
Definition bslstl_multimap.h:2380
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, size_type >::type count(const LOOKUP_KEY &key) const
Definition bslstl_multimap.h:1619
bsl::reverse_iterator< iterator > reverse_iterator
Definition bslstl_multimap.h:775
bool empty() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2832
reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2456
pair< const_iterator, const_iterator > equal_range(const key_type &key) const
Definition bslstl_multimap.h:1718
ALLOCATOR allocator_type
Definition bslstl_multimap.h:758
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2744
~multimap()
Destroy this object.
Definition bslstl_multimap.h:2371
AllocatorTraits::pointer pointer
Definition bslstl_multimap.h:764
iterator emplace_hint(const_iterator hint, Args &&... args)
Definition bslstl_multimap.h:2606
value_compare value_comp() const
Definition bslstl_multimap.h:2866
iterator lower_bound(const key_type &key)
Definition bslstl_multimap.h:1354
const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2798
multimap(const COMPARATOR &comparator, const ALLOCATOR &basicAllocator=ALLOCATOR())
Definition bslstl_multimap.h:905
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2448
key_compare key_comp() const
Definition bslstl_multimap.h:2858
const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2815
iterator find(const key_type &key)
Definition bslstl_multimap.h:1321
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, iterator >::type upper_bound(const LOOKUP_KEY &key)
Definition bslstl_multimap.h:1412
size_type count(const key_type &key) const
Definition bslstl_multimap.h:1598
const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2789
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, const_iterator >::type lower_bound(const LOOKUP_KEY &key) const
Definition bslstl_multimap.h:1664
multimap()
Definition bslstl_multimap.h:2157
VALUE mapped_type
Definition bslstl_multimap.h:755
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, iterator >::type lower_bound(const LOOKUP_KEY &key)
Definition bslstl_multimap.h:1375
KEY key_type
Definition bslstl_multimap.h:754
iterator upper_bound(const key_type &key)
Definition bslstl_multimap.h:1391
value_type & reference
Definition bslstl_multimap.h:759
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, pair< iterator, iterator > >::type equal_range(const LOOKUP_KEY &key)
Definition bslstl_multimap.h:1455
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, const_iterator >::type upper_bound(const LOOKUP_KEY &key) const
Definition bslstl_multimap.h:1701
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_multimap.h:1177
reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2464
multimap &operator=(BloombergLP::bslmf::MovableRef< multimap > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2440
Definition bslstl_pair.h:1210
#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
#define BSLS_PERFORMANCEHINT_PREDICT_LIKELY(expr)
Definition bsls_performancehint.h:451
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
Definition bdlb_printmethods.h:283
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
T::const_iterator cend(const T &container)
Definition bslstl_iterator.h:1611
bool operator<(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
T::const_reverse_iterator crbegin(const T &container)
Definition bslstl_iterator.h:1597
bool operator>(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator>=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator<=(const array< VALUE_TYPE, SIZE > &lhs, const 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
T::const_iterator cbegin(const T &container)
Definition bslstl_iterator.h:1553
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
bool operator!=(const memory_resource &a, const memory_resource &b)
T::const_reverse_iterator crend(const T &container)
Definition bslstl_iterator.h:1654
Definition bdlc_flathashmap.h:1805
Definition balxml_encoderoptions.h:68
Definition bdlbb_blob.h:576
TYPE first
Definition bslstl_pair.h:605
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 bslmf_isconvertible.h:867
t_TYPE type
Definition bslmf_typeidentity.h:216
Definition bslalg_hasstliterators.h:99
Definition bslma_usesbslmaallocator.h:343