BDE 4.14.0 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 Sun Sep 1 05:39:10 2024
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)
206 /// type `KEY` . Note that this class exactly matches its definition in
207 /// the C++11 standard [23.4.4.1]; otherwise, we would have implemented
208 /// it as a separate component-local class.
209 ///
210 /// See @ref bslstl_multimap_cpp03
211 class value_compare {
212
213 // FRIENDS
214 friend class multimap;
215
216 protected:
217 // PROTECTED DATA
218 COMPARATOR comp; // we would not have elected to make this data
219 // member 'protected'
220
221 // PROTECTED CREATORS
222
223 /// Create a @ref value_compare object that uses the specified
224 /// `comparator`.
225 value_compare(COMPARATOR comparator); // IMPLICIT
226
227 public:
228 // PUBLIC TYPES
229
230 /// This `typedef` is an alias for the result type of a call to the
231 /// overload of `operator()` (the comparison function) provided by a
232 /// `multimap::value_compare` object.
233 typedef bool result_type;
234
235 /// This `typedef` is an alias for the type of the first parameter
236 /// of the overload of `operator()` (the comparison function)
237 /// provided by a `multimap::value_compare` object.
239
240 /// This `typedef` is an alias for the type of the second parameter
241 /// of the overload of `operator()` (the comparison function)
242 /// provided by a `multimap::value_compare` object.
244
245 // CREATORS
246 value_compare(const value_compare& original) = default;
247 // Create a @ref value_compare object having the same value as the
248 // specified 'original' object.
249
250 ~value_compare() = default;
251 // Destroy this object.
252
253 // MANIPULATORS
254 value_compare& operator=(const value_compare& rhs) = default;
255 // Assign to this object the value of the specified 'rhs' object,
256 // and return a reference providing modifiable access to this
257 // object.
258
259 // ACCESSORS
260
261 /// Return `true` if the specified `x` object is ordered before the
262 /// specified `y` object, as determined by the comparator supplied
263 /// at construction, and `false` otherwise.
264 bool operator()(const value_type& x, const value_type& y) const;
265 };
266
267 private:
268 // PRIVATE CLASS METHODS
269
270 /// Return an address providing modifiable access to the specified
271 /// `node`. The behavior is undefined unless `node` is the address of a
272 /// `Node` object.
273 static Node *toNode(BloombergLP::bslalg::RbTreeNode *node);
274
275 /// Return an address providing non-modifiable access to the specified
276 /// `node`. The behavior is undefined unless `node` is the address of a
277 /// `Node` object.
278 static const Node *toNode(const BloombergLP::bslalg::RbTreeNode *node);
279
280 // PRIVATE MANIPULATORS
281
282 /// Return a reference providing modifiable access to the comparator for
283 /// this multimap.
284 Comparator& comparator();
285
286 /// Return a reference providing modifiable access to the node allocator
287 /// for this multimap.
288 NodeFactory& nodeFactory();
289
290 /// Efficiently exchange the value, comparator, and allocator of this
291 /// object with the value, comparator, and allocator of the specified
292 /// `other` object. This method provides the no-throw exception-safety
293 /// guarantee, *unless* swapping the (user-supplied) comparator or
294 /// allocator objects can throw.
295 void quickSwapExchangeAllocators(multimap& other);
296
297 /// Efficiently exchange the value and comparator of this object with
298 /// the value and comparator of the specified `other` object. This
299 /// method provides the no-throw exception-safety guarantee, *unless*
300 /// swapping the (user-supplied) comparator objects can throw. The
301 /// behavior is undefined unless this object was created with the same
302 /// allocator as `other`.
303 void quickSwapRetainAllocators(multimap& other);
304
305 // PRIVATE ACCESSORS
306
307 /// Return a reference providing non-modifiable access to the comparator
308 /// for this multimap.
309 const Comparator& comparator() const;
310
311 /// Return a reference providing non-modifiable access to the node
312 /// allocator for this multimap.
313 const NodeFactory& nodeFactory() const;
314
315 public:
316 // CREATORS
317
318 multimap();
319 /// Create an empty multimap. Optionally specify a `comparator` used to
320 /// order key-value pairs contained in this object. If `comparator` is
321 /// not supplied, a default-constructed object of the (template
322 /// parameter) type `COMPARATOR` is used. Optionally specify a
323 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
324 /// supplied, a default-constructed object of the (template parameter)
325 /// type `ALLOCATOR` is used. If the type `ALLOCATOR` is
326 /// `bsl::allocator` (the default), then `basicAllocator`, if supplied,
327 /// shall be convertible to `bslma::Allocator *`. If the type
328 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
329 /// supplied, the currently installed default allocator is used.
330 explicit multimap(const COMPARATOR& comparator,
331 const ALLOCATOR& basicAllocator = ALLOCATOR())
332 : d_compAndAlloc(comparator, basicAllocator)
333 , d_tree()
334 {
335 // The implementation is placed here in the class definition to work
336 // around an AIX compiler bug, where the constructor can fail to
337 // compile because it is unable to find the definition of the default
338 // argument. This occurs when a parameterized class wraps around the
339 // container and the comparator is defined after the new class.
340 }
341
342 /// Create an empty multimap that uses the specified `basicAllocator` to
343 /// supply memory. Use a default-constructed object of the (template
344 /// parameter) type `COMPARATOR` to order the key-value pairs contained
345 /// in this multimap. Note that a `bslma::Allocator *` can be supplied
346 /// for `basicAllocator` if the (template parameter) `ALLOCATOR` is
347 /// `bsl::allocator` (the default).
348 explicit multimap(const ALLOCATOR& basicAllocator);
349
350 /// Create a multimap having the same value as the specified `original`
351 /// object. Use a copy of `original.key_comp()` to order the key-value
352 /// pairs contained in this multimap. Use the allocator returned by
353 /// 'bsl::allocator_traits<ALLOCATOR>::
354 /// select_on_container_copy_construction(original.get_allocator())' to
355 /// allocate memory. This method requires that the (template parameter)
356 /// types `KEY` and `VALUE` both be `copy-insertable` into this multimap
357 /// (see {Requirements on `KEY` and `VALUE`}).
358 multimap(const multimap& original);
359
360 /// Create a multimap having the same value as the specified `original`
361 /// object by moving (in constant time) the contents of `original` to
362 /// the new multimap. Use a copy of `original.key_comp()` to order the
363 /// key-value pairs contained in this multimap. The allocator
364 /// associated with `original` is propagated for use in the
365 /// newly-created multimap. `original` is left in a valid but
366 /// unspecified state.
367 multimap(BloombergLP::bslmf::MovableRef<multimap> original); // IMPLICIT
368
369 /// Create a multimap having the same value as the specified `original`
370 /// object that uses the specified `basicAllocator` to supply memory.
371 /// Use a copy of `original.key_comp()` to order the key-value pairs
372 /// contained in this multimap. This method requires that the (template
373 /// parameter) types `KEY` and `VALUE` both be `copy-insertable` into
374 /// this multimap (see {Requirements on `KEY` and `VALUE`}). Note that
375 /// a `bslma::Allocator *` can be supplied for `basicAllocator` if the
376 /// (template parameter) `ALLOCATOR` is `bsl::allocator` (the default).
377 multimap(const multimap& original,
378 const typename type_identity<ALLOCATOR>::type& basicAllocator);
379
380 /// Create a multimap having the same value as the specified `original`
381 /// object that uses the specified `basicAllocator` to supply memory.
382 /// The contents of `original` are moved (in constant time) to the new
383 /// multimap if `basicAllocator == original.get_allocator()`, and are
384 /// move-inserted (in linear time) using `basicAllocator` otherwise.
385 /// `original` is left in a valid but unspecified state. Use a copy of
386 /// `original.key_comp()` to order the key-value pairs contained in this
387 /// multimap. This method requires that the (template parameter) types
388 /// `KEY` and `VALUE` both be `move-insertable` into this multimap (see
389 /// {Requirements on `KEY` and `VALUE`}). Note that a 'bslma::Allocator
390 /// *` can be supplied for `basicAllocator' if the (template parameter)
391 /// `ALLOCATOR` is `bsl::allocator` (the default).
392 multimap(BloombergLP::bslmf::MovableRef<multimap> original,
393 const typename type_identity<ALLOCATOR>::type& basicAllocator);
394
395 /// Create a multimap, and insert each `value_type` object in the
396 /// sequence starting at the specified `first` element, and ending
397 /// immediately before the specified `last` element. Optionally specify
398 /// a `comparator` used to order key-value pairs contained in this
399 /// object. If `comparator` is not supplied, a default-constructed
400 /// object of the (template parameter) type `COMPARATOR` is used.
401 /// Optionally specify a `basicAllocator` used to supply memory. If
402 /// `basicAllocator` is not supplied, a default-constructed object of
403 /// the (template parameter) type `ALLOCATOR` is used. If the type
404 /// `ALLOCATOR` is `bsl::allocator` (the default), then
405 /// `basicAllocator`, if supplied, shall be convertible to
406 /// `bslma::Allocator *`. If the type `ALLOCATOR` is `bsl::allocator`
407 /// and `basicAllocator` is not supplied, the currently installed
408 /// default allocator is used. If the sequence `first` to `last` is
409 /// ordered according to `comparator`, then this operation has `O[N]`
410 /// complexity, where `N` is the number of elements between `first` and
411 /// `last`; otherwise, this operation has `O[N * log(N)]` complexity.
412 /// The (template parameter) type `INPUT_ITERATOR` shall meet the
413 /// requirements of an input iterator defined in the C++11 standard
414 /// [24.2.3] providing access to values of a type convertible to
415 /// `value_type`, and `value_type` must be `emplace-constructible` from
416 /// `*i` into this multimap, where `i` is a dereferenceable iterator in
417 /// the range `[first .. last)` (see {Requirements on `KEY` and
418 /// `VALUE`}). The behavior is undefined unless `first` and `last`
419 /// refer to a sequence of valid values where `first` is at a position
420 /// at or before `last`.
421 template <class INPUT_ITERATOR>
422 multimap(INPUT_ITERATOR first,
423 INPUT_ITERATOR last,
424 const COMPARATOR& comparator = COMPARATOR(),
425 const ALLOCATOR& basicAllocator = ALLOCATOR());
426 template <class INPUT_ITERATOR>
427 multimap(INPUT_ITERATOR first,
428 INPUT_ITERATOR last,
429 const ALLOCATOR& basicAllocator);
430
431#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
432 multimap(std::initializer_list<value_type> values,
433 const COMPARATOR& comparator = COMPARATOR(),
434 const ALLOCATOR& basicAllocator = ALLOCATOR());
435 /// Create a multimap and insert each `value_type` object in the
436 /// specified `values` initializer list. Optionally specify a
437 /// `comparator` used to order keys contained in this object. If
438 /// `comparator` is not supplied, a default-constructed object of the
439 /// (template parameter) type `COMPARATOR` is used. Optionally specify
440 /// a `basicAllocator` used to supply memory. If `basicAllocator` is
441 /// not supplied, a default-constructed object of the (template
442 /// parameter) type `ALLOCATOR` is used. If the type `ALLOCATOR` is
443 /// `bsl::allocator` (the default), then `basicAllocator`, if supplied,
444 /// shall be convertible to `bslma::Allocator *`. If the type
445 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
446 /// supplied, the currently installed default allocator is used. If
447 /// `values` is ordered according to `comparator`, then this operation
448 /// has `O[N]` complexity, where `N` is the number of elements in
449 /// `values`; otherwise, this operation has `O[N * log(N)]` complexity.
450 /// This method requires that the (template parameter) types `KEY` and
451 /// `VALUE` both be `copy-insertable` into this multimap (see
452 /// {Requirements on `KEY` and `VALUE`}).
453 multimap(std::initializer_list<value_type> values,
454 const ALLOCATOR& basicAllocator);
455#endif
456
457 /// Destroy this object.
458 ~multimap();
459
460 // MANIPULATORS
461
462 /// Assign to this object the value and comparator of the specified
463 /// `rhs` object, propagate to this object the allocator of `rhs` if the
464 /// `ALLOCATOR` type has trait `propagate_on_container_copy_assignment`,
465 /// and return a reference providing modifiable access to this object.
466 /// If an exception is thrown, `*this` is left in a valid but
467 /// unspecified state. This method requires that the (template
468 /// parameter) types `KEY` and `VALUE` both be `copy-assignable` and
469 /// `copy-insertable` into this multimap (see {Requirements on `KEY` and
470 /// `VALUE`}).
471 multimap& operator=(const multimap& rhs);
472
473 multimap& operator=(BloombergLP::bslmf::MovableRef<multimap> rhs)
475 AllocatorTraits::is_always_equal::value &&
476 std::is_nothrow_move_assignable<COMPARATOR>::value);
477 // Assign to this object the value and comparator of the specified
478 // 'rhs' object, propagate to this object the allocator of 'rhs' if the
479 // 'ALLOCATOR' type has trait 'propagate_on_container_move_assignment',
480 // and return a reference providing modifiable access to this object.
481 // The contents of 'rhs' are moved (in constant time) to this multimap
482 // if 'get_allocator() == rhs.get_allocator()' (after accounting for
483 // the aforementioned trait); otherwise, all elements in this multimap
484 // are either destroyed or move-assigned to and each additional element
485 // in 'rhs' is move-inserted into this multimap. 'rhs' is left in a
486 // valid but unspecified state, and if an exception is thrown, '*this'
487 // is left in a valid but unspecified state. This method requires that
488 // the (template parameter) types 'KEY' and 'VALUE' both be
489 // 'move-assignable' and 'move-insertable' into this multimap (see
490 // {Requirements on 'KEY' and 'VALUE'}).
491
492#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
493 /// Assign to this object the value resulting from first clearing this
494 /// multimap and then inserting each `value_type` object in the
495 /// specified `values` initializer list, and return a reference
496 /// providing modifiable access to this object. This method requires
497 /// that the (template parameter) types `KEY` and `VALUE` both be
498 /// `copy-insertable` into this multimap (see {Requirements on `KEY` and
499 /// `VALUE`}).
500 multimap& operator=(std::initializer_list<value_type> values);
501#endif
502
503 /// Return an iterator providing modifiable access to the first
504 /// `value_type` object in the ordered sequence of `value_type` objects
505 /// maintained by this multimap, or the `end` iterator if this multimap
506 /// is empty.
508
509 /// Return an iterator providing modifiable access to the past-the-end
510 /// element in the ordered sequence of `value_type` objects maintained
511 /// by this multimap.
513
514 /// Return a reverse iterator providing modifiable access to the last
515 /// `value_type` object in the ordered sequence of `value_type` objects
516 /// maintained by this multimap, or `rend` if this multimap is empty.
518
519 /// Return a reverse iterator providing modifiable access to the
520 /// prior-to-the-beginning element in the ordered sequence of
521 /// `value_type` objects maintained by this multimap.
523
524 /// Insert the specified `value` into this multimap. If a range
525 /// containing elements equivalent to `value` already exists, insert the
526 /// `value` at the end of that range. Return an iterator referring to
527 /// the newly inserted `value_type` object. This method requires that
528 /// the (template parameter) types `KEY` and `VALUE` both be
529 /// `copy-insertable` into this multimap (see {Requirements on `KEY` and
530 /// `VALUE`}).
531 iterator insert(const value_type& value);
532
533#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
534 template <class ALT_VALUE_TYPE>
536#elif !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
537 template <class ALT_VALUE_TYPE>
538 typename enable_if<is_convertible<ALT_VALUE_TYPE, value_type>::value,
539 iterator>::type
540#else
541 /// Insert into this multimap a `value_type` object created from the
542 /// specified `value`. If a range containing elements equivalent to
543 /// `value_type` object already exists, insert the `value_type` object
544 /// at the end of that range. Return an iterator referring to the newly
545 /// inserted `value_type` object. This method requires that the
546 /// (template parameter) types `KEY` and `VALUE` both be
547 /// `move-insertable` into this multimap (see {Requirements on `KEY` and
548 /// `VALUE`}), and the `value_type` be constructible from the (template
549 /// parameter) `ALT_VALUE_TYPE`.
550 template <class ALT_VALUE_TYPE>
551 typename enable_if<std::is_constructible<value_type,
552 ALT_VALUE_TYPE&&>::value,
553 iterator>::type
554#endif
555 insert(BSLS_COMPILERFEATURES_FORWARD_REF(ALT_VALUE_TYPE) value)
556 {
557 // Note that some compilers fail when this method is defined
558 // out-of-line.
559
560 return emplace(BSLS_COMPILERFEATURES_FORWARD(ALT_VALUE_TYPE, value));
561 }
562
563 /// Insert the specified `value` into this multimap (in amortized
564 /// constant time if the specified `hint` is a valid immediate successor
565 /// to the key of `value`). Return an iterator referring to the newly
566 /// inserted `value_type` object. If `hint` is not a valid immediate
567 /// successor to the key of `value`, this operation has `O[log(N)]`
568 /// complexity, where `N` is the size of this multimap. This method
569 /// requires that the (template parameter) types `KEY` and `VALUE` both
570 /// be `copy-insertable` into this multimap (see {Requirements on `KEY`
571 /// and `VALUE`}). The behavior is undefined unless `hint` is an
572 /// iterator in the range `[begin() .. end()]` (both endpoints
573 /// included).
574 iterator insert(const_iterator hint, const value_type& value);
575
576#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
577 template <class ALT_VALUE_TYPE>
579#elif !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
580 template <class ALT_VALUE_TYPE>
581 typename enable_if<is_convertible<ALT_VALUE_TYPE, value_type>::value,
582 iterator>::type
583#else
584 /// Insert into this multimap a `value_type` object created from the
585 /// specified `value` (in amortized constant time if the specified
586 /// `hint` is a valid immediate successor to the object created from
587 /// `value`). Return an iterator referring to the newly inserted
588 /// `value_type` object in this multimap. If `hint` is not a valid
589 /// immediate successor to the object created from `value`, this
590 /// operation has `O[log(N)]` complexity, where `N` is the size of this
591 /// multimap. This method requires that the (template parameter) types
592 /// `KEY` and `VALUE` both be `move-insertable` into this multimap (see
593 /// {Requirements on `KEY` and `VALUE`}), and the `value_type` be
594 /// constructible from the (template parameter) `ALT_VALUE_TYPE`. The
595 /// behavior is undefined unless `hint` is an iterator in the range
596 /// `[begin() .. end()]` (both endpoints included).
597 template <class ALT_VALUE_TYPE>
598 typename enable_if<std::is_constructible<value_type,
599 ALT_VALUE_TYPE&&>::value,
600 iterator>::type
601#endif
603 BSLS_COMPILERFEATURES_FORWARD_REF(ALT_VALUE_TYPE) value)
604 {
605 // Note that some compilers fail when this method is defined
606 // out-of-line.
607
608 return emplace_hint(hint,
609 BSLS_COMPILERFEATURES_FORWARD(ALT_VALUE_TYPE, value));
610 }
611
612 /// Insert into this multimap the value of each `value_type` object in
613 /// the range starting at the specified `first` iterator and ending
614 /// immediately before the specified `last` iterator. The (template
615 /// parameter) type `INPUT_ITERATOR` shall meet the requirements of an
616 /// input iterator defined in the C++11 standard [24.2.3] providing
617 /// access to values of a type convertible to `value_type`, and
618 /// `value_type` must be `emplace-constructible` from `*i` into this
619 /// multimap, where `i` is a dereferenceable iterator in the range
620 /// `[first .. last)` (see {Requirements on `KEY` and `VALUE`}). The
621 /// behavior is undefined unless `first` and `last` refer to a sequence
622 /// of valid values where `first` is at a position at or before `last`.
623 template <class INPUT_ITERATOR>
624 void insert(INPUT_ITERATOR first, INPUT_ITERATOR last);
625
626#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
627 void insert(const_iterator first, const_iterator last);
628 // This method is provided only on Sun to work around a bug in the Sun
629 // Studio 12.3 compiler, which prevents us from disabling (at compile
630 // time) the overload of 'insert' taking a 'const_iterator' and a
631 // forwarding reference if the second argument is not convertible to
632 // the value type associated with the map. Without such a check, in
633 // certain cases, the same compiler complains of ambiguity between
634 // the 'insert' method taking two input iterators and the 'insert'
635 // method taking a 'const_iterator' and a forwarding reference; such
636 // an ambiguity is resolved by providing this method, which is
637 // equivalent to the 'insert' method (above) taking two input iterators
638 // of template parameter type.
639#endif
640
641#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
642 /// Insert into this multimap the value of each `value_type` object in
643 /// the specified `values` initializer list. This method requires that
644 /// the (template parameter) types `KEY` and `VALUE` both be
645 /// `copy-insertable` into this multimap (see {Requirements on `KEY` and
646 /// `VALUE`}).
647 void insert(std::initializer_list<value_type> values);
648#endif
649
650#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
651// {{{ BEGIN GENERATED CODE
652// Command line: sim_cpp11_features.pl bslstl_multimap.h
653#ifndef BSLSTL_MULTIMAP_VARIADIC_LIMIT
654#define BSLSTL_MULTIMAP_VARIADIC_LIMIT 2
655#endif
656#ifndef BSLSTL_MULTIMAP_VARIADIC_LIMIT_A
657#define BSLSTL_MULTIMAP_VARIADIC_LIMIT_A BSLSTL_MULTIMAP_VARIADIC_LIMIT
658#endif
659
660#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 0
662#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 0
663
664#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 1
665 template <class Args_1>
667#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 1
668
669#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 2
670 template <class Args_1,
671 class Args_2>
673 BSLS_COMPILERFEATURES_FORWARD_REF(Args_2) args_2);
674#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 2
675
676
677#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 0
679#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 0
680
681#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 1
682 template <class Args_1>
684 BSLS_COMPILERFEATURES_FORWARD_REF(Args_1) args_1);
685#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 1
686
687#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 2
688 template <class Args_1,
689 class Args_2>
692 BSLS_COMPILERFEATURES_FORWARD_REF(Args_2) args_2);
693#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 2
694
695#else
696// The generated code below is a workaround for the absence of perfect
697// forwarding in some compilers.
698
699 template <class... Args>
701
702 template <class... Args>
705// }}} END GENERATED CODE
706#endif
707
708 iterator erase(const_iterator position);
709 /// Remove from this multimap the `value_type` object at the specified
710 /// `position`, and return an iterator referring to the element
711 /// immediately following the removed element, or to the past-the-end
712 /// position if the removed element was the last element in the sequence
713 /// of elements maintained by this multimap. This method invalidates
714 /// only iterators and references to the removed element and previously
715 /// saved values of the `end()` iterator. The behavior is undefined
716 /// unless `position` refers to a `value_type` object in this multimap.
717 iterator erase(iterator position);
718
719 /// Remove from this multimap all `value_type` objects whose keys are
720 /// equivalent to the specified `key`, if such entries exist, and return
721 /// the number of erased objects; otherwise, if there is no `value_type`
722 /// objects having an equivalent key, return 0 with no other effect.
723 /// This method invalidates only iterators and references to the removed
724 /// element and previously saved values of the `end()` iterator.
725 size_type erase(const key_type& key);
726
728 /// Remove from this multimap the `value_type` objects starting at the
729 /// specified `first` position up to, but including the specified `last`
730 /// position, and return `last`. This method invalidates only
731 /// iterators and references to the removed element and previously saved
732 /// values of the `end()` iterator. The behavior is undefined unless
733 /// `first` and `last` either refer to elements in this multimap or are
734 /// the `end` iterator, and the `first` position is at or before the
735 /// `last` position in the ordered sequence provided by this container.
736
738 AllocatorTraits::is_always_equal::value &&
739 bsl::is_nothrow_swappable<COMPARATOR>::value);
740 // Exchange the value and comparator of this object with those of the
741 // specified 'other' object; also exchange the allocator of this object
742 // with that of 'other' if the (template parameter) type 'ALLOCATOR'
743 // has the 'propagate_on_container_swap' trait, and do not modify
744 // either allocator otherwise. This method provides the no-throw
745 // exception-safety guarantee if and only if the (template parameter)
746 // type 'COMPARATOR' provides a no-throw swap operation, and provides
747 // the basic exception-safety guarantee otherwise; if an exception is
748 // thrown, both objects are left in valid but unspecified states. This
749 // operation has 'O[1]' complexity if either this object was created
750 // with the same allocator as 'other' or 'ALLOCATOR' has the
751 // 'propagate_on_container_swap' trait; otherwise, it has 'O[n + m]'
752 // complexity, where 'n' and 'm' are the number of elements in this
753 // object and 'other', respectively. Note that this method's support
754 // for swapping objects created with different allocators when
755 // 'ALLOCATOR' does not have the 'propagate_on_container_swap' trait is
756 // a departure from the C++ Standard.
757
758 /// Remove all entries from this multimap. Note that the multimap is
759 /// empty after this call, but allocated memory may be retained for
760 /// future use.
762
763 // Turn off complaints about necessarily class-defined methods.
764 // BDE_VERIFY pragma: push
765 // BDE_VERIFY pragma: -CD01
766
767 /// Return an iterator providing modifiable access to the first
768 /// `value_type` object in this multimap whose key is equivalent to the
769 /// specified `key`, if such an entry exists, and the past-the-end
770 /// (`end`) iterator otherwise.
771 ///
772 /// Note: implemented inline due to Sun CC compilation error.
773 iterator find(const key_type& key)
774 {
775 return iterator(BloombergLP::bslalg::RbTreeUtil::find(
776 d_tree, this->comparator(), key));
777 }
778
779 /// Return an iterator providing modifiable access to the first
780 /// `value_type` object in this multimap whose key is equivalent to the
781 /// specified `key`, if such an entry exists, and the past-the-end
782 /// (`end`) iterator otherwise.
783 ///
784 /// Note: implemented inline due to Sun CC compilation error.
785 template <class LOOKUP_KEY>
786 typename bsl::enable_if<
787 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
788 LOOKUP_KEY>::value,
789 iterator>::type
790 find(const LOOKUP_KEY& key)
791 {
792 return iterator(BloombergLP::bslalg::RbTreeUtil::find(
793 d_tree, this->comparator(), key));
794 }
795
796 /// Return an iterator providing modifiable access to the first (i.e.,
797 /// ordered least) `value_type` object in this multimap whose key is
798 /// greater-than or equal-to the specified `key`, and the past-the-end
799 /// iterator if this multimap does not contain a `value_type` object
800 /// whose key is greater-than or equal-to `key`. Note that this
801 /// function returns the *first* position before which a `value_type`
802 /// object having an equivalent key could be inserted into the ordered
803 /// sequence maintained by this multimap, while preserving its ordering.
804 ///
805 /// Note: implemented inline due to Sun CC compilation error.
806 iterator lower_bound(const key_type& key)
807 {
808 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
809 d_tree, this->comparator(), key));
810 }
811
812 /// Return an iterator providing modifiable access to the first (i.e.,
813 /// ordered least) `value_type` object in this multimap whose key is
814 /// greater-than or equal-to the specified `key`, and the past-the-end
815 /// iterator if this multimap does not contain a `value_type` object
816 /// whose key is greater-than or equal-to `key`. Note that this
817 /// function returns the *first* position before which a `value_type`
818 /// object having an equivalent key could be inserted into the ordered
819 /// sequence maintained by this multimap, while preserving its ordering.
820 ///
821 /// Note: implemented inline due to Sun CC compilation error.
822 template <class LOOKUP_KEY>
823 typename bsl::enable_if<
824 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
825 LOOKUP_KEY>::value,
826 iterator>::type
827 lower_bound(const LOOKUP_KEY& key)
828 {
829 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
830 d_tree, this->comparator(), key));
831 }
832
833 /// Return an iterator providing modifiable access to the first (i.e.,
834 /// ordered least) `value_type` object in this multimap whose key is
835 /// greater than the specified `key`, and the past-the-end iterator if
836 /// this multimap does not contain a `value_type` object whose key is
837 /// greater-than `key`. Note that this function returns the *last*
838 /// position before which a `value_type` object having an equivalent key
839 /// could be inserted into the ordered sequence maintained by this
840 /// multimap, while preserving its ordering.
841 ///
842 /// Note: implemented inline due to Sun CC compilation error.
843 iterator upper_bound(const key_type& key)
844 {
845 return iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
846 d_tree, this->comparator(), key));
847 }
848
849 /// Return an iterator providing modifiable access to the first (i.e.,
850 /// ordered least) `value_type` object in this multimap whose key is
851 /// greater than the specified `key`, and the past-the-end iterator if
852 /// this multimap does not contain a `value_type` object whose key is
853 /// greater-than `key`. Note that this function returns the *last*
854 /// position before which a `value_type` object having an equivalent key
855 /// could be inserted into the ordered sequence maintained by this
856 /// multimap, while preserving its ordering.
857 ///
858 /// Note: implemented inline due to Sun CC compilation error.
859 template <class LOOKUP_KEY>
860 typename bsl::enable_if<
861 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
862 LOOKUP_KEY>::value,
863 iterator>::type
864 upper_bound(const LOOKUP_KEY& key)
865 {
866 return iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
867 d_tree, this->comparator(), key));
868 }
869
870 /// Return a pair of iterators providing modifiable access to the
871 /// sequence of `value_type` objects in this multimap whose keys are
872 /// equivalent to the specified `key`, where the first iterator is
873 /// positioned at the start of the sequence and the second is positioned
874 /// one past the end of the sequence. The first returned iterator will
875 /// be `lower_bound(key)`, the second returned iterator will be
876 /// `upper_bound(key)`, and, if this multimap contains no `value_type`
877 /// object with an equivalent key, then the two returned iterators will
878 /// have the same value.
879 ///
880 /// Note: implemented inline due to Sun CC compilation error.
882 {
883 iterator startIt = lower_bound(key);
884 iterator endIt = startIt;
885 if (endIt != end() && !comparator()(key, *endIt.node())) {
886 endIt = upper_bound(key);
887 }
888 return bsl::pair<iterator, iterator>(startIt, endIt);
889 }
890
891 /// Return a pair of iterators providing modifiable access to the
892 /// sequence of `value_type` objects in this multimap whose keys are
893 /// equivalent to the specified `key`, where the first iterator is
894 /// positioned at the start of the sequence and the second is positioned
895 /// one past the end of the sequence. The first returned iterator will
896 /// be `lower_bound(key)`, the second returned iterator will be
897 /// `upper_bound(key)`, and, if this multimap contains no `value_type`
898 /// object with an equivalent key, then the two returned iterators will
899 /// have the same value.
900 ///
901 /// Note: implemented inline due to Sun CC compilation error.
902 template <class LOOKUP_KEY>
903 typename bsl::enable_if<
904 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
905 LOOKUP_KEY>::value,
906 pair<iterator, iterator> >::type
907 equal_range(const LOOKUP_KEY& key)
908 {
909 iterator startIt = lower_bound(key);
910 iterator endIt = startIt;
911 if (endIt != end() && !comparator()(key, *endIt.node())) {
912 endIt = upper_bound(key);
913 }
914 return pair<iterator, iterator>(startIt, endIt);
915 }
916
917 // BDE_VERIFY pragma: pop
918
919 // ACCESSORS
920
921 /// Return (a copy of) the allocator used for memory allocation by this
922 /// multimap.
924
925 /// Return an iterator providing non-modifiable access to the first
926 /// `value_type` object in the ordered sequence of `value_type` objects
927 /// maintained by this multimap, or the `end` iterator if this multimap
928 /// is empty.
930
931 /// Return an iterator providing non-modifiable access to the
932 /// past-the-end element in the ordered sequence of `value_type` objects
933 /// maintained by this multimap.
935
936 /// Return a reverse iterator providing non-modifiable access to the
937 /// last `value_type` object in the ordered sequence of `value_type`
938 /// objects maintained by this multimap, or `rend` if this multimap is
939 /// empty.
941
942 /// Return a reverse iterator providing non-modifiable access to the
943 /// prior-to-the-beginning element in the ordered sequence of
944 /// `value_type` objects maintained by this multimap.
946
947 /// Return an iterator providing non-modifiable access to the first
948 /// `value_type` object in the ordered sequence of `value_type` objects
949 /// maintained by this multimap, or the `cend` iterator if this multimap
950 /// is empty.
952
953 /// Return an iterator providing non-modifiable access to the
954 /// past-the-end element in the ordered sequence of `value_type` objects
955 /// maintained by this multimap.
957
958 /// Return a reverse iterator providing non-modifiable access to the
959 /// last `value_type` object in the ordered sequence of `value_type`
960 /// objects maintained by this multimap, or `rend` if this multimap is
961 /// empty.
963
964 /// Return a reverse iterator providing non-modifiable access to the
965 /// prior-to-the-beginning element in the ordered sequence of
966 /// `value_type` objects maintained by this multimap.
968
969 /// Return `true` if this multimap contains an element whose key is
970 /// equivalent to the specified `key`.
971 bool contains(const key_type &key) const;
972
973 /// Return `true` if this multimap contains an element whose key is
974 /// equivalent to the specified `key`.
975 ///
976 /// Note: implemented inline due to Sun CC compilation error
977 template <class LOOKUP_KEY>
978 typename bsl::enable_if<
979 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
980 LOOKUP_KEY>::value,
981 bool>::type
982 contains(const LOOKUP_KEY& key) const
983 {
984 return find(key) != end();
985 }
986
987 /// Return `true` if this multimap contains no elements, and `false`
988 /// otherwise.
989 bool empty() const BSLS_KEYWORD_NOEXCEPT;
990
991 /// Return the number of elements in this multimap.
993
994 /// Return a theoretical upper bound on the largest number of elements
995 /// that this multimap could possibly hold. Note that there is no
996 /// guarantee that the multimap can successfully grow to the returned
997 /// size, or even close to that size without running out of resources.
999
1000 /// Return the key-comparison functor (or function pointer) used by this
1001 /// multimap; if a comparator was supplied at construction, return its
1002 /// value, otherwise return a default constructed @ref key_compare object.
1003 /// Note that this comparator compares objects of type `KEY`, which is
1004 /// the key part of the `value_type` objects contained in this multimap.
1005 key_compare key_comp() const;
1006
1007 /// Return a functor for comparing two `value_type` objects by comparing
1008 /// their respective keys using `key_comp()`. Note that this
1009 /// comparator compares objects of type `value_type` (i.e., 'pair<const
1010 /// KEY, VALUE>').
1011 value_compare value_comp() const;
1012
1013 // Turn off complaints about necessarily class-defined methods.
1014 // BDE_VERIFY pragma: push
1015 // BDE_VERIFY pragma: -CD01
1016
1017 /// Return an iterator providing non-modifiable access to the first
1018 /// `value_type` object having the specified `key` in the ordered
1019 /// sequence maintained by this multimap, if such an object exists, and
1020 /// the past-the-end (`end`) iterator otherwise.
1021 ///
1022 /// Note: implemented inline due to Sun CC compilation error.
1023 const_iterator find(const key_type& key) const
1024 {
1025 return const_iterator(BloombergLP::bslalg::RbTreeUtil::find(
1026 d_tree, this->comparator(), key));
1027 }
1028
1029 /// Return an iterator providing non-modifiable access to the first
1030 /// `value_type` object having the specified `key` in the ordered
1031 /// sequence maintained by this multimap, if such an object exists, and
1032 /// the past-the-end (`end`) iterator otherwise.
1033 ///
1034 /// Note: implemented inline due to Sun CC compilation error.
1035 template <class LOOKUP_KEY>
1036 typename bsl::enable_if<
1037 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1038 LOOKUP_KEY>::value,
1039 const_iterator>::type
1040 find(const LOOKUP_KEY& key) const
1041 {
1042 return const_iterator(BloombergLP::bslalg::RbTreeUtil::find(
1043 d_tree, this->comparator(), key));
1044 }
1045
1046 /// Return the number of `value_type` objects within this multimap whose
1047 /// keys are equivalent to the specified `key`.
1048 ///
1049 /// Note: implemented inline due to Sun CC compilation error.
1050 size_type count(const key_type& key) const
1051 {
1052 int count = 0;
1053 const_iterator it = lower_bound(key);
1054
1055 while (it != end() && !comparator()(key, *it.node())) {
1056 ++it;
1057 ++count;
1058 }
1059 return count;
1060 }
1061
1062 /// Return the number of `value_type` objects within this multimap whose
1063 /// keys are equivalent to the specified `key`.
1064 ///
1065 /// Note: implemented inline due to Sun CC compilation error.
1066 template <class LOOKUP_KEY>
1067 typename bsl::enable_if<
1068 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1069 LOOKUP_KEY>::value,
1070 size_type>::type
1071 count(const LOOKUP_KEY& key) const
1072 {
1073 int count = 0;
1074 const_iterator it = lower_bound(key);
1075
1076 while (it != end() && !comparator()(key, *it.node())) {
1077 ++it;
1078 ++count;
1079 }
1080 return count;
1081 }
1082
1083 /// Return an iterator providing non-modifiable access to the first
1084 /// (i.e., ordered least) `value_type` object in this multimap whose key
1085 /// is greater-than or equal-to the specified `key`, and the
1086 /// past-the-end iterator if this multimap does not contain a
1087 /// `value_type` object whose key is greater-than or equal-to `key`.
1088 /// Note that this function returns the *first* position before which a
1089 /// `value_type` object having an equivalent key could be inserted into
1090 /// the ordered sequence maintained by this multimap, while preserving
1091 /// its ordering.
1092 ///
1093 /// Note: implemented inline due to Sun CC compilation error.
1094 const_iterator lower_bound(const key_type& key) const
1095 {
1096 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1097 d_tree, this->comparator(), key));
1098 }
1099
1100 /// Return an iterator providing non-modifiable access to the first
1101 /// (i.e., ordered least) `value_type` object in this multimap whose key
1102 /// is greater-than or equal-to the specified `key`, and the
1103 /// past-the-end iterator if this multimap does not contain a
1104 /// `value_type` object whose key is greater-than or equal-to `key`.
1105 /// Note that this function returns the *first* position before which a
1106 /// `value_type` object having an equivalent key could be inserted into
1107 /// the ordered sequence maintained by this multimap, while preserving
1108 /// its ordering.
1109 ///
1110 /// Note: implemented inline due to Sun CC compilation error.
1111 template <class LOOKUP_KEY>
1112 typename bsl::enable_if<
1113 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1114 LOOKUP_KEY>::value,
1115 const_iterator>::type
1116 lower_bound(const LOOKUP_KEY& key) const
1117 {
1118 return const_iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1119 d_tree, this->comparator(), key));
1120 }
1121
1122 /// Return an iterator providing non-modifiable access to the first
1123 /// (i.e., ordered least) `value_type` object in this multimap whose key
1124 /// is greater than the specified `key`, and the past-the-end iterator
1125 /// if this multimap does not contain a `value_type` object whose key is
1126 /// greater-than `key`. Note that this function returns the *last*
1127 /// position before which a `value_type` object having an equivalent key
1128 /// could be inserted into the ordered sequence maintained by this
1129 /// multimap, while preserving its ordering.
1130 ///
1131 /// Note: implemented inline due to Sun CC compilation error.
1132 const_iterator upper_bound(const key_type& key) const
1133 {
1134 return const_iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1135 d_tree, this->comparator(), key));
1136 }
1137
1138 /// Return an iterator providing non-modifiable access to the first
1139 /// (i.e., ordered least) `value_type` object in this multimap whose key
1140 /// is greater than the specified `key`, and the past-the-end iterator
1141 /// if this multimap does not contain a `value_type` object whose key is
1142 /// greater-than `key`. Note that this function returns the *last*
1143 /// position before which a `value_type` object having an equivalent key
1144 /// could be inserted into the ordered sequence maintained by this
1145 /// multimap, while preserving its ordering.
1146 ///
1147 /// Note: implemented inline due to Sun CC compilation error.
1148 template <class LOOKUP_KEY>
1149 typename bsl::enable_if<
1150 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1151 LOOKUP_KEY>::value,
1152 const_iterator>::type
1153 upper_bound(const LOOKUP_KEY& key) const
1154 {
1155 return const_iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1156 d_tree, this->comparator(), key));
1157 }
1158
1159 /// Return a pair of iterators providing non-modifiable access to the
1160 /// sequence of `value_type` objects in this multimap whose keys are
1161 /// equivalent to the specified `key`, where the first iterator is
1162 /// positioned at the start of the sequence and the second iterator is
1163 /// positioned one past the end of the sequence. The first returned
1164 /// iterator will be `lower_bound(key)`, the second returned iterator
1165 /// will be `upper_bound(key)`, and, if this multimap contains no
1166 /// `value_type` objects having keys equivalent to `key`, then the two
1167 /// returned iterators will have the same value.
1168 ///
1169 /// Note: implemented inline due to Sun CC compilation error.
1170 pair<const_iterator, const_iterator> equal_range(const key_type& key) const
1171 {
1172 const_iterator startIt = lower_bound(key);
1173 const_iterator endIt = startIt;
1174 if (endIt != end() && !comparator()(key, *endIt.node())) {
1175 endIt = upper_bound(key);
1176 }
1177 return bsl::pair<const_iterator, const_iterator>(startIt, endIt);
1178 }
1179
1180 /// Return a pair of iterators providing non-modifiable access to the
1181 /// sequence of `value_type` objects in this multimap whose keys are
1182 /// equivalent to the specified `key`, where the first iterator is
1183 /// positioned at the start of the sequence and the second iterator is
1184 /// positioned one past the end of the sequence. The first returned
1185 /// iterator will be `lower_bound(key)`, the second returned iterator
1186 /// will be `upper_bound(key)`, and, if this multimap contains no
1187 /// `value_type` objects having keys equivalent to `key`, then the two
1188 /// returned iterators will have the same value.
1189 ///
1190 /// Note: implemented inline due to Sun CC compilation error.
1191 template <class LOOKUP_KEY>
1192 typename bsl::enable_if<
1193 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1194 LOOKUP_KEY>::value,
1195 pair<const_iterator, const_iterator> >::type
1196 equal_range(const LOOKUP_KEY& key) const
1197 {
1198 const_iterator startIt = lower_bound(key);
1199 const_iterator endIt = startIt;
1200 if (endIt != end() && !comparator()(key, *endIt.node())) {
1201 endIt = upper_bound(key);
1202 }
1203 return pair<const_iterator, const_iterator>(startIt, endIt);
1204 }
1205
1206 // BDE_VERIFY pragma: pop
1207};
1208
1209#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1210// CLASS TEMPLATE DEDUCTION GUIDES
1211
1212/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1213/// of the iterators supplied to the constructor of `multimap`. Deduce the
1214/// template parameters `COMPARATOR` and `ALLOCATOR` from the other
1215/// parameters passed to the constructor. This deduction guide does not
1216/// participate unless the supplied allocator meets the requirements of a
1217/// standard allocator.
1218template <
1219 class INPUT_ITERATOR,
1220 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1221 class VALUE =
1222 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1223 class COMPARATOR = std::less<KEY>,
1224 class ALLOCATOR = bsl::allocator<
1225 BloombergLP::bslstl::IteratorUtil::IterToAlloc_t<INPUT_ITERATOR>>,
1226 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<COMPARATOR>>,
1227 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1228 >
1229multimap(INPUT_ITERATOR,
1230 INPUT_ITERATOR,
1231 COMPARATOR = COMPARATOR(),
1232 ALLOCATOR = ALLOCATOR())
1233-> multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>;
1234
1235/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1236/// of the iterators supplied to the constructor of `multimap`. Deduce the
1237/// template parameter `COMPARATOR` from the other parameter passed to the
1238/// constructor. This deduction guide does not participate unless the
1239/// supplied allocator is convertible to
1240/// `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1241template <
1242 class INPUT_ITERATOR,
1243 class COMPARATOR,
1244 class ALLOC,
1245 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1246 class VALUE =
1247 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1248 class DEFAULT_ALLOCATOR = bsl::allocator<pair<const KEY, VALUE>>,
1249 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1250 >
1251multimap(INPUT_ITERATOR, INPUT_ITERATOR, COMPARATOR, ALLOC *)
1252-> multimap<KEY, VALUE, COMPARATOR>;
1253
1254/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1255/// of the iterators supplied to the constructor of `multimap`. This
1256/// deduction guide does not participate unless the supplied allocator meets
1257/// the requirements of a standard allocator.
1258template <
1259 class INPUT_ITERATOR,
1260 class ALLOCATOR,
1261 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1262 class VALUE =
1263 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1264 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1265 >
1266multimap(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR)
1267-> multimap<KEY, VALUE, std::less<KEY>, ALLOCATOR>;
1268
1269/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1270/// of the iterators supplied to the constructor of `multimap`. This
1271/// deduction guide does not participate unless the supplied allocator is
1272/// convertible to `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1273template <
1274 class INPUT_ITERATOR,
1275 class ALLOC,
1276 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1277 class VALUE =
1278 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1279 class DEFAULT_ALLOCATOR = bsl::allocator<pair<const KEY, VALUE>>,
1280 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1281 >
1282multimap(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
1283-> multimap<KEY, VALUE>;
1284
1285/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1286/// of the initializer_list supplied to the constructor of `multimap`.
1287/// Deduce the template parameters `COMPARATOR` and `ALLOCATOR` from the
1288/// other parameters passed to the constructor. This deduction guide does
1289/// not participate unless the supplied allocator meets the requirements of
1290/// a standard allocator.
1291template <
1292 class KEY,
1293 class VALUE,
1294 class COMPARATOR = std::less<KEY>,
1295 class ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1296 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<COMPARATOR>>,
1297 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1298 >
1299multimap(std::initializer_list<pair<const KEY, VALUE>>,
1300 COMPARATOR = COMPARATOR(),
1301 ALLOCATOR = ALLOCATOR())
1302-> multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>;
1303
1304/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1305/// of the initializer_list supplied to the constructor of `multimap`.
1306/// Deduce the template parameter `COMPARATOR` from the other parameters
1307/// passed to the constructor. This deduction guide does not participate
1308/// unless the supplied allocator is convertible to
1309/// `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1310template <
1311 class KEY,
1312 class VALUE,
1313 class COMPARATOR,
1314 class ALLOC,
1315 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1316 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1317 >
1318multimap(std::initializer_list<pair<const KEY, VALUE>>, COMPARATOR, ALLOC *)
1319-> multimap<KEY, VALUE, COMPARATOR>;
1320
1321/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1322/// of the initializer_list supplied to the constructor of `multimap`.
1323/// Deduce the template parameter `ALLOCATOR` from the other parameter
1324/// passed to the constructor. This deduction guide does not participate
1325/// unless the supplied allocator meets the requirements of a standard
1326/// allocator.
1327template <
1328 class KEY,
1329 class VALUE,
1330 class ALLOCATOR,
1331 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1332 >
1333multimap(std::initializer_list<pair<const KEY, VALUE>>, ALLOCATOR)
1334-> multimap<KEY, VALUE, std::less<KEY>, ALLOCATOR>;
1335
1336/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
1337/// of the initializer_list supplied to the constructor of `multimap`. This
1338/// deduction guide does not participate unless the supplied allocator is
1339/// convertible to `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
1340template <
1341 class KEY,
1342 class VALUE,
1343 class ALLOC,
1344 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1345 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1346 >
1347multimap(std::initializer_list<pair<const KEY, VALUE>>, ALLOC *)
1348-> multimap<KEY, VALUE>;
1349#endif
1350
1351// FREE OPERATORS
1352
1353/// Return `true` if the specified `lhs` and `rhs` objects have the same
1354/// value, and `false` otherwise. Two `multimap` objects `lhs` and `rhs`
1355/// have the same value if they have the same number of key-value pairs, and
1356/// each element in the ordered sequence of key-value pairs of `lhs` has the
1357/// same value as the corresponding element in the ordered sequence of
1358/// key-value pairs of `rhs`. This method requires that the (template
1359/// parameter) types `KEY` and `VALUE` both be `equality-comparable` (see
1360/// {Requirements on `KEY` and `VALUE`}).
1361template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1362bool operator==(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1363 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1364
1365#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1366template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1367bool operator!=(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1368 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1369 // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the
1370 // same value, and 'false' otherwise. Two 'multimap' objects 'lhs' and
1371 // 'rhs' do not have the same value if they do not have the same number of
1372 // key-value pairs, or some element in the ordered sequence of key-value
1373 // pairs of 'lhs' does not have the same value as the corresponding element
1374 // in the ordered sequence of key-value pairs of 'rhs'. This method
1375 // requires that the (template parameter) types 'KEY' and 'VALUE' both be
1376 // 'equality-comparable' (see {Requirements on 'KEY' and 'VALUE'}).
1377#endif
1378
1379#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1380
1381/// Perform a lexicographic three-way comparison of the specified `lhs` and
1382/// the specified `rhs` maps by using the comparison operators of
1383/// `bsl::pair<const KEY, VALUE>` on each element; return the result of that
1384/// comparison.
1385template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1386BloombergLP::bslalg::SynthThreeWayUtil::Result<pair<const KEY, VALUE>>
1387operator<=>(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1388 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1389
1390#else
1391
1392template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1393bool operator<(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1394 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1395 // Return 'true' if the value of the specified 'lhs' multimap is
1396 // lexicographically less than that of the specified 'rhs' multimap, and
1397 // 'false' otherwise. Given iterators 'i' and 'j' over the respective
1398 // sequences '[lhs.begin() .. lhs.end())' and '[rhs.begin() .. rhs.end())',
1399 // the value of multimap 'lhs' is lexicographically less than that of
1400 // multimap 'rhs' if 'true == *i < *j' for the first pair of corresponding
1401 // iterator positions where '*i < *j' and '*j < *i' are not both 'false'.
1402 // If no such corresponding iterator position exists, the value of 'lhs' is
1403 // lexicographically less than that of 'rhs' if 'lhs.size() < rhs.size()'.
1404 // This method requires that 'operator<', inducing a total order, be
1405 // defined for 'value_type'.
1406
1407template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1408bool operator>(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1409 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1410 // Return 'true' if the value of the specified 'lhs' multimap is
1411 // lexicographically greater than that of the specified 'rhs' multimap, and
1412 // 'false' otherwise. The value of multimap 'lhs' is lexicographically
1413 // greater than that of multimap 'rhs' if 'rhs' is lexicographically less
1414 // than 'lhs' (see 'operator<'). This method requires that 'operator<',
1415 // inducing a total order, be defined for 'value_type'. Note that this
1416 // operator returns 'rhs < lhs'.
1417
1418template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1419bool operator<=(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1420 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1421 // Return 'true' if the value of the specified 'lhs' multimap is
1422 // lexicographically less than or equal to that of the specified 'rhs'
1423 // multimap, and 'false' otherwise. The value of multimap 'lhs' is
1424 // lexicographically less than or equal to that of multimap 'rhs' if 'rhs'
1425 // is not lexicographically less than 'lhs' (see 'operator<'). This method
1426 // requires that 'operator<', inducing a total order, be defined for
1427 // 'value_type'. Note that this operator returns '!(rhs < lhs)'.
1428
1429template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1430bool operator>=(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1431 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1432 // Return 'true' if the value of the specified 'lhs' multimap is
1433 // lexicographically greater than or equal to that of the specified 'rhs'
1434 // multimap, and 'false' otherwise. The value of multimap 'lhs' is
1435 // lexicographically greater than or equal to that of multimap 'rhs' if
1436 // 'lhs' is not lexicographically less than 'rhs' (see 'operator<'). This
1437 // method requires that 'operator<', inducing a total order, be defined for
1438 // 'value_type'. Note that this operator returns '!(lhs < rhs)'.
1439
1440#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1441
1442// FREE FUNCTIONS
1443
1444/// Exchange the value and comparator of the specified `a` object with those
1445/// of the specified `b` object; also exchange the allocator of `a` with
1446/// that of `b` if the (template parameter) type `ALLOCATOR` has the
1447/// `propagate_on_container_swap` trait, and do not modify either allocator
1448/// otherwise. This function provides the no-throw exception-safety
1449/// guarantee if and only if the (template parameter) type `COMPARATOR`
1450/// provides a no-throw swap operation, and provides the basic
1451/// exception-safety guarantee otherwise; if an exception is thrown, both
1452/// objects are left in valid but unspecified states. This operation has
1453/// `O[1]` complexity if either `a` was created with the same allocator as
1454/// `b` or `ALLOCATOR` has the `propagate_on_container_swap` trait;
1455/// otherwise, it has `O[n + m]` complexity, where `n` and `m` are the
1456/// number of elements in `a` and `b`, respectively. Note that this
1457/// function's support for swapping objects created with different
1458/// allocators when `ALLOCATOR` does not have the
1459/// `propagate_on_container_swap` trait is a departure from the C++
1460/// Standard.
1461template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1462void swap(multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& a,
1463 multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& b)
1465
1466// ============================================================================
1467// INLINE FUNCTION DEFINITIONS
1468// ============================================================================
1469
1470 // -----------------
1471 // class DataWrapper
1472 // -----------------
1473
1474// CREATORS
1475template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1476inline
1477multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::DataWrapper(
1478 const COMPARATOR& comparator,
1479 const ALLOCATOR& basicAllocator)
1480: ::bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator(comparator)
1481, d_pool(basicAllocator)
1482{
1483}
1484
1485template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1486inline
1487multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::DataWrapper(
1488 BloombergLP::bslmf::MovableRef<DataWrapper> original)
1489: ::bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator(
1490 MoveUtil::access(original).keyComparator())
1491, d_pool(MoveUtil::move(MoveUtil::access(original).d_pool))
1492{
1493}
1494
1495// MANIPULATORS
1496template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1497inline
1498typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
1499multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::nodeFactory()
1500{
1501 return d_pool;
1502}
1503
1504// ACCESSORS
1505template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1506inline
1507const typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
1508multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::nodeFactory() const
1509{
1510 return d_pool;
1511}
1512
1513 // -----------------------------
1514 // class multimap::value_compare
1515 // -----------------------------
1516
1517template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1518inline
1519multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::value_compare::value_compare(
1520 COMPARATOR comparator)
1521: comp(comparator)
1522{
1523}
1524
1525template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1526inline
1527bool multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::value_compare::operator()(
1528 const value_type& x,
1529 const value_type& y) const
1530{
1531 return comp(x.first, y.first);
1532}
1533
1534 // --------------
1535 // class multimap
1536 // --------------
1537
1538// PRIVATE MANIPULATORS
1539template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1540inline
1541typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator&
1542multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::comparator()
1543{
1544 return d_compAndAlloc;
1545}
1546
1547template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1548inline
1549typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
1550multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::nodeFactory()
1551{
1552 return d_compAndAlloc.nodeFactory();
1553}
1554
1555template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1556inline
1557void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::quickSwapExchangeAllocators(
1558 multimap& other)
1559{
1560 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &other.d_tree);
1561 nodeFactory().swapExchangeAllocators(other.nodeFactory());
1562
1563 // 'DataWrapper' contains a 'NodeFactory' object and inherits from
1564 // 'Comparator'. If the empty-base-class optimization has been applied to
1565 // 'Comparator', then we must not call 'swap' on it because
1566 // 'sizeof(Comparator) > 0' and, therefore, we will incorrectly swap bytes
1567 // of the 'NodeFactory' members!
1568
1569 if (sizeof(NodeFactory) != sizeof(DataWrapper)) {
1570 comparator().swap(other.comparator());
1571 }
1572}
1573
1574template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1575inline
1576void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::quickSwapRetainAllocators(
1577 multimap& other)
1578{
1579 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &other.d_tree);
1580 nodeFactory().swapRetainAllocators(other.nodeFactory());
1581
1582 // See 'quickSwapExchangeAllocators' (above).
1583
1584 if (sizeof(NodeFactory) != sizeof(DataWrapper)) {
1585 comparator().swap(other.comparator());
1586 }
1587}
1588
1589// PRIVATE ACCESSORS
1590template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1591inline
1592const typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator&
1593multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::comparator() const
1594{
1595 return d_compAndAlloc;
1596}
1597
1598template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1599inline
1600const typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
1601multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::nodeFactory() const
1602{
1603 return d_compAndAlloc.nodeFactory();
1604}
1605
1606// CREATORS
1607template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1608inline
1609multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap()
1610: d_compAndAlloc(COMPARATOR(), ALLOCATOR())
1611, d_tree()
1612{
1613}
1614
1615template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1616inline
1617multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
1618 const ALLOCATOR& basicAllocator)
1619: d_compAndAlloc(COMPARATOR(), basicAllocator)
1620, d_tree()
1621{
1622}
1623
1624template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1625inline
1626multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(const multimap& original)
1627: d_compAndAlloc(original.comparator().keyComparator(),
1628 AllocatorTraits::select_on_container_copy_construction(
1629 original.nodeFactory().allocator()))
1630, d_tree()
1631{
1632 if (0 < original.size()) {
1633 nodeFactory().reserveNodes(original.size());
1634 BloombergLP::bslalg::RbTreeUtil::copyTree(&d_tree,
1635 original.d_tree,
1636 &nodeFactory());
1637 }
1638}
1639
1640template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1641inline
1642multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
1643 BloombergLP::bslmf::MovableRef<multimap> original)
1644: d_compAndAlloc(MoveUtil::move(MoveUtil::access(original).d_compAndAlloc))
1645, d_tree()
1646{
1647 multimap& lvalue = original;
1648 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &lvalue.d_tree);
1649}
1650
1651template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1652inline
1653multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
1654 const multimap& original,
1655 const typename type_identity<ALLOCATOR>::type& basicAllocator)
1656: d_compAndAlloc(original.comparator().keyComparator(), basicAllocator)
1657, d_tree()
1658{
1659 if (0 < original.size()) {
1660 nodeFactory().reserveNodes(original.size());
1661 BloombergLP::bslalg::RbTreeUtil::copyTree(&d_tree,
1662 original.d_tree,
1663 &nodeFactory());
1664 }
1665}
1666
1667template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1668inline
1669multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
1670 BloombergLP::bslmf::MovableRef<multimap> original,
1671 const typename type_identity<ALLOCATOR>::type& basicAllocator)
1672: d_compAndAlloc(MoveUtil::access(original).comparator().keyComparator(),
1673 basicAllocator)
1674, d_tree()
1675{
1676 multimap& lvalue = original;
1677
1679 nodeFactory().allocator() == lvalue.nodeFactory().allocator())) {
1680 d_compAndAlloc.nodeFactory().adopt(
1681 MoveUtil::move(lvalue.d_compAndAlloc.nodeFactory()));
1682 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &lvalue.d_tree);
1683 }
1684 else {
1685 if (0 < lvalue.size()) {
1686 nodeFactory().reserveNodes(lvalue.size());
1687 BloombergLP::bslalg::RbTreeUtil::moveTree(&d_tree,
1688 &lvalue.d_tree,
1689 &nodeFactory(),
1690 &lvalue.nodeFactory());
1691 }
1692 }
1693}
1694
1695template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1696template <class INPUT_ITERATOR>
1697inline
1698multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
1699 INPUT_ITERATOR first,
1700 INPUT_ITERATOR last,
1701 const COMPARATOR& comparator,
1702 const ALLOCATOR& basicAllocator)
1703: d_compAndAlloc(comparator, basicAllocator)
1704, d_tree()
1705{
1706 if (first != last) {
1707
1708 size_type numElements =
1709 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
1710
1711 if (0 < numElements) {
1712 nodeFactory().reserveNodes(numElements);
1713 }
1714
1715 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
1716 &d_tree,
1717 &nodeFactory());
1718
1719 // The following loop guarantees amortized linear time to insert an
1720 // ordered sequence of values (as required by the standard). If the
1721 // values are in sorted order, we are guaranteed the next node can be
1722 // inserted as the right child of the previous node, and can call
1723 // 'insertAt'.
1724
1725 insert(*first);
1726 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
1727 while (++first != last) {
1728 // The values are not in order, so insert them normally.
1729
1730 const value_type& value = *first;
1731 if (this->comparator()(value.first, *prevNode)) {
1732 insert(value);
1733 insert(++first, last);
1734 break;
1735 }
1736 BloombergLP::bslalg::RbTreeNode *node =
1737 nodeFactory().emplaceIntoNewNode(value);
1738 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
1739 prevNode,
1740 false,
1741 node);
1742 prevNode = node;
1743 }
1744 proctor.release();
1745 }
1746}
1747
1748template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1749template <class INPUT_ITERATOR>
1750inline
1751multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
1752 INPUT_ITERATOR first,
1753 INPUT_ITERATOR last,
1754 const ALLOCATOR& basicAllocator)
1755: d_compAndAlloc(COMPARATOR(), basicAllocator)
1756, d_tree()
1757{
1758 if (first != last) {
1759
1760 size_type numElements =
1761 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
1762
1763 if (0 < numElements) {
1764 nodeFactory().reserveNodes(numElements);
1765 }
1766
1767 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
1768 &d_tree,
1769 &nodeFactory());
1770
1771 // The following loop guarantees amortized linear time to insert an
1772 // ordered sequence of values (as required by the standard). If the
1773 // values are in sorted order, we are guaranteed the next node can be
1774 // inserted as the right child of the previous node, and can call
1775 // 'insertAt'.
1776
1777 insert(*first);
1778 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
1779 while (++first != last) {
1780 // The values are not in order, so insert them normally.
1781
1782 const value_type& value = *first;
1783 if (this->comparator()(value.first, *prevNode)) {
1784 insert(value);
1785 insert(++first, last);
1786 break;
1787 }
1788 BloombergLP::bslalg::RbTreeNode *node =
1789 nodeFactory().emplaceIntoNewNode(value);
1790 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
1791 prevNode,
1792 false,
1793 node);
1794 prevNode = node;
1795 }
1796 proctor.release();
1797 }
1798}
1799
1800#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1801template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1802inline
1803multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
1804 std::initializer_list<value_type> values,
1805 const COMPARATOR& comparator,
1806 const ALLOCATOR& basicAllocator)
1807: multimap(values.begin(), values.end(), comparator, basicAllocator)
1808{
1809}
1810
1811template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1812inline
1813multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
1814 std::initializer_list<value_type> values,
1815 const ALLOCATOR& basicAllocator)
1816: multimap(values.begin(), values.end(), COMPARATOR(), basicAllocator)
1817{
1818}
1819#endif
1820
1821template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1822inline
1823multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::~multimap()
1824{
1825 clear();
1826}
1827
1828// MANIPULATORS
1829template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1830inline
1831multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>&
1832multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::operator=(const multimap& rhs)
1833{
1834 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &rhs)) {
1835 if (AllocatorTraits::propagate_on_container_copy_assignment::value) {
1836 multimap other(rhs, rhs.nodeFactory().allocator());
1837 quickSwapExchangeAllocators(other);
1838 }
1839 else {
1840 multimap other(rhs, nodeFactory().allocator());
1841 quickSwapRetainAllocators(other);
1842 }
1843 }
1844 return *this;
1845}
1846
1847template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1848inline
1849multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>&
1850multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::operator=(
1851 BloombergLP::bslmf::MovableRef<multimap> rhs)
1853 AllocatorTraits::is_always_equal::value &&
1854 std::is_nothrow_move_assignable<COMPARATOR>::value)
1855{
1856 multimap& lvalue = rhs;
1857
1858 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &lvalue)) {
1859 if (nodeFactory().allocator() == lvalue.nodeFactory().allocator()) {
1860 multimap other(MoveUtil::move(lvalue));
1861 quickSwapRetainAllocators(other);
1862 }
1863 else if (
1864 AllocatorTraits::propagate_on_container_move_assignment::value) {
1865 multimap other(MoveUtil::move(lvalue));
1866 quickSwapExchangeAllocators(other);
1867 }
1868 else {
1869 multimap other(MoveUtil::move(lvalue), nodeFactory().allocator());
1870 quickSwapRetainAllocators(other);
1871 }
1872 }
1873 return *this;
1874}
1875
1876#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1877template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1878inline
1879multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>&
1880multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::operator=(
1881 std::initializer_list<value_type> values)
1882{
1883 clear();
1884 insert(values.begin(), values.end());
1885 return *this;
1886}
1887#endif
1888
1889template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1890inline
1891typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
1892multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::begin() BSLS_KEYWORD_NOEXCEPT
1893{
1894 return iterator(d_tree.firstNode());
1895}
1896
1897template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1898inline
1899typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
1900multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::end() BSLS_KEYWORD_NOEXCEPT
1901{
1902 return iterator(d_tree.sentinel());
1903}
1904
1905template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1906inline
1907typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::reverse_iterator
1908multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::rbegin() BSLS_KEYWORD_NOEXCEPT
1909{
1910 return reverse_iterator(end());
1911}
1912
1913template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1914inline
1915typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::reverse_iterator
1916multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::rend() BSLS_KEYWORD_NOEXCEPT
1917{
1918 return reverse_iterator(begin());
1919}
1920
1921template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1922inline
1923typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
1924multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(const value_type& value)
1925{
1926 bool leftChild;
1927
1928 BloombergLP::bslalg::RbTreeNode *insertLocation =
1929 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
1930 &d_tree,
1931 this->comparator(),
1932 value.first);
1933
1934 BloombergLP::bslalg::RbTreeNode *node =
1935 nodeFactory().emplaceIntoNewNode(value);
1936
1937 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
1938 insertLocation,
1939 leftChild,
1940 node);
1941 return iterator(node);
1942}
1943
1944template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1945template <class INPUT_ITERATOR>
1946inline
1947void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(INPUT_ITERATOR first,
1948 INPUT_ITERATOR last)
1949{
1950 ///Implementation Notes
1951 ///--------------------
1952 // First, consume currently held free nodes. Tf those nodes are
1953 // insufficient *and* one can calculate the remaining number of elements,
1954 // then reserve exactly that many free nodes. There is no more than one
1955 // call to 'reserveNodes' per invocation of this method, hence the use of
1956 // 'BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY'.
1957
1958 const bool canCalculateInsertDistance =
1959 is_convertible<typename
1960 iterator_traits<INPUT_ITERATOR>::iterator_category,
1961 forward_iterator_tag>::value;
1962
1963 while (first != last) {
1964 if (canCalculateInsertDistance
1966 !nodeFactory().hasFreeNodes())) {
1967 const size_type numElements =
1968 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
1969
1970 nodeFactory().reserveNodes(numElements);
1971 }
1972 insert(*first);
1973 ++first;
1974 }
1975}
1976
1977#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
1978template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1979inline
1980void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(const_iterator first,
1981 const_iterator last)
1982{
1983 while (first != last) {
1984 insert(*first);
1985 ++first;
1986 }
1987}
1988#endif
1989
1990template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1991inline
1992typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
1993multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(const_iterator hint,
1994 const value_type& value)
1995{
1996 bool leftChild;
1997
1998 BloombergLP::bslalg::RbTreeNode *hintNode =
1999 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2000
2001 BloombergLP::bslalg::RbTreeNode *insertLocation =
2002 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2003 &d_tree,
2004 this->comparator(),
2005 value.first,
2006 hintNode);
2007
2008 BloombergLP::bslalg::RbTreeNode *node =
2009 nodeFactory().emplaceIntoNewNode(value);
2010
2011 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2012 insertLocation,
2013 leftChild,
2014 node);
2015 return iterator(node);
2016}
2017
2018#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2019template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2020inline
2021void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(
2022 std::initializer_list<value_type> values)
2023{
2024 insert(values.begin(), values.end());
2025}
2026#endif
2027
2028#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
2029// {{{ BEGIN GENERATED CODE
2030// Command line: sim_cpp11_features.pl bslstl_multimap.h
2031#ifndef BSLSTL_MULTIMAP_VARIADIC_LIMIT
2032#define BSLSTL_MULTIMAP_VARIADIC_LIMIT 2
2033#endif
2034#ifndef BSLSTL_MULTIMAP_VARIADIC_LIMIT_B
2035#define BSLSTL_MULTIMAP_VARIADIC_LIMIT_B BSLSTL_MULTIMAP_VARIADIC_LIMIT
2036#endif
2037#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 0
2038template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2039inline
2040typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2041multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace(
2042 )
2043{
2044 bool leftChild;
2045
2046 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2047 );
2048
2049 BloombergLP::bslalg::RbTreeNode *insertLocation =
2050 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2051 &leftChild,
2052 &d_tree,
2053 this->comparator(),
2054 static_cast<const Node *>(node)->value().first);
2055
2056 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2057 insertLocation,
2058 leftChild,
2059 node);
2060 return iterator(node);
2061}
2062#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 0
2063
2064#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 1
2065template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2066template <class Args_1>
2067inline
2068typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2069multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace(
2070 BSLS_COMPILERFEATURES_FORWARD_REF(Args_1) args_1)
2071{
2072 bool leftChild;
2073
2074 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2075 BSLS_COMPILERFEATURES_FORWARD(Args_1, args_1));
2076
2077 BloombergLP::bslalg::RbTreeNode *insertLocation =
2078 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2079 &leftChild,
2080 &d_tree,
2081 this->comparator(),
2082 static_cast<const Node *>(node)->value().first);
2083
2084 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2085 insertLocation,
2086 leftChild,
2087 node);
2088 return iterator(node);
2089}
2090#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 1
2091
2092#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 2
2093template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2094template <class Args_1,
2095 class Args_2>
2096inline
2097typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2098multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace(
2099 BSLS_COMPILERFEATURES_FORWARD_REF(Args_1) args_1,
2100 BSLS_COMPILERFEATURES_FORWARD_REF(Args_2) args_2)
2101{
2102 bool leftChild;
2103
2104 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2105 BSLS_COMPILERFEATURES_FORWARD(Args_1, args_1),
2106 BSLS_COMPILERFEATURES_FORWARD(Args_2, args_2));
2107
2108 BloombergLP::bslalg::RbTreeNode *insertLocation =
2109 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2110 &leftChild,
2111 &d_tree,
2112 this->comparator(),
2113 static_cast<const Node *>(node)->value().first);
2114
2115 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2116 insertLocation,
2117 leftChild,
2118 node);
2119 return iterator(node);
2120}
2121#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 2
2122
2123
2124#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 0
2125template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2126inline
2127typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2128multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint)
2129{
2130 bool leftChild;
2131
2132 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2133 );
2134
2135 BloombergLP::bslalg::RbTreeNode *hintNode =
2136 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2137
2138 BloombergLP::bslalg::RbTreeNode *insertLocation =
2139 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2140 &leftChild,
2141 &d_tree,
2142 this->comparator(),
2143 static_cast<const Node *>(node)->value().first,
2144 hintNode);
2145
2146 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2147 insertLocation,
2148 leftChild,
2149 node);
2150 return iterator(node);
2151}
2152#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 0
2153
2154#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 1
2155template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2156template <class Args_1>
2157inline
2158typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2159multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
2160 BSLS_COMPILERFEATURES_FORWARD_REF(Args_1) args_1)
2161{
2162 bool leftChild;
2163
2164 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2165 BSLS_COMPILERFEATURES_FORWARD(Args_1, args_1));
2166
2167 BloombergLP::bslalg::RbTreeNode *hintNode =
2168 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2169
2170 BloombergLP::bslalg::RbTreeNode *insertLocation =
2171 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2172 &leftChild,
2173 &d_tree,
2174 this->comparator(),
2175 static_cast<const Node *>(node)->value().first,
2176 hintNode);
2177
2178 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2179 insertLocation,
2180 leftChild,
2181 node);
2182 return iterator(node);
2183}
2184#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 1
2185
2186#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 2
2187template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2188template <class Args_1,
2189 class Args_2>
2190inline
2191typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2192multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
2193 BSLS_COMPILERFEATURES_FORWARD_REF(Args_1) args_1,
2194 BSLS_COMPILERFEATURES_FORWARD_REF(Args_2) args_2)
2195{
2196 bool leftChild;
2197
2198 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2199 BSLS_COMPILERFEATURES_FORWARD(Args_1, args_1),
2200 BSLS_COMPILERFEATURES_FORWARD(Args_2, args_2));
2201
2202 BloombergLP::bslalg::RbTreeNode *hintNode =
2203 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2204
2205 BloombergLP::bslalg::RbTreeNode *insertLocation =
2206 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2207 &leftChild,
2208 &d_tree,
2209 this->comparator(),
2210 static_cast<const Node *>(node)->value().first,
2211 hintNode);
2212
2213 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2214 insertLocation,
2215 leftChild,
2216 node);
2217 return iterator(node);
2218}
2219#endif // BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 2
2220
2221#else
2222// The generated code below is a workaround for the absence of perfect
2223// forwarding in some compilers.
2224template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2225template <class... Args>
2226inline
2227typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2228multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace(
2230{
2231 bool leftChild;
2232
2233 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2234 BSLS_COMPILERFEATURES_FORWARD(Args, args)...);
2235
2236 BloombergLP::bslalg::RbTreeNode *insertLocation =
2237 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2238 &leftChild,
2239 &d_tree,
2240 this->comparator(),
2241 static_cast<const Node *>(node)->value().first);
2242
2243 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2244 insertLocation,
2245 leftChild,
2246 node);
2247 return iterator(node);
2248}
2249
2250template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2251template <class... Args>
2252inline
2253typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2254multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
2256{
2257 bool leftChild;
2258
2259 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2260 BSLS_COMPILERFEATURES_FORWARD(Args, args)...);
2261
2262 BloombergLP::bslalg::RbTreeNode *hintNode =
2263 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2264
2265 BloombergLP::bslalg::RbTreeNode *insertLocation =
2266 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2267 &leftChild,
2268 &d_tree,
2269 this->comparator(),
2270 static_cast<const Node *>(node)->value().first,
2271 hintNode);
2272
2273 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2274 insertLocation,
2275 leftChild,
2276 node);
2277 return iterator(node);
2278}
2279
2280// }}} END GENERATED CODE
2281#endif
2282
2283template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2284inline
2285typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2286multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::erase(const_iterator position)
2287{
2288 BSLS_ASSERT_SAFE(position != end());
2289
2290 BloombergLP::bslalg::RbTreeNode *node =
2291 const_cast<BloombergLP::bslalg::RbTreeNode *>(position.node());
2292 BloombergLP::bslalg::RbTreeNode *result =
2293 BloombergLP::bslalg::RbTreeUtil::next(node);
2294 BloombergLP::bslalg::RbTreeUtil::remove(&d_tree, node);
2295 nodeFactory().deleteNode(node);
2296 return iterator(result);
2297}
2298
2299template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2300inline
2301typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2302multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::erase(iterator position)
2303{
2304 return erase(const_iterator(position));
2305}
2306
2307template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2308inline
2309typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::size_type
2310multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::erase(const key_type& key)
2311{
2312 size_type count = 0;
2313 const_iterator first = find(key);
2314
2315 if (first != end()) {
2316 const_iterator last = upper_bound(key);
2317 while (first != last) {
2318 first = erase(first);
2319 ++count;
2320 }
2321 }
2322 return count;
2323}
2324
2325template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2326inline
2327typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2328multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::erase(const_iterator first,
2329 const_iterator last)
2330{
2331 while (first != last) {
2332 first = erase(first);
2333 }
2334 return iterator(last.node());
2335}
2336
2337template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2338inline
2339void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::swap(multimap& other)
2341 AllocatorTraits::is_always_equal::value &&
2342 bsl::is_nothrow_swappable<COMPARATOR>::value)
2343{
2344 if (AllocatorTraits::propagate_on_container_swap::value) {
2345 quickSwapExchangeAllocators(other);
2346 }
2347 else {
2348 // C++11 behavior for member 'swap': undefined for unequal allocators.
2349 // BSLS_ASSERT(allocator() == other.allocator());
2350
2352 nodeFactory().allocator() == other.nodeFactory().allocator())) {
2353 quickSwapRetainAllocators(other);
2354 }
2355 else {
2357
2358 multimap toOtherCopy(MoveUtil::move(*this),
2359 other.nodeFactory().allocator());
2360 multimap toThisCopy( MoveUtil::move(other),
2361 nodeFactory().allocator());
2362
2363 this->quickSwapRetainAllocators(toThisCopy);
2364 other.quickSwapRetainAllocators(toOtherCopy);
2365 }
2366 }
2367}
2368
2369template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2370inline
2371void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::clear() BSLS_KEYWORD_NOEXCEPT
2372{
2373 BSLS_ASSERT_SAFE(d_tree.firstNode());
2374
2375 if (d_tree.rootNode()) {
2376 BSLS_ASSERT_SAFE(0 < d_tree.numNodes());
2377 BSLS_ASSERT_SAFE(d_tree.firstNode() != d_tree.sentinel());
2378
2379 BloombergLP::bslalg::RbTreeUtil::deleteTree(&d_tree, &nodeFactory());
2380 }
2381#if defined(BSLS_ASSERT_SAFE_IS_USED)
2382 else {
2383 BSLS_ASSERT_SAFE(0 == d_tree.numNodes());
2384 BSLS_ASSERT_SAFE(d_tree.firstNode() == d_tree.sentinel());
2385 }
2386#endif
2387}
2388
2389// ACCESSORS
2390template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2391inline
2392typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::allocator_type
2393multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::get_allocator() const
2395{
2396 return nodeFactory().allocator();
2397}
2398
2399template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2400inline
2401typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_iterator
2402multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::begin() const
2404{
2405 return cbegin();
2406}
2407
2408
2409template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2410inline
2411typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_iterator
2412multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::end() const BSLS_KEYWORD_NOEXCEPT
2413{
2414 return cend();
2415}
2416
2417
2418template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2419inline
2420typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_reverse_iterator
2421multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::rbegin() const
2423{
2424 return crbegin();
2425}
2426
2427template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2428inline
2429typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_reverse_iterator
2430multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::rend() const BSLS_KEYWORD_NOEXCEPT
2431{
2432 return crend();
2433}
2434
2435template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2436inline
2437typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_iterator
2438multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::cbegin() const
2440{
2441 return const_iterator(d_tree.firstNode());
2442}
2443
2444template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2445inline
2446typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_iterator
2447multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::cend() const BSLS_KEYWORD_NOEXCEPT
2448{
2449 return const_iterator(d_tree.sentinel());
2450}
2451
2452template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2453inline
2454typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_reverse_iterator
2455multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::crbegin() const
2457{
2458 return const_reverse_iterator(end());
2459}
2460
2461template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2462inline
2463typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_reverse_iterator
2464multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::crend() const
2466{
2467 return const_reverse_iterator(begin());
2468}
2469
2470template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2471inline
2472bool multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::contains(
2473 const key_type& key) const
2474{
2475 return find(key) != end();
2476}
2477
2478// capacity:
2479template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2480inline
2481bool multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::empty() const
2483{
2484 return 0 == d_tree.numNodes();
2485}
2486
2487template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2488inline
2489typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::size_type
2490multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::size() const BSLS_KEYWORD_NOEXCEPT
2491{
2492 return d_tree.numNodes();
2493}
2494
2495template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2496inline
2497typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::size_type
2498multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::max_size() const
2500{
2501 return AllocatorTraits::max_size(get_allocator());
2502}
2503
2504template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2505inline
2506typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::key_compare
2507multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::key_comp() const
2508{
2509 return comparator().keyComparator();
2510}
2511
2512template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2513inline
2514typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::value_compare
2515multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::value_comp() const
2516{
2517 return value_compare(key_comp());
2518}
2519
2520} // close namespace bsl
2521
2522// FREE OPERATORS
2523template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2524inline
2525bool bsl::operator==(
2528{
2529 return BloombergLP::bslalg::RangeCompare::equal(lhs.begin(),
2530 lhs.end(),
2531 lhs.size(),
2532 rhs.begin(),
2533 rhs.end(),
2534 rhs.size());
2535}
2536
2537#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2538template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2539inline
2540bool bsl::operator!=(
2543{
2544 return !(lhs == rhs);
2545}
2546#endif
2547
2548#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2549
2550template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2551inline
2552BloombergLP::bslalg::SynthThreeWayUtil::Result<bsl::pair<const KEY, VALUE>>
2553bsl::operator<=>(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
2554 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs)
2555{
2556 return bsl::lexicographical_compare_three_way(
2557 lhs.begin(),
2558 lhs.end(),
2559 rhs.begin(),
2560 rhs.end(),
2561 BloombergLP::bslalg::SynthThreeWayUtil::compare);
2562}
2563
2564#else
2565
2566template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2567inline
2568bool bsl::operator<(
2571{
2572 return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.begin(),
2573 lhs.end(),
2574 lhs.size(),
2575 rhs.begin(),
2576 rhs.end(),
2577 rhs.size());
2578}
2579
2580template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2581inline
2582bool bsl::operator>(
2585{
2586 return rhs < lhs;
2587}
2588
2589template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2590inline
2591bool bsl::operator<=(
2594{
2595 return !(rhs < lhs);
2596}
2597
2598
2599template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2600inline
2601bool bsl::operator>=(
2604{
2605 return !(lhs < rhs);
2606}
2607
2608#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2609
2610// FREE FUNCTIONS
2611template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2612inline
2616{
2617 a.swap(b);
2618}
2619
2620// ============================================================================
2621// TYPE TRAITS
2622// ============================================================================
2623
2624// Type traits for STL *ordered* containers:
2625//: o An ordered container defines STL iterators.
2626//: o An ordered container uses 'bslma' allocators if the (template parameter)
2627//: type 'ALLOCATOR' is convertible from 'bslma::Allocator *'.
2628
2629
2630
2631namespace bslalg {
2632
2633template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2634struct HasStlIterators<bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR> >
2636{
2637};
2638
2639} // close namespace bslalg
2640
2641namespace bslma {
2642
2643template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2644struct UsesBslmaAllocator<bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR> >
2645 : bsl::is_convertible<Allocator*, ALLOCATOR>
2646{};
2647
2648} // close namespace bslma
2649
2650
2651
2652#else // if ! defined(DEFINED_BSLSTL_MULTIMAP_H)
2653# error Not valid except when included from bslstl_multimap.h
2654#endif // ! defined(COMPILING_BSLSTL_MULTIMAP_H)
2655
2656#endif // ! defined(INCLUDED_BSLSTL_MULTIMAP_CPP03)
2657
2658// ----------------------------------------------------------------------------
2659// Copyright 2019 Bloomberg Finance L.P.
2660//
2661// Licensed under the Apache License, Version 2.0 (the "License");
2662// you may not use this file except in compliance with the License.
2663// You may obtain a copy of the License at
2664//
2665// http://www.apache.org/licenses/LICENSE-2.0
2666//
2667// Unless required by applicable law or agreed to in writing, software
2668// distributed under the License is distributed on an "AS IS" BASIS,
2669// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2670// See the License for the specific language governing permissions and
2671// limitations under the License.
2672// ----------------------------- END-OF-FILE ----------------------------------
2673
2674/** @} */
2675/** @} */
2676/** @} */
Definition bslma_bslallocator.h:580
COMPARATOR comp
Definition bslstl_multimap.h:793
friend class multimap
Definition bslstl_multimap.h:789
value_compare & operator=(const value_compare &rhs)=default
bool operator()(const value_type &x, const value_type &y) const
Definition bslstl_multimap.h:2075
value_type first_argument_type
Definition bslstl_multimap.h:813
value_compare(COMPARATOR comparator)
Definition bslstl_multimap.h:2067
bool result_type
Definition bslstl_multimap.h:808
value_type second_argument_type
Definition bslstl_multimap.h:818
Definition bslstl_multimap.h:665
void swap(multimap &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:1309
AllocatorTraits::difference_type difference_type
Definition bslstl_multimap.h:763
pair< const KEY, VALUE > value_type
Definition bslstl_multimap.h:756
bool contains(const key_type &key) const
Definition bslstl_multimap.h:2823
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_multimap.h:776
size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2849
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this multimap.
Definition bslstl_multimap.h:2841
bsl::pair< iterator, iterator > equal_range(const key_type &key)
Definition bslstl_multimap.h:1429
const value_type & const_reference
Definition bslstl_multimap.h:760
COMPARATOR key_compare
Definition bslstl_multimap.h:757
iterator emplace(Args &&... args)
Definition bslstl_multimap.h:2581
AllocatorTraits::const_pointer const_pointer
Definition bslstl_multimap.h:765
AllocatorTraits::size_type size_type
Definition bslstl_multimap.h:762
iterator insert(const value_type &value)
Definition bslstl_multimap.h:2472
BloombergLP::bslstl::TreeIterator< const value_type, Node, difference_type > const_iterator
Definition bslstl_multimap.h:773
const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2806
iterator erase(const_iterator position)
Definition bslstl_multimap.h:2637
BloombergLP::bslstl::TreeIterator< value_type, Node, difference_type > iterator
Definition bslstl_multimap.h:769
multimap & operator=(const multimap &rhs)
Definition bslstl_multimap.h:2380
bsl::reverse_iterator< iterator > reverse_iterator
Definition bslstl_multimap.h:775
bool empty() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2832
reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2456
ALLOCATOR allocator_type
Definition bslstl_multimap.h:758
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2744
~multimap()
Destroy this object.
Definition bslstl_multimap.h:2371
AllocatorTraits::pointer pointer
Definition bslstl_multimap.h:764
iterator emplace_hint(const_iterator hint, Args &&... args)
Definition bslstl_multimap.h:2606
value_compare value_comp() const
Definition bslstl_multimap.h:2866
iterator lower_bound(const key_type &key)
Definition bslstl_multimap.h:1354
const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2798
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2448
key_compare key_comp() const
Definition bslstl_multimap.h:2858
const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2815
iterator find(const key_type &key)
Definition bslstl_multimap.h:1321
size_type count(const key_type &key) const
Definition bslstl_multimap.h:1598
const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2789
multimap()
Definition bslstl_multimap.h:2157
VALUE mapped_type
Definition bslstl_multimap.h:755
KEY key_type
Definition bslstl_multimap.h:754
iterator upper_bound(const key_type &key)
Definition bslstl_multimap.h:1391
value_type & reference
Definition bslstl_multimap.h:759
reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2464
multimap &operator=(BloombergLP::bslmf::MovableRef< multimap > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2440
Definition bslstl_pair.h:1210
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2012
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:634
#define BSLS_PERFORMANCEHINT_PREDICT_LIKELY(expr)
Definition bsls_performancehint.h:451
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
void swap(OptionValue &a, OptionValue &b)
Definition bdlb_printmethods.h:283
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
T::const_iterator cend(const T &container)
Definition bslstl_iterator.h:1611
bool operator<(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
T::const_reverse_iterator crbegin(const T &container)
Definition bslstl_iterator.h:1597
bool operator>(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator>=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator<=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
deque< VALUE_TYPE, ALLOCATOR >::size_type erase(deque< VALUE_TYPE, ALLOCATOR > &deq, const BDE_OTHER_TYPE &value)
Definition bslstl_deque.h:4126
T::iterator begin(T &container)
Definition bslstl_iterator.h:1495
bool operator==(const memory_resource &a, const memory_resource &b)
T::const_iterator cbegin(const T &container)
Definition bslstl_iterator.h:1553
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
bool operator!=(const memory_resource &a, const memory_resource &b)
T::const_reverse_iterator crend(const T &container)
Definition bslstl_iterator.h:1654
Definition bdlc_flathashmap.h:1805
Definition balxml_encoderoptions.h:68
Definition bdlbb_blob.h:576
Definition bslma_allocatortraits.h:1061
BloombergLP::bslma::AllocatorTraits_ConstPointerType< ALLOCATOR >::type const_pointer
Definition bslma_allocatortraits.h:1152
BloombergLP::bslma::AllocatorTraits_SizeType< ALLOCATOR >::type size_type
Definition bslma_allocatortraits.h:1165
BloombergLP::bslma::AllocatorTraits_PointerType< ALLOCATOR >::type pointer
Definition bslma_allocatortraits.h:1149
BloombergLP::bslma::AllocatorTraits_DifferenceType< ALLOCATOR >::type difference_type
Definition bslma_allocatortraits.h:1162
Definition bslmf_enableif.h:525
Definition bslmf_isconvertible.h:867
t_TYPE type
Definition bslmf_typeidentity.h:216