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