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