BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_multiset_cpp03.h
Go to the documentation of this file.
1/// @file bslstl_multiset_cpp03.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_multiset_cpp03.h -*-C++-*-
8
9// Automatically generated file. **DO NOT EDIT**
10
11#ifndef INCLUDED_BSLSTL_MULTISET_CPP03
12#define INCLUDED_BSLSTL_MULTISET_CPP03
13
14/// @defgroup bslstl_multiset_cpp03 bslstl_multiset_cpp03
15/// @brief Provide C++03 implementation for bslstl_multiset.h
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_multiset_cpp03
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_multiset_cpp03-purpose"> Purpose</a>
25/// * <a href="#bslstl_multiset_cpp03-classes"> Classes </a>
26/// * <a href="#bslstl_multiset_cpp03-description"> Description </a>
27///
28/// # Purpose {#bslstl_multiset_cpp03-purpose}
29/// Provide C++03 implementation for bslstl_multiset.h
30///
31/// # Classes {#bslstl_multiset_cpp03-classes}
32/// See bslstl_multiset.h for list of classes
33///
34/// @see bslstl_multiset
35///
36/// # Description {#bslstl_multiset_cpp03-description}
37/// This component is the C++03 translation of a C++11 component,
38/// generated by the 'sim_cpp11_features.pl' program. If the original header
39/// contains any specially delimited regions of C++11 code, then this generated
40/// file contains the C++03 equivalent, i.e., with variadic templates expanded
41/// and rvalue-references replaced by 'bslmf::MovableRef' objects. The header
42/// code in this file is designed to be '#include'd into the original header
43/// when compiling with a C++03 compiler. If there are no specially delimited
44/// regions of C++11 code, then this header contains no code and is not
45/// '#include'd in the original header.
46///
47/// Generated on Thu Mar 19 20:53:55 2026
48/// Command line: sim_cpp11_features.pl bslstl_multiset.h
49/// @}
50/** @} */
51/** @} */
52
53/** @addtogroup bsl
54 * @{
55 */
56/** @addtogroup bslstl
57 * @{
58 */
59/** @addtogroup bslstl_multiset_cpp03
60 * @{
61 */
62
63#ifdef COMPILING_BSLSTL_MULTISET_H
64
65namespace bsl {
66
67 // ==============
68 // class multiset
69 // ==============
70
71/// This class template implements a value-semantic container type holding
72/// an ordered sequence of possibly duplicate keys (of the template
73/// parameter type, `KEY`).
74///
75/// This class:
76/// * supports a complete set of *value-semantic* operations
77/// - except for BDEX serialization
78/// * is *exception-neutral* (agnostic except for the `at` method)
79/// * is *alias-safe*
80/// * is `const` *thread-safe*
81/// For terminology see @ref bsldoc_glossary .
82///
83/// See @ref bslstl_multiset_cpp03
84template <class KEY,
85 class COMPARATOR = std::less<KEY>,
86 class ALLOCATOR = bsl::allocator<KEY> >
87class multiset {
88
89 // PRIVATE TYPES
90
91 /// This typedef is an alias for the type of key objects maintained by
92 /// this multiset.
93 typedef const KEY ValueType;
94
95 /// This typedef is an alias for the comparator used internally by this
96 /// multiset.
97 typedef BloombergLP::bslstl::SetComparator<KEY, COMPARATOR> Comparator;
98
99 /// This typedef is an alias for the type of nodes held by the tree (of
100 /// nodes) used to implement this multiset.
101 typedef BloombergLP::bslstl::TreeNode<KEY> Node;
102
103 /// This typedef is an alias for the factory type used to create and
104 /// destroy `Node` objects.
105 typedef BloombergLP::bslstl::TreeNodePool<KEY, ALLOCATOR> NodeFactory;
106
107 /// This typedef is an alias for the allocator traits type associated
108 /// with this container.
109 typedef bsl::allocator_traits<ALLOCATOR> AllocatorTraits;
110
111 /// This typedef is a convenient alias for the utility associated with
112 /// movable references.
113 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
114
115 /// This class is a wrapper around the comparator and allocator data
116 /// members. It takes advantage of the empty-base optimization (EBO) so
117 /// that if the comparator is stateless, it takes up no space.
118 ///
119 /// TBD: This class should eventually be replaced by the use of a
120 /// general EBO-enabled component that provides a `pair`-like interface
121 /// or a `tuple`.
122 ///
123 /// See @ref bslstl_multiset_cpp03
124 class DataWrapper : public Comparator {
125
126 // DATA
127 NodeFactory d_pool; // pool of 'Node' objects
128
129 private:
130 // NOT IMPLEMENTED
131 DataWrapper(const DataWrapper&);
132 DataWrapper& operator=(const DataWrapper&);
133
134 public:
135 // CREATORS
136
137 /// Create a data wrapper using a copy of the specified `comparator`
138 /// to order keys and a copy of the specified `basicAllocator` to
139 /// supply memory.
140 explicit DataWrapper(const COMPARATOR& comparator,
141 const ALLOCATOR& basicAllocator);
142
143 /// Create a data wrapper initialized to the contents of the `pool`
144 /// associated with the specified `original` data wrapper. The
145 /// comparator and allocator associated with `original` are
146 /// propagated to the new data wrapper. `original` is left in a
147 /// valid but unspecified state.
148 DataWrapper(BloombergLP::bslmf::MovableRef<DataWrapper> original);
149
150 // MANIPULATORS
151
152 /// Return a reference providing modifiable access to the node
153 /// factory associated with this data wrapper.
154 NodeFactory& nodeFactory();
155
156 // ACCESSORS
157
158 /// Return a reference providing non-modifiable access to the node
159 /// factory associated with this data wrapper.
160 const NodeFactory& nodeFactory() const;
161 };
162
163 // DATA
164 DataWrapper d_compAndAlloc;
165 // comparator and pool of 'Node'
166 // objects
167
168 BloombergLP::bslalg::RbTreeAnchor d_tree; // balanced tree of 'Node'
169 // objects
170
171 public:
172 // PUBLIC TYPES
173 typedef KEY key_type;
174 typedef KEY value_type;
175 typedef COMPARATOR key_compare;
176 typedef COMPARATOR value_compare;
177 typedef ALLOCATOR allocator_type;
178 typedef value_type& reference;
179 typedef const value_type& const_reference;
180
181 typedef typename AllocatorTraits::size_type size_type;
183 typedef typename AllocatorTraits::pointer pointer;
185
186 typedef BloombergLP::bslstl::TreeIterator<const value_type,
187 Node,
189 typedef BloombergLP::bslstl::TreeIterator<const value_type,
190 Node,
192 typedef bsl::reverse_iterator<iterator> reverse_iterator;
193 typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;
194
195 private:
196 // PRIVATE MANIPULATORS
197
198 /// Return a reference providing modifiable access to the comparator for
199 /// this multiset.
200 Comparator& comparator();
201
202 /// Return a reference providing modifiable access to the node-allocator
203 /// for this multiset.
204 NodeFactory& nodeFactory();
205
206 /// Efficiently exchange the value, comparator, and allocator of this
207 /// object with the value, comparator, and allocator of the specified
208 /// `other` object. This method provides the no-throw exception-safety
209 /// guarantee, *unless* swapping the (user-supplied) comparator or
210 /// allocator objects can throw.
211 void quickSwapExchangeAllocators(multiset& other);
212
213 /// Efficiently exchange the value and comparator of this object with
214 /// the value and comparator of the specified `other` object. This
215 /// method provides the no-throw exception-safety guarantee, *unless*
216 /// swapping the (user-supplied) comparator objects can throw.
217 ///
218 /// \pre The behavior is undefined unless this object was created with the same
219 /// allocator as `other`.
220 void quickSwapRetainAllocators(multiset& other);
221
222 /// Insert the values between the specified `first` and `last` into an
223 /// initially empty set. If sorted, directly place each value in its
224 /// proper position. If an out of order value is detected, revert to
225 /// normal insertion.
226 template <class INPUT_ITERATOR, class SENTINEL>
227 void constructFromRange(INPUT_ITERATOR first, SENTINEL last);
228
229#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
230 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
231
232 /// Insert the values between the specified `first` and `last` into an
233 /// initially empty set. The specified 'numElements` is used to improve
234 /// performance. If sorted, directly place each value in its proper
235 /// position. If an out of order value is detected, revert to normal insertion.
236 ///
237 /// \pre The behavior is undefined if the iterators support
238 /// the calculation of distance and `numElements` is not the distance
239 /// from `first` to `last`.
240 template <class INPUT_ITERATOR, class SENTINEL>
241 void constructFromRange(INPUT_ITERATOR first,
242 SENTINEL last,
243 size_t numElements);
244#endif
245
246 // Insert the values between `first` and `last` into this map.
247 template <class INPUT_ITERATOR, class SENTINEL>
248 void insertFromRange(INPUT_ITERATOR first,
249 SENTINEL last);
250
251#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
252 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
253
254 /// Insert the values between the specified `first` and `last` into this
255 /// map. The specified `numElements` is used to improve performance.
256 ///
257 /// \pre The behavior is undefined if the iterators support the calculation
258 /// of distance and `numElements` is not the distance from `first` to
259 /// `last`.
260 template <class INPUT_ITERATOR, class SENTINEL>
261 void insertFromRange(INPUT_ITERATOR first,
262 SENTINEL last,
263 size_t numElements);
264#endif
265
266 // PRIVATE ACCESSORS
267
268 /// Return a reference providing non-modifiable access to the comparator
269 /// for this multiset.
270 const Comparator& comparator() const;
271
272 /// Return a reference providing non-modifiable access to the
273 /// node-allocator for this multiset.
274 const NodeFactory& nodeFactory() const;
275
276 public:
277 // CREATORS
278
279 /// Create an empty multiset. Optionally specify a `comparator` used to
280 /// order keys contained in this object. If `comparator` is not
281 /// supplied, a default-constructed object of the (template parameter)
282 /// type `COMPARATOR` is used. Optionally specify the `basicAllocator`
283 /// used to supply memory. If `basicAllocator` is not supplied, a
284 /// default-constructed object of the (template parameter) type
285 /// `ALLOCATOR` is used. If the type `ALLOCATOR` is `bsl::allocator`
286 /// (the default), then `basicAllocator`, if supplied, shall be
287 /// convertible to `bslma::Allocator *`. If the type `ALLOCATOR` is
288 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
289 /// installed default allocator is used.
290 multiset();
291 explicit multiset(const COMPARATOR& comparator,
292 const ALLOCATOR& basicAllocator = ALLOCATOR())
293 : d_compAndAlloc(comparator, basicAllocator)
294 , d_tree()
295 {
296 // The implementation is placed here in the class definition to work
297 // around an AIX compiler bug, where the constructor can fail to
298 // compile because it is unable to find the definition of the default
299 // argument. This occurs when a templatized class wraps around the
300 // container and the comparator is defined after the new class.
301 }
302
303 /// Create an empty multiset that uses the specified `basicAllocator` to
304 /// supply memory. Use a default-constructed object of the (template
305 /// parameter) type `COMPARATOR` to order the keys contained in this multiset.
306 ///
307 /// \note Note that a `bslma::Allocator *` can be supplied for
308 /// `basicAllocator` if the (template parameter) `ALLOCATOR` is
309 /// `bsl::allocator` (the default).
310 explicit multiset(const ALLOCATOR& basicAllocator);
311
312 /// Create a multiset having the same value as the specified `original`
313 /// object. Use a copy of `original.key_comp()` to order the keys
314 /// contained in this multiset. Use the allocator returned by
315 /// 'bsl::allocator_traits<ALLOCATOR>::
316 /// select_on_container_copy_construction(original.get_allocator())' to
317 /// allocate memory. This method requires that the (template parameter)
318 /// type `KEY` be `copy-insertable` into this multiset (see
319 /// {Requirements on `KEY`}).
320 multiset(const multiset& original);
321
322 /// Create a multiset having the same value as that of the specified
323 /// `original` object by moving (in constant time) the contents of
324 /// `original` to the new multiset. Use a copy of `original.key_comp()`
325 /// to order the keys contained in this multiset. The allocator
326 /// associated with `original` is propagated for use in the
327 /// newly-created multiset. `original` is left in a valid but
328 /// unspecified state.
329 multiset(BloombergLP::bslmf::MovableRef<multiset> original); // IMPLICIT
330
331 /// Create a multiset having the same value as the specified `original`
332 /// object that uses the specified `basicAllocator` to supply memory.
333 /// Use a copy of `original.key_comp()` to order the keys contained in
334 /// this multiset. This method requires that the (template parameter)
335 /// type `KEY` be `copy-insertable` into this multiset (see {Requirements on `KEY`}).
336 ///
337 /// \note Note that a `bslma::Allocator *` can be
338 /// supplied for `basicAllocator` if the (template parameter) type
339 /// `ALLOCATOR` is `bsl::allocator` (the default).
340 multiset(const multiset& original,
341 const typename type_identity<ALLOCATOR>::type& basicAllocator);
342
343 /// Create a multiset having the same value as the specified `original`
344 /// object that uses the specified `basicAllocator` to supply memory.
345 /// The contents of `original` are moved (in constant time) to the new
346 /// multiset if `basicAllocator == original.get_allocator()`, and are
347 /// move-inserted (in linear time) using `basicAllocator` otherwise.
348 /// `original` is left in a valid but unspecified state. Use a copy of
349 /// `original.key_comp()` to order the keys contained in this multiset.
350 /// This method requires that the (template parameter) type `KEY` be
351 /// `move-insertable` into this multiset (see {Requirements on `KEY`}).
352 ///
353 /// \note Note that a `bslma::Allocator *` can be supplied for
354 /// `basicAllocator` if the (template parameter) type `ALLOCATOR` is
355 /// `bsl::allocator` (the default).
356 multiset(BloombergLP::bslmf::MovableRef<multiset> original,
357 const typename type_identity<ALLOCATOR>::type& basicAllocator);
358
359 /// Create a multiset, and insert each `value_type` object in the
360 /// sequence starting at the specified `first` element, and ending
361 /// immediately before the specified `last` element. Optionally specify
362 /// a `comparator` used to order keys contained in this object. If
363 /// `comparator` is not supplied, a default-constructed object of the
364 /// (template parameter) type `COMPARATOR` is used. Optionally specify
365 /// a `basicAllocator` used to supply memory. If `basicAllocator` is
366 /// not supplied, a default-constructed object of the (template
367 /// parameter) type `ALLOCATOR` is used. If the type `ALLOCATOR` is
368 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
369 /// installed default allocator is used. If the sequence `first` to
370 /// `last` is ordered according to `comparator`, then this operation has
371 /// `O[N]` complexity, where `N` is the number of elements between
372 /// `first` and `last`, otherwise this operation has `O[N * log(N)]`
373 /// complexity. The (template parameter) type `INPUT_ITERATOR` shall
374 /// meet the requirements of an input iterator defined in the C++11
375 /// standard [24.2.3] providing access to values of a type convertible
376 /// to `value_type`, and `value_type` must be `emplace-constructible`
377 /// from `*i` into this multiset, where `i` is a dereferenceable
378 /// iterator in the range `[first .. last)` (see {Requirements on `KEY`}).
379 ///
380 /// \pre The behavior is undefined unless `first` and `last` refer
381 /// to a sequence of valid values where `first` is at a position at or before `last`.
382 ///
383 /// \note Note that a `bslma::Allocator *` can be supplied for
384 /// `basicAllocator` if the type `ALLOCATOR` is `bsl::allocator` (the
385 /// default).
386 template <class INPUT_ITERATOR>
387 multiset(INPUT_ITERATOR first,
388 INPUT_ITERATOR last,
389 const COMPARATOR& comparator = COMPARATOR(),
390 const ALLOCATOR& basicAllocator = ALLOCATOR());
391 template <class INPUT_ITERATOR>
392 multiset(INPUT_ITERATOR first,
393 INPUT_ITERATOR last,
394 const ALLOCATOR& basicAllocator);
395
396 /// Create a multiset having the (`value_type`) values obtained from the
397 /// specified `range`. Ignore those those objects having a key equivalent
398 /// to that which appears earlier in the sequence. Optionally specify a
399 /// `comparator` used to order key-value pairs contained in this object.
400 /// If `comparator` is not supplied, a default-constructed object of the
401 /// (template parameter) type `COMPARATOR` is used. Optionally specify a
402 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
403 /// supplied, a default-constructed object of the (template parameter) type
404 /// `ALLOCATOR` is used. If the type `ALLOCATOR` is `bsl::allocator`
405 /// (the default), then `basicAllocator`, if supplied, shall be
406 /// convertible to `bslma::Allocator *`. If the type `ALLOCATOR` is
407 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
408 /// installed default allocator is used. If values obtained from `range
409 /// are ordered according to `comparator`, then this operation has `O[N]`
410 /// complexity, where `N` is the number of values in the `range`;
411 /// otherwise, this operation has `O[N * log(N)]` complexity.
412 ///
413 /// \note Note that `RANGE` must meet the requirements of an input range and the values
414 /// from `range` must have a type matching or convertible to `value_type`.
415 template <class RANGE>
417 multiset(
420 const COMPARATOR& comparator = COMPARATOR(),
421 const ALLOCATOR& basicAllocator = ALLOCATOR())
422 : d_compAndAlloc(comparator, basicAllocator)
423 , d_tree()
424 {
425 // Defined inline to avoid Windows errors.
426
427#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
428 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
429 if constexpr (ranges::sized_range<RANGE>) {
430 constructFromRange(bsl::ranges::begin(range),
431 bsl::ranges::end (range),
432 bsl::ranges::size (range));
433 } else // ...
434#endif
435 {
436 constructFromRange(bsl::ranges::begin(range),
437 bsl::ranges::end (range));
438 }
439 }
440
441 template <class RANGE>
443 multiset(from_range_t ,
445 const ALLOCATOR& basicAllocator)
446 : d_compAndAlloc(COMPARATOR(), basicAllocator)
447 , d_tree()
448 {
449 // Defined inline to avoid Windows errors.
450
452 range,
453 COMPARATOR(),
454 nodeFactory().allocator());
455 quickSwapRetainAllocators(other);
456 }
457
458#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
459 /// Create a multiset and insert each `value_type` object in the
460 /// specified `values` initializer list. Optionally specify a
461 /// `comparator` used to order keys contained in this object. If
462 /// `comparator` is not supplied, a default-constructed object of the
463 /// (template parameter) type `COMPARATOR` is used. Optionally specify
464 /// a `basicAllocator` used to supply memory. If `basicAllocator` is
465 /// not supplied, a default-constructed object of the (template
466 /// parameter) type `ALLOCATOR` is used. If the type `ALLOCATOR` is
467 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
468 /// installed default allocator is used. If `values` is ordered
469 /// according to `comparator`, then this operation has `O[N]`
470 /// complexity, where `N` is the number of elements in `values`;
471 /// otherwise this operation has `O[N * log(N)]` complexity. This
472 /// method requires that the (template parameter) type `KEY` be
473 /// `copy-insertable` into this multiset (see {Requirements on `KEY`}).
474 ///
475 /// \note Note that a `bslma::Allocator *` can be supplied for
476 /// `basicAllocator` if the type `ALLOCATOR` is `bsl::allocator` (the
477 /// default).
478 multiset(std::initializer_list<KEY> values,
479 const COMPARATOR& comparator = COMPARATOR(),
480 const ALLOCATOR& basicAllocator = ALLOCATOR());
481 multiset(std::initializer_list<KEY> values,
482 const ALLOCATOR& basicAllocator);
483#endif
484
485 /// Destroy this object.
486 ~multiset();
487
488 // MANIPULATORS
489
490 /// Assign to this object the value and comparator of the specified
491 /// `rhs` object, propagate to this object the allocator of `rhs` if the
492 /// `ALLOCATOR` type has trait @ref propagate_on_container_copy_assignment ,
493 /// and return a reference providing modifiable access to this object.
494 /// If an exception is thrown, `*this` is left in a valid but
495 /// unspecified state. This method requires that the (template
496 /// parameter) type `KEY` be `copy-assignable` and `copy-insertable`
497 /// into this multiset (see {Requirements on `KEY`}).
499
500 multiset& operator=(BloombergLP::bslmf::MovableRef<multiset> rhs)
502 AllocatorTraits::is_always_equal::value
503 && std::is_nothrow_move_assignable<COMPARATOR>::value);
504 // Assign to this object the value and comparator of the specified
505 // 'rhs' object, propagate to this object the allocator of 'rhs' if the
506 // 'ALLOCATOR' type has trait @ref propagate_on_container_move_assignment ,
507 // and return a reference providing modifiable access to this object.
508 // The contents of 'rhs' are moved (in constant time) to this multiset
509 // if 'get_allocator() == rhs.get_allocator()' (after accounting for
510 // the aforementioned trait); otherwise, all elements in this multiset
511 // are either destroyed or move-assigned to and each additional element
512 // in 'rhs' is move-inserted into this multiset. 'rhs' is left in a
513 // valid but unspecified state, and if an exception is thrown, '*this'
514 // is left in a valid but unspecified state. This method requires that
515 // the (template parameter) type 'KEY' be 'move-assignable' and
516 // 'move-insertable' into this multiset (see {Requirements on 'KEY'}).
517
518#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
519 /// Assign to this object the value resulting from first clearing this
520 /// multiset and then inserting each `value_type` object in the
521 /// specified `values` initializer list and return a reference providing
522 /// modifiable access to this object. This method requires that the
523 /// (template parameter) type `KEY` be `copy-insertable` into this
524 /// multiset (see {Requirements on `KEY`}).
525 multiset& operator=(std::initializer_list<KEY> values);
526#endif
527
528 /// Return an iterator providing modifiable access to the first
529 /// `value_type` object in the ordered sequence of `value_type` objects
530 /// maintained by this multiset, or the `end` iterator if this multiset
531 /// is empty.
533
534 /// Return an iterator providing modifiable access to the past-the-end
535 /// element in the ordered sequence of `value_type` objects maintained
536 /// by this multiset.
538
539 /// Return a reverse iterator providing modifiable access to the last
540 /// `value_type` object in the ordered sequence of `value_type` objects
541 /// maintained by this multiset, or `rend` if this multiset is empty.
543
544 /// Return a reverse iterator providing modifiable access to the
545 /// prior-to-the-beginning element in the ordered sequence of
546 /// `value_type` objects maintained by this multiset.
548
549 /// Insert the specified `value` into this multiset. If a range
550 /// containing elements equivalent to `value` already exists, insert the
551 /// `value` at the end of that range. Return an iterator referring to
552 /// the newly inserted `value_type` object. This method requires that
553 /// the (template parameter) type `KEY` be `copy-insertable` into this
554 /// multiset (see {Requirements on `KEY`}).
555 iterator insert(const value_type& value);
556
557 /// Insert the specified `value` into this multiset. If a range
558 /// containing elements equivalent to `value` already exists in this
559 /// multiset, insert `value` at the end of that range. `value` is left
560 /// in a valid but unspecified state. Return an iterator referring to
561 /// the newly inserted `value_type` object in this multiset that is
562 /// equivalent to `value`. This method requires that the (template
563 /// parameter) type `KEY` be `move-insertable` into this multiset (see
564 /// {Requirements on `KEY`}).
565 iterator insert(BloombergLP::bslmf::MovableRef<value_type> value);
566
567 /// Insert the specified `value` into this multiset (in amortized
568 /// constant time if the specified `hint` is a valid immediate successor
569 /// to `value`). Return an iterator referring to the newly inserted
570 /// `value_type` object in this multiset that is equivalent to `value`.
571 /// If `hint` is not a valid immediate successor to `value`, this
572 /// operation has `O[log(N)]` complexity, where `N` is the size of this
573 /// multiset. This method requires that the (template parameter) type
574 /// `KEY` be `copy-insertable` into this multiset (see {Requirements on `KEY`}).
575 ///
576 /// \pre The behavior is undefined unless `hint` is an iterator in
577 /// the range `[begin() .. end()]` (both endpoints included).
578 iterator insert(const_iterator hint, const value_type& value);
579
580 /// Insert the specified `value` into this multiset (in amortized
581 /// constant time if the specified `hint` is a valid immediate successor
582 /// to `value`). `value` is left in a valid but unspecified state.
583 /// Return an iterator referring to the newly inserted `value_type`
584 /// object in this multiset that is equivalent to `value`. If `hint` is
585 /// not a valid immediate successor to `value`, this operation has
586 /// `O[log(N)]` complexity, where `N` is the size of this multiset.
587 /// This method requires that the (template parameter) type `KEY` be
588 /// `move-insertable` into this multiset (see {Requirements on `KEY`}).
589 ///
590 /// \pre The behavior is undefined unless `hint` is an iterator in the range
591 /// `[begin() .. end()]` (both endpoints included).
593 BloombergLP::bslmf::MovableRef<value_type> value);
594
595 /// Insert into this multiset the value of each `value_type` object in
596 /// the range starting at the specified `first` iterator and ending
597 /// immediately before the specified `last` iterator. The (template
598 /// parameter) type `INPUT_ITERATOR` shall meet the requirements of an
599 /// input iterator defined in the C++11 standard [24.2.3] providing
600 /// access to values of a type convertible to `value_type`, and
601 /// `value_type` must be `emplace-constructible` from `*i` into this
602 /// multiset, where `i` is a dereferenceable iterator in the range
603 /// `[first .. last)` (see {Requirements on `KEY`}).
604 ///
605 /// \pre The behavior is undefined unless `first` and `last` refer to a sequence of valid
606 /// values where `first` is at a position at or before `last`.
607 template <class INPUT_ITERATOR>
608 void insert(INPUT_ITERATOR first, INPUT_ITERATOR last);
609
610#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
611 /// Insert into this multiset the value of each `value_type` object in
612 /// the specified `values` initializer list. This method requires that
613 /// the (template parameter) type `KEY` be `copy-insertable` into this
614 /// multiset (see {Requirements on `KEY`}).
615 void insert(std::initializer_list<KEY> values);
616#endif
617
618 /// Insert into this multiset the value of each `value_type` object in the
619 /// specified `range` if the key equivalent of that object is not
620 /// already contained in this map. The (template parameter) type `RANGE`
621 /// must meet the requirements the C++20 standard [ranges] providing access
622 /// to values of a type convertible to `value_type`, and `value_type` must
623 /// be `emplace-constructible` from `*i` into this map, where `i` is a
624 /// dereferenceable iterator obtained from `range` (see {Requirements on `KEY`}).
625 ///
626 /// \pre The behavior is undefined if `range` overlaps this multiset.
627 template <class RANGE>
630 {
631 // Defined inline to avoid Windows errors.
632
633#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
634 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
635 if constexpr (ranges::sized_range<RANGE>) {
636 insertFromRange(bsl::ranges::begin(range),
637 bsl::ranges::end (range),
638 bsl::ranges::size (range));
639 } else // ...
640#endif
641 {
642 insertFromRange(bsl::ranges::begin(range),
643 bsl::ranges::end (range));
644 }
645 }
646
647#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
648// {{{ BEGIN GENERATED CODE
649// Command line: sim_cpp11_features.pl bslstl_multiset.h
650#ifndef BSLSTL_MULTISET_VARIADIC_LIMIT
651#define BSLSTL_MULTISET_VARIADIC_LIMIT 10
652#endif
653#ifndef BSLSTL_MULTISET_VARIADIC_LIMIT_A
654#define BSLSTL_MULTISET_VARIADIC_LIMIT_A BSLSTL_MULTISET_VARIADIC_LIMIT
655#endif
656#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 0
658#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 0
659
660#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 1
661 template <class Args_01>
663#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 1
664
665#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 2
666 template <class Args_01,
667 class Args_02>
669 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02);
670#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 2
671
672#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 3
673 template <class Args_01,
674 class Args_02,
675 class Args_03>
677 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
678 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03);
679#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 3
680
681#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 4
682 template <class Args_01,
683 class Args_02,
684 class Args_03,
685 class Args_04>
687 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
688 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
689 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04);
690#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 4
691
692#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 5
693 template <class Args_01,
694 class Args_02,
695 class Args_03,
696 class Args_04,
697 class Args_05>
699 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
700 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
701 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
702 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05);
703#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 5
704
705#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 6
706 template <class Args_01,
707 class Args_02,
708 class Args_03,
709 class Args_04,
710 class Args_05,
711 class Args_06>
713 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
714 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
715 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
716 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
717 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06);
718#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 6
719
720#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 7
721 template <class Args_01,
722 class Args_02,
723 class Args_03,
724 class Args_04,
725 class Args_05,
726 class Args_06,
727 class Args_07>
729 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
730 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
731 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
732 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
733 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
734 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07);
735#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 7
736
737#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 8
738 template <class Args_01,
739 class Args_02,
740 class Args_03,
741 class Args_04,
742 class Args_05,
743 class Args_06,
744 class Args_07,
745 class Args_08>
747 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
748 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
749 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
750 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
751 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
752 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
753 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08);
754#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 8
755
756#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 9
757 template <class Args_01,
758 class Args_02,
759 class Args_03,
760 class Args_04,
761 class Args_05,
762 class Args_06,
763 class Args_07,
764 class Args_08,
765 class Args_09>
767 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
768 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
769 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
770 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
771 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
772 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
773 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
774 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09);
775#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 9
776
777#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 10
778 template <class Args_01,
779 class Args_02,
780 class Args_03,
781 class Args_04,
782 class Args_05,
783 class Args_06,
784 class Args_07,
785 class Args_08,
786 class Args_09,
787 class Args_10>
789 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
790 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
791 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
792 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
793 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
794 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
795 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
796 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09,
797 BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) args_10);
798#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 10
799
800
801#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 0
803#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 0
804
805#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 1
806 template <class Args_01>
808 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01);
809#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 1
810
811#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 2
812 template <class Args_01,
813 class Args_02>
815 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
816 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02);
817#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 2
818
819#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 3
820 template <class Args_01,
821 class Args_02,
822 class Args_03>
824 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
825 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
826 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03);
827#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 3
828
829#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 4
830 template <class Args_01,
831 class Args_02,
832 class Args_03,
833 class Args_04>
835 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
836 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
837 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
838 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04);
839#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 4
840
841#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 5
842 template <class Args_01,
843 class Args_02,
844 class Args_03,
845 class Args_04,
846 class Args_05>
848 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
849 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
850 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
851 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
852 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05);
853#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 5
854
855#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 6
856 template <class Args_01,
857 class Args_02,
858 class Args_03,
859 class Args_04,
860 class Args_05,
861 class Args_06>
863 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
864 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
865 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
866 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
867 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
868 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06);
869#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 6
870
871#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 7
872 template <class Args_01,
873 class Args_02,
874 class Args_03,
875 class Args_04,
876 class Args_05,
877 class Args_06,
878 class Args_07>
880 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
881 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
882 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
883 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
884 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
885 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
886 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07);
887#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 7
888
889#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 8
890 template <class Args_01,
891 class Args_02,
892 class Args_03,
893 class Args_04,
894 class Args_05,
895 class Args_06,
896 class Args_07,
897 class Args_08>
899 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
900 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
901 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
902 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
903 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
904 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
905 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
906 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08);
907#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 8
908
909#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 9
910 template <class Args_01,
911 class Args_02,
912 class Args_03,
913 class Args_04,
914 class Args_05,
915 class Args_06,
916 class Args_07,
917 class Args_08,
918 class Args_09>
920 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
921 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
922 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
923 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
924 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
925 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
926 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
927 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
928 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09);
929#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 9
930
931#if BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 10
932 template <class Args_01,
933 class Args_02,
934 class Args_03,
935 class Args_04,
936 class Args_05,
937 class Args_06,
938 class Args_07,
939 class Args_08,
940 class Args_09,
941 class Args_10>
943 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
944 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
945 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
946 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
947 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
948 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
949 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
950 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
951 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09,
952 BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) args_10);
953#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_A >= 10
954
955#else
956// The generated code below is a workaround for the absence of perfect
957// forwarding in some compilers.
958 template <class... Args>
960
961 template <class... Args>
964
965// }}} END GENERATED CODE
966#endif
967
968 /// Remove from this multiset the `value_type` object at the specified
969 /// `position`, and return an iterator referring to the element
970 /// immediately following the removed element, or to the past-the-end
971 /// position if the removed element was the last element in the sequence
972 /// of elements maintained by this multiset. This method invalidates
973 /// only iterators and references to the removed element and previously
974 /// saved values of the `end()` iterator.
975 ///
976 /// \pre The behavior is undefined unless `position` refers to a `value_type` object in this multiset.
977 iterator erase(const_iterator position);
978
979 /// Remove from this multiset all `value_type` objects equivalent to the
980 /// specified `key`, if they exist, and return the number of erased
981 /// objects; otherwise, if there are no `value_type` objects equivalent
982 /// to `key`, return 0 with no other effect. This method invalidates
983 /// only iterators and references to the removed element and previously
984 /// saved values of the `end()` iterator.
985 size_type erase(const key_type& key);
986 template <class t_KEY>
987 typename enable_if<
988 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
989 t_KEY>::value &&
990 !is_convertible<BSLS_COMPILERFEATURES_FORWARD_REF(t_KEY),
991 iterator>::value &&
992 !is_convertible<BSLS_COMPILERFEATURES_FORWARD_REF(t_KEY),
993 const_iterator>::value,
995 {
996 // Implemented inline due to Sun CC compilation error.
997 size_type count = 0;
998 iterator it = this->lower_bound(key);
999 while (it != end() && !key_comp()(key, *it)) {
1000 // !(*it > key)
1001 it = erase(it);
1002 count++;
1003 }
1004 return count;
1005 }
1006
1007 /// Remove from this multiset the `value_type` objects starting at the
1008 /// specified `first` position up to, but not including the specified
1009 /// `last` position, and return `last`. This method invalidates only
1010 /// iterators and references to the removed element and previously saved values of the `end()` iterator.
1011 ///
1012 /// \pre The behavior is undefined unless
1013 /// `first` and `last` either refer to elements in this multiset or are
1014 /// the `end` iterator, and the `first` position is at or before the
1015 /// `last` position in the ordered sequence provided by this container.
1017
1019 AllocatorTraits::is_always_equal::value
1020 && bsl::is_nothrow_swappable<COMPARATOR>::value);
1021 // Exchange the value and comparator of this object with those of the
1022 // specified 'other' object; also exchange the allocator of this object
1023 // with that of 'other' if the (template parameter) type 'ALLOCATOR'
1024 // has the @ref propagate_on_container_swap trait, and do not modify
1025 // either allocator otherwise. This method provides the no-throw
1026 // exception-safety guarantee if and only if the (template parameter)
1027 // type 'COMPARATOR' provides a no-throw swap operation, and provides
1028 // the basic exception-safety guarantee otherwise; if an exception is
1029 // thrown, both objects are left in valid but unspecified states. This
1030 // operation has 'O[1]' complexity if either this object was created
1031 // with the same allocator as 'other' or 'ALLOCATOR' has the
1032 // @ref propagate_on_container_swap trait; otherwise, it has 'O[n + m]'
1033 // complexity, where 'n' and 'm' are the number of elements in this
1034 // object and 'other', respectively. Note that this method's support
1035 // for swapping objects created with different allocators when
1036 // 'ALLOCATOR' does not have the @ref propagate_on_container_swap trait is
1037 // a departure from the C++ Standard.
1038
1039 /// Remove all entries from this multiset.
1040 /// \note Note that the multiset is
1041 /// empty after this call, but allocated memory may be retained for
1042 /// future use.
1044
1045 // Turn off complaints about necessarily class-defined methods.
1046 // BDE_VERIFY pragma: push
1047 // BDE_VERIFY pragma: -CD01
1048
1049 /// Return an iterator providing modifiable access to the first
1050 /// `value_type` object in this multiset equivalent to the specified
1051 /// `key`, if such an object exists, and the past-the-end (`end`)
1052 /// iterator otherwise.
1053 ///
1054 /// Note: implemented inline due to Sun CC compilation error.
1055 iterator find(const key_type& key)
1056 {
1057 return iterator(BloombergLP::bslalg::RbTreeUtil::find(
1058 d_tree, this->comparator(), key));
1059 }
1060
1061 /// Return an iterator providing modifiable access to the first
1062 /// `value_type` object in this multiset equivalent to the specified
1063 /// `key`, if such an object exists, and the past-the-end (`end`)
1064 /// iterator otherwise.
1065 ///
1066 /// Note: implemented inline due to Sun CC compilation error.
1067 template <class LOOKUP_KEY>
1068 typename bsl::enable_if<
1069 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1070 LOOKUP_KEY>::value,
1071 iterator>::type
1072 find(const LOOKUP_KEY& key)
1073 {
1074 return iterator(BloombergLP::bslalg::RbTreeUtil::find(
1075 d_tree, this->comparator(), key));
1076 }
1077
1078 /// Return an iterator providing modifiable access to the first (i.e.,
1079 /// ordered least) `value_type` object in this multiset greater-than or
1080 /// equal-to the specified `key`, and the past-the-end iterator if this
1081 /// multiset does not contain a `value_type` object greater-than or equal-to `key`.
1082 ///
1083 /// \note Note that this function returns the *first*
1084 /// position before which a `value_type` object equivalent to `key`
1085 /// could be inserted into the ordered sequence maintained by this
1086 /// multiset, while preserving its ordering.
1087 ///
1088 /// Note: implemented inline due to Sun CC compilation error.
1089 iterator lower_bound(const key_type& key)
1090 {
1091 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1092 d_tree, this->comparator(), key));
1093 }
1094
1095 /// Return an iterator providing modifiable access to the first (i.e.,
1096 /// ordered least) `value_type` object in this multiset greater-than or
1097 /// equal-to the specified `key`, and the past-the-end iterator if this
1098 /// multiset does not contain a `value_type` object greater-than or equal-to `key`.
1099 ///
1100 /// \note Note that this function returns the *first*
1101 /// position before which a `value_type` object equivalent to `key`
1102 /// could be inserted into the ordered sequence maintained by this
1103 /// multiset, while preserving its ordering.
1104 ///
1105 /// Note: implemented inline due to Sun CC compilation error.
1106 template <class LOOKUP_KEY>
1107 typename bsl::enable_if<
1108 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1109 LOOKUP_KEY>::value,
1110 iterator>::type
1111 lower_bound(const LOOKUP_KEY& key)
1112 {
1113 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1114 d_tree, this->comparator(), key));
1115 }
1116
1117 /// Return an iterator providing modifiable access to the first (i.e.,
1118 /// ordered least) `value_type` object in this multiset greater than the
1119 /// specified `key`, and the past-the-end iterator if this multiset does
1120 /// not contain a `value_type` object greater-than `key`.
1121 ///
1122 /// \note Note that this function returns the *last* position before which a
1123 /// `value_type` object equivalent to `key` could be inserted into the
1124 /// ordered sequence maintained by this multiset, while preserving its
1125 /// ordering.
1126 ///
1127 /// Note: implemented inline due to Sun CC compilation error.
1128 iterator upper_bound(const key_type& key)
1129 {
1130 return iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1131 d_tree, this->comparator(), key));
1132 }
1133
1134 /// Return an iterator providing modifiable access to the first (i.e.,
1135 /// ordered least) `value_type` object in this multiset greater than the
1136 /// specified `key`, and the past-the-end iterator if this multiset does
1137 /// not contain a `value_type` object greater-than `key`.
1138 ///
1139 /// \note Note that this function returns the *last* position before which a
1140 /// `value_type` object equivalent to `key` could be inserted into the
1141 /// ordered sequence maintained by this multiset, while preserving its
1142 /// ordering.
1143 ///
1144 /// Note: implemented inline due to Sun CC compilation error.
1145 template <class LOOKUP_KEY>
1146 typename bsl::enable_if<
1147 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1148 LOOKUP_KEY>::value,
1149 iterator>::type
1150 upper_bound(const LOOKUP_KEY& key)
1151 {
1152 return iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1153 d_tree, this->comparator(), key));
1154 }
1155
1156 /// Return a pair of iterators providing modifiable access to the
1157 /// sequence of `value_type` objects in this multiset equivalent to the
1158 /// specified `key`, where the first iterator is positioned at the start
1159 /// of the sequence and the second is positioned one past the end of the
1160 /// sequence. The first returned iterator will be `lower_bound(key)`,
1161 /// the second returned iterator will be `upper_bound(key)`, and, if
1162 /// this multiset contains no `value_type` objects with an equivalent
1163 /// key, then the two returned iterators will have the same value.
1164 ///
1165 /// Note: implemented inline due to Sun CC compilation error.
1166 pair<iterator, iterator> equal_range(const key_type& key)
1167 {
1168 iterator startIt = lower_bound(key);
1169 iterator endIt = startIt;
1170
1171 if (endIt != end() && !comparator()(key, *endIt.node())) {
1172 endIt = upper_bound(key);
1173 }
1174 return pair<iterator, iterator>(startIt, endIt);
1175 }
1176
1177 /// Return a pair of iterators providing modifiable access to the
1178 /// sequence of `value_type` objects in this multiset equivalent to the
1179 /// specified `key`, where the first iterator is positioned at the start
1180 /// of the sequence and the second is positioned one past the end of the
1181 /// sequence. The first returned iterator will be `lower_bound(key)`,
1182 /// the second returned iterator will be `upper_bound(key)`, and, if
1183 /// this multiset contains no `value_type` objects with an equivalent
1184 /// key, then the two returned iterators will have the same value.
1185 ///
1186 /// Note: implemented inline due to Sun CC compilation error.
1187 template <class LOOKUP_KEY>
1188 typename bsl::enable_if<
1189 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1190 LOOKUP_KEY>::value,
1191 pair<iterator, iterator> >::type
1192 equal_range(const LOOKUP_KEY& key)
1193 {
1194 iterator startIt = lower_bound(key);
1195 iterator endIt = startIt;
1196 if (endIt != end() && !comparator()(key, *endIt.node())) {
1197 endIt = upper_bound(key);
1198 }
1199 return pair<iterator, iterator>(startIt, endIt);
1200 }
1201
1202 // BDE_VERIFY pragma: pop
1203
1204 // ACCESSORS
1205
1206 /// Return (a copy of) the allocator used for memory allocation by this
1207 /// multiset.
1209
1210 /// Return an iterator providing non-modifiable access to the first
1211 /// `value_type` object in the ordered sequence of `value_type` objects
1212 /// maintained by this multiset, or the `end` iterator if this multiset
1213 /// is empty.
1215
1216 /// Return an iterator providing non-modifiable access to the
1217 /// past-the-end element in the ordered sequence of `value_type` objects
1218 /// maintained by this multiset.
1220
1221 /// Return a reverse iterator providing non-modifiable access to the
1222 /// last `value_type` object in the ordered sequence of `value_type`
1223 /// objects maintained by this multiset, or `rend` if this multiset is
1224 /// empty.
1226
1227 /// Return a reverse iterator providing non-modifiable access to the
1228 /// prior-to-the-beginning element in the ordered sequence of
1229 /// `value_type` objects maintained by this multiset.
1231
1232 /// Return an iterator providing non-modifiable access to the first
1233 /// `value_type` object in the ordered sequence of `value_type` objects
1234 /// maintained by this multiset, or the `end` iterator if this multiset
1235 /// is empty.
1237
1238 /// Return an iterator providing non-modifiable access to the
1239 /// past-the-end element in the ordered sequence of `value_type` objects
1240 /// maintained by this multiset.
1242
1243 /// Return a reverse iterator providing non-modifiable access to the
1244 /// last `value_type` object in the ordered sequence of `value_type`
1245 /// objects maintained by this multiset, or `rend` if this multiset is
1246 /// empty.
1248
1249 /// Return a reverse iterator providing non-modifiable access to the
1250 /// prior-to-the-beginning element in the ordered sequence of
1251 /// `value_type` objects maintained by this multiset.
1253
1254 /// Return `true` if this map contains an element whose key is
1255 /// equivalent to the specified `key`.
1256 bool contains(const key_type &key) const;
1257
1258 /// Return `true` if this map contains an element whose key is
1259 /// equivalent to the specified `key`.
1260 ///
1261 /// Note: implemented inline due to Sun CC compilation error
1262 template <class LOOKUP_KEY>
1263 typename bsl::enable_if<
1264 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1265 LOOKUP_KEY>::value,
1266 bool>::type
1267 contains(const LOOKUP_KEY& key) const
1268 {
1269 return find(key) != end();
1270 }
1271
1272 /// Return `true` if this multiset contains no elements, and `false`
1273 /// otherwise.
1274 bool empty() const BSLS_KEYWORD_NOEXCEPT;
1275
1276 /// Return the number of elements in this multiset.
1278
1279 /// Return a theoretical upper bound on the largest number of elements that this multiset could possibly hold.
1280 ///
1281 /// \note Note that there is no
1282 /// guarantee that the multiset can successfully grow to the returned
1283 /// size, or even close to that size without running out of resources.
1285
1286 /// Return the key-comparison functor (or function pointer) used by this
1287 /// multiset; if a comparator was supplied at construction, return its
1288 /// value, otherwise return a default constructed @ref key_compare object.
1289 ///
1290 /// \note Note that this comparator compares objects of type `KEY`, which is
1291 /// the type of the `value_type` objects contained in this multiset.
1292 key_compare key_comp() const;
1293
1294 /// Return a functor for comparing two `value_type` objects using `key_comp()`.
1295 ///
1296 /// \note Note that since `value_type` is an alias to `KEY` for
1297 /// `multiset`, this method returns the same functor as `key_comp()`.
1298 value_compare value_comp() const;
1299
1300 // Turn off complaints about necessarily class-defined methods.
1301 // BDE_VERIFY pragma: push
1302 // BDE_VERIFY pragma: -CD01
1303
1304 /// Return an iterator providing non-modifiable access to the first
1305 /// `value_type` object that is equivalent to the specified `key` in
1306 /// ordered sequence maintained by this multiset, if such an object
1307 /// exists, and the past-the-end (`end`) iterator otherwise.
1308 ///
1309 /// Note: implemented inline due to Sun CC compilation error.
1310 const_iterator find(const key_type& key) const
1311 {
1312 return const_iterator(BloombergLP::bslalg::RbTreeUtil::find(
1313 d_tree, this->comparator(), key));
1314 }
1315
1316 /// Return an iterator providing non-modifiable access to the first
1317 /// `value_type` object that is equivalent to the specified `key` in
1318 /// ordered sequence maintained by this multiset, if such an object
1319 /// exists, and the past-the-end (`end`) iterator otherwise.
1320 ///
1321 /// Note: implemented inline due to Sun CC compilation error.
1322 template <class LOOKUP_KEY>
1323 typename bsl::enable_if<
1324 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1325 LOOKUP_KEY>::value,
1326 const_iterator>::type
1327 find(const LOOKUP_KEY& key) const
1328 {
1329 return const_iterator(BloombergLP::bslalg::RbTreeUtil::find(
1330 d_tree, this->comparator(), key));
1331 }
1332
1333 /// Return the number of `value_type` objects within this multiset that
1334 /// are equivalent to the specified `key`.
1335 ///
1336 /// Note: implemented inline due to Sun CC compilation error.
1337 size_type count(const key_type& key) const
1338 {
1339 int count = 0;
1340 const_iterator it = lower_bound(key);
1341
1342 while (it != end() && !comparator()(key, *it.node())) {
1343 ++it;
1344 ++count;
1345 }
1346 return count;
1347 }
1348
1349 /// Return the number of `value_type` objects within this multiset that
1350 /// are equivalent to the specified `key`.
1351 ///
1352 /// Note: implemented inline due to Sun CC compilation error.
1353 template <class LOOKUP_KEY>
1354 typename bsl::enable_if<
1355 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1356 LOOKUP_KEY>::value,
1357 size_type>::type
1358 count(const LOOKUP_KEY& key) const
1359 {
1360 int count = 0;
1361 const_iterator it = lower_bound(key);
1362
1363 while (it != end() && !comparator()(key, *it.node())) {
1364 ++it;
1365 ++count;
1366 }
1367 return count;
1368 }
1369
1370 /// Return an iterator providing non-modifiable access to the first
1371 /// (i.e., ordered least) `value_type` object in this multiset
1372 /// greater-than or equal-to the specified `key`, and the past-the-end
1373 /// iterator if this multiset does not contain a `value_type` greater-than or equal-to `key`.
1374 ///
1375 /// \note Note that this function returns the
1376 /// *first* position before which a `value_type` object equivalent to
1377 /// `key` could be inserted into the ordered sequence maintained by this
1378 /// multiset, while preserving its ordering.
1379 ///
1380 /// Note: implemented inline due to Sun CC compilation error.
1381 const_iterator lower_bound(const key_type& key) const
1382 {
1383 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1384 d_tree, this->comparator(), key));
1385 }
1386
1387 /// Return an iterator providing non-modifiable access to the first
1388 /// (i.e., ordered least) `value_type` object in this multiset
1389 /// greater-than or equal-to the specified `key`, and the past-the-end
1390 /// iterator if this multiset does not contain a `value_type` greater-than or equal-to `key`.
1391 ///
1392 /// \note Note that this function returns the
1393 /// *first* position before which a `value_type` object equivalent to
1394 /// `key` could be inserted into the ordered sequence maintained by this
1395 /// multiset, while preserving its ordering.
1396 ///
1397 /// Note: implemented inline due to Sun CC compilation error.
1398 template <class LOOKUP_KEY>
1399 typename bsl::enable_if<
1400 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1401 LOOKUP_KEY>::value,
1402 const_iterator>::type
1403 lower_bound(const LOOKUP_KEY& key) const
1404 {
1405 return const_iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1406 d_tree, this->comparator(), key));
1407 }
1408
1409 /// Return an iterator providing non-modifiable access to the first
1410 /// (i.e., ordered least) `value_type` object in this multiset greater
1411 /// than the specified `key`, and the past-the-end iterator if this
1412 /// multiset does not contain a `value_type` object greater-than `key`.
1413 ///
1414 /// \note Note that this function returns the *last* position before which a
1415 /// `value_type` object equivalent to `key` could be inserted into the
1416 /// ordered sequence maintained by this multiset, while preserving its
1417 /// ordering.
1418 ///
1419 /// Note: implemented inline due to Sun CC compilation error.
1420 const_iterator upper_bound(const key_type& key) const
1421 {
1422 return const_iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1423 d_tree, this->comparator(), key));
1424 }
1425
1426 /// Return an iterator providing non-modifiable access to the first
1427 /// (i.e., ordered least) `value_type` object in this multiset greater
1428 /// than the specified `key`, and the past-the-end iterator if this
1429 /// multiset does not contain a `value_type` object greater-than `key`.
1430 ///
1431 /// \note Note that this function returns the *last* position before which a
1432 /// `value_type` object equivalent to `key` could be inserted into the
1433 /// ordered sequence maintained by this multiset, while preserving its
1434 /// ordering.
1435 ///
1436 /// Note: implemented inline due to Sun CC compilation error.
1437 template <class LOOKUP_KEY>
1438 typename bsl::enable_if<
1439 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1440 LOOKUP_KEY>::value,
1441 const_iterator>::type
1442 upper_bound(const LOOKUP_KEY& key) const
1443 {
1444 return const_iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1445 d_tree, this->comparator(), key));
1446 }
1447
1448 /// Return a pair of iterators providing non-modifiable access to the
1449 /// sequence of `value_type` objects in this multiset that are
1450 /// equivalent to the specified `key`, where the first iterator is
1451 /// positioned at the start of the sequence, and the second is
1452 /// positioned one past the end of the sequence. The first returned
1453 /// iterator will be `lower_bound(key)`; the second returned iterator
1454 /// will be `upper_bound(key)`; and, if this multiset contains no
1455 /// `value_type` objects equivalent to `key`, then the two returned
1456 /// iterators will have the same value.
1457 ///
1458 /// Note: implemented inline due to Sun CC compilation error.
1459 pair<const_iterator, const_iterator> equal_range(const key_type& key) const
1460 {
1461 const_iterator startIt = lower_bound(key);
1462 const_iterator endIt = startIt;
1463
1464 if (endIt != end() && !comparator()(key, *endIt.node())) {
1465 endIt = upper_bound(key);
1466 }
1467 return pair<const_iterator, const_iterator>(startIt, endIt);
1468 }
1469
1470 /// Return a pair of iterators providing non-modifiable access to the
1471 /// sequence of `value_type` objects in this multiset that are
1472 /// equivalent to the specified `key`, where the first iterator is
1473 /// positioned at the start of the sequence, and the second is
1474 /// positioned one past the end of the sequence. The first returned
1475 /// iterator will be `lower_bound(key)`; the second returned iterator
1476 /// will be `upper_bound(key)`; and, if this multiset contains no
1477 /// `value_type` objects equivalent to `key`, then the two returned
1478 /// iterators will have the same value.
1479 ///
1480 /// Note: implemented inline due to Sun CC compilation error.
1481 template <class LOOKUP_KEY>
1482 typename bsl::enable_if<
1483 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1484 LOOKUP_KEY>::value,
1485 pair<const_iterator, const_iterator> >::type
1486 equal_range(const LOOKUP_KEY& key) const
1487 {
1488 const_iterator startIt = lower_bound(key);
1489 const_iterator endIt = startIt;
1490 if (endIt != end() && !comparator()(key, *endIt.node())) {
1491 endIt = upper_bound(key);
1492 }
1493 return pair<const_iterator, const_iterator>(startIt, endIt);
1494 }
1495
1496 // BDE_VERIFY pragma: pop
1497};
1498
1499#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1500// CLASS TEMPLATE DEDUCTION GUIDES
1501
1502/// Deduce the template parameter `KEY` from the `value_type` of the
1503/// iterators supplied to the constructor of `multiset`. Deduce the
1504/// template parameters `COMPARATOR` and `ALLOCATOR` from the other
1505/// parameters passed to the constructor. This guide does not participate
1506/// unless the supplied (or defaulted) `ALLOCATOR` meets the requirements of
1507/// a standard allocator.
1508template <
1509 class INPUT_ITERATOR,
1510 class KEY =
1511 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1512 class COMPARATOR = std::less<KEY>,
1513 class ALLOCATOR = bsl::allocator<KEY>,
1514 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<COMPARATOR>>,
1515 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1516 >
1517multiset(INPUT_ITERATOR,
1518 INPUT_ITERATOR,
1519 COMPARATOR = COMPARATOR(),
1520 ALLOCATOR = ALLOCATOR())
1521-> multiset<KEY, COMPARATOR, ALLOCATOR>;
1522
1523/// Deduce the template parameter `KEY` from the `value_type` of the
1524/// iterators supplied to the constructor of `multiset`. Deduce the
1525/// template parameter `COMPARATOR` from the other parameter passed to the
1526/// constructor. This deduction guide does not participate unless the
1527/// specified `ALLOC` is convertible to `bsl::allocator<KEY>`.
1528template <
1529 class INPUT_ITERATOR,
1530 class COMPARATOR,
1531 class ALLOC,
1532 class KEY =
1533 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1534 class DEFAULT_ALLOCATOR = bsl::allocator<KEY>,
1535 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1536 >
1537multiset(INPUT_ITERATOR, INPUT_ITERATOR, COMPARATOR, ALLOC *)
1538-> multiset<KEY, COMPARATOR>;
1539
1540/// Deduce the template parameter `KEY` from the `value_type` of the
1541/// iterators supplied to the constructor of `multiset`. Deduce the
1542/// template parameter `ALLOCATOR` from the other parameter passed to the
1543/// constructor. This deduction guide does not participate unless the
1544/// supplied allocator meets the requirements of a standard allocator.
1545template <
1546 class INPUT_ITERATOR,
1547 class ALLOCATOR,
1548 class KEY =
1549 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1550 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1551 >
1552multiset(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR)
1553-> multiset<KEY, std::less<KEY>, ALLOCATOR>;
1554
1555/// Deduce the template parameter `KEY` from the `value_type` of the
1556/// iterators supplied to the constructor of `multiset`. This deduction
1557/// guide does not participate unless the specified `ALLOC` is convertible
1558/// to `bsl::allocator<KEY>`.
1559template <
1560 class INPUT_ITERATOR,
1561 class ALLOC,
1562 class KEY =
1563 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1564 class DEFAULT_ALLOCATOR = bsl::allocator<KEY>,
1565 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1566 >
1567multiset(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
1568-> multiset<KEY>;
1569
1570/// Deduce the template parameter `KEY` from the `value_type` of the
1571/// initializer_list supplied to the constructor of `multiset`. Deduce the
1572/// template parameters `COMPARATOR` and `ALLOCATOR` from the other
1573/// parameters passed to the constructor.
1574template <
1575 class KEY,
1576 class COMPARATOR = std::less<KEY>,
1577 class ALLOCATOR = bsl::allocator<KEY>,
1578 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<COMPARATOR>>,
1579 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1580 >
1581multiset(std::initializer_list<KEY>,
1582 COMPARATOR = COMPARATOR(),
1583 ALLOCATOR = ALLOCATOR())
1584-> multiset<KEY, COMPARATOR, ALLOCATOR>;
1585
1586/// Deduce the template parameter `KEY` from the `value_type` of the
1587/// initializer_list supplied to the constructor of `multiset`. Deduce the
1588/// template parameter `COMPARATOR` from the other parameter passed to the
1589/// constructor. This deduction guide does not participate unless the
1590/// specified `ALLOC` is convertible to `bsl::allocator<KEY>`.
1591template <
1592 class KEY,
1593 class COMPARATOR,
1594 class ALLOC,
1595 class DEFAULT_ALLOCATOR = bsl::allocator<KEY>,
1596 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1597 >
1598multiset(std::initializer_list<KEY>, COMPARATOR, ALLOC *)
1599-> multiset<KEY, COMPARATOR>;
1600
1601/// Deduce the template parameter `KEY` from the `value_type` of the
1602/// initializer_list supplied to the constructor of `multiset`. Deduce the
1603/// template parameter `ALLOCATOR` from the other parameter passed to the
1604/// constructor.
1605template <
1606 class KEY,
1607 class ALLOCATOR,
1608 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1609 >
1610multiset(std::initializer_list<KEY>, ALLOCATOR)
1611-> multiset<KEY, std::less<KEY>, ALLOCATOR>;
1612
1613/// Deduce the template parameter `KEY` from the `value_type` of the
1614/// initializer_list supplied to the constructor of `multiset`. This
1615/// deduction guide does not participate unless the specified `ALLOC` is
1616/// convertible to `bsl::allocator<KEY>`.
1617template <
1618 class KEY,
1619 class ALLOC,
1620 class DEFAULT_ALLOCATOR = bsl::allocator<KEY>,
1621 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1622 >
1623multiset(std::initializer_list<KEY>, ALLOC *)
1624-> multiset<KEY>;
1625
1626#endif
1627
1628// FREE OPERATORS
1629
1630/// Return `true` if the specified `lhs` and `rhs` objects have the same
1631/// value, and `false` otherwise. Two `multiset` objects `lhs` and `rhs`
1632/// have the same value if they have the same number of keys, and each
1633/// element in the ordered sequence of keys of `lhs` has the same value as
1634/// the corresponding element in the ordered sequence of keys of `rhs`.
1635/// This method requires that the (template parameter) type `KEY` be
1636/// `equality-comparable` (see {Requirements on `KEY`}).
1637template <class KEY, class COMPARATOR, class ALLOCATOR>
1638bool operator==(const multiset<KEY, COMPARATOR, ALLOCATOR>& lhs,
1639 const multiset<KEY, COMPARATOR, ALLOCATOR>& rhs);
1640
1641#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1642template <class KEY, class COMPARATOR, class ALLOCATOR>
1643bool operator!=(const multiset<KEY, COMPARATOR, ALLOCATOR>& lhs,
1644 const multiset<KEY, COMPARATOR, ALLOCATOR>& rhs);
1645 // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the
1646 // same value, and 'false' otherwise. Two 'multiset' objects 'lhs' and
1647 // 'rhs' do not have the same value if they do not have the same number of
1648 // keys, or some element in the ordered sequence of keys of 'lhs' does not
1649 // have the same value as the corresponding element in the ordered sequence
1650 // of keys of 'rhs'. This method requires that the (template parameter)
1651 // type 'KEY' be 'equality-comparable' (see {Requirements on 'KEY'}).
1652#endif
1653
1654#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1655
1656/// Perform a lexicographic three-way comparison of the specified `lhs` and
1657/// the specified `rhs` multisets by using the comparison operators of `KEY`
1658/// on each element; return the result of that comparison.
1659template <class KEY, class COMPARATOR, class ALLOCATOR>
1660BloombergLP::bslalg::SynthThreeWayUtil::Result<KEY>
1661operator<=>(const multiset<KEY, COMPARATOR, ALLOCATOR>& lhs,
1662 const multiset<KEY, COMPARATOR, ALLOCATOR>& rhs);
1663
1664#else
1665
1666template <class KEY, class COMPARATOR, class ALLOCATOR>
1667bool operator< (const multiset<KEY, COMPARATOR, ALLOCATOR>& lhs,
1668 const multiset<KEY, COMPARATOR, ALLOCATOR>& rhs);
1669 // Return 'true' if the value of the specified 'lhs' multiset is
1670 // lexicographically less than that of the specified 'rhs' multiset, and
1671 // 'false' otherwise. Given iterators 'i' and 'j' over the respective
1672 // sequences '[lhs.begin() .. lhs.end())' and '[rhs.begin() .. rhs.end())',
1673 // the value of multiset 'lhs' is lexicographically less than that of
1674 // multiset 'rhs' if 'true == *i < *j' for the first pair of corresponding
1675 // iterator positions where '*i < *j' and '*j < *i' are not both 'false'.
1676 // If no such corresponding iterator position exists, the value of 'lhs' is
1677 // lexicographically less than that of 'rhs' if 'lhs.size() < rhs.size()'.
1678 // This method requires that 'operator<', inducing a total order, be
1679 // defined for 'value_type'.
1680
1681template <class KEY, class COMPARATOR, class ALLOCATOR>
1682bool operator> (const multiset<KEY, COMPARATOR, ALLOCATOR>& lhs,
1683 const multiset<KEY, COMPARATOR, ALLOCATOR>& rhs);
1684 // Return 'true' if the value of the specified 'lhs' multiset is
1685 // lexicographically greater than that of the specified 'rhs' multiset, and
1686 // 'false' otherwise. The value of multiset 'lhs' is lexicographically
1687 // greater than that of multiset 'rhs' if 'rhs' is lexicographically less
1688 // than 'lhs' (see 'operator<'). This method requires that 'operator<',
1689 // inducing a total order, be defined for 'value_type'. Note that this
1690 // operator returns 'rhs < lhs'.
1691
1692template <class KEY, class COMPARATOR, class ALLOCATOR>
1693bool operator<=(const multiset<KEY, COMPARATOR, ALLOCATOR>& lhs,
1694 const multiset<KEY, COMPARATOR, ALLOCATOR>& rhs);
1695 // Return 'true' if the value of the specified 'lhs' multiset is
1696 // lexicographically less than or equal to that of the specified 'rhs'
1697 // multiset, and 'false' otherwise. The value of multiset 'lhs' is
1698 // lexicographically less than or equal to that of multiset 'rhs' if 'rhs'
1699 // is not lexicographically less than 'lhs' (see 'operator<'). This method
1700 // requires that 'operator<', inducing a total order, be defined for
1701 // 'value_type'. Note that this operator returns '!(rhs < lhs)'.
1702
1703template <class KEY, class COMPARATOR, class ALLOCATOR>
1704bool operator>=(const multiset<KEY, COMPARATOR, ALLOCATOR>& lhs,
1705 const multiset<KEY, COMPARATOR, ALLOCATOR>& rhs);
1706 // Return 'true' if the value of the specified 'lhs' multiset is
1707 // lexicographically greater than or equal to that of the specified 'rhs'
1708 // multiset, and 'false' otherwise. The value of multiset 'lhs' is
1709 // lexicographically greater than or equal to that of multiset 'rhs' if
1710 // 'lhs' is not lexicographically less than 'rhs' (see 'operator<'). This
1711 // method requires that 'operator<', inducing a total order, be defined for
1712 // 'value_type'. Note that this operator returns '!(lhs < rhs)'.
1713
1714#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1715
1716// FREE FUNCTIONS
1717
1718/// Erase all the elements in the specified multiset `ms` that satisfy the
1719/// specified predicate `predicate`. Return the number of elements erased.
1720template <class KEY, class COMPARATOR, class ALLOCATOR, class PREDICATE>
1721typename multiset<KEY, COMPARATOR, ALLOCATOR>::size_type
1722erase_if(multiset<KEY, COMPARATOR, ALLOCATOR>& ms, PREDICATE predicate);
1723
1724template <class KEY, class COMPARATOR, class ALLOCATOR>
1725void swap(multiset<KEY, COMPARATOR, ALLOCATOR>& a,
1726 multiset<KEY, COMPARATOR, ALLOCATOR>& b)
1728 BSLS_KEYWORD_NOEXCEPT_OPERATOR(a.swap(b)));
1729 // Exchange the value and comparator of the specified 'a' object with those
1730 // of the specified 'b' object; also exchange the allocator of 'a' with
1731 // that of 'b' if the (template parameter) type 'ALLOCATOR' has the
1732 // @ref propagate_on_container_swap trait, and do not modify either allocator
1733 // otherwise. This function provides the no-throw exception-safety
1734 // guarantee if and only if the (template parameter) type 'COMPARATOR'
1735 // provides a no-throw swap operation, and provides the basic
1736 // exception-safety guarantee otherwise; if an exception is thrown, both
1737 // objects are left in valid but unspecified states. This operation has
1738 // 'O[1]' complexity if either 'a' was created with the same allocator as
1739 // 'b' or 'ALLOCATOR' has the @ref propagate_on_container_swap trait;
1740 // otherwise, it has 'O[n + m]' complexity, where 'n' and 'm' are the
1741 // number of elements in 'a' and 'b', respectively. Note that this
1742 // function's support for swapping objects created with different
1743 // allocators when 'ALLOCATOR' does not have the
1744 // @ref propagate_on_container_swap trait is a departure from the C++
1745 // Standard.
1746
1747// ============================================================================
1748// TEMPLATE AND INLINE FUNCTION DEFINITIONS
1749// ============================================================================
1750
1751 // -----------------
1752 // class DataWrapper
1753 // -----------------
1754
1755// CREATORS
1756template <class KEY, class COMPARATOR, class ALLOCATOR>
1757inline
1758multiset<KEY, COMPARATOR, ALLOCATOR>::DataWrapper::DataWrapper(
1759 const COMPARATOR& comparator,
1760 const ALLOCATOR& basicAllocator)
1761: ::bsl::multiset<KEY, COMPARATOR, ALLOCATOR>::Comparator(comparator)
1762, d_pool(basicAllocator)
1763{
1764}
1765
1766template <class KEY, class COMPARATOR, class ALLOCATOR>
1767inline
1768multiset<KEY, COMPARATOR, ALLOCATOR>::DataWrapper::DataWrapper(
1769 BloombergLP::bslmf::MovableRef<DataWrapper> original)
1770: ::bsl::multiset<KEY, COMPARATOR, ALLOCATOR>::Comparator(
1771 MoveUtil::access(original).keyComparator())
1772, d_pool(MoveUtil::move(MoveUtil::access(original).d_pool))
1773{
1774}
1775
1776// MANIPULATORS
1777template <class KEY, class COMPARATOR, class ALLOCATOR>
1778inline
1779typename multiset<KEY, COMPARATOR, ALLOCATOR>::NodeFactory&
1780multiset<KEY, COMPARATOR, ALLOCATOR>::DataWrapper::nodeFactory()
1781{
1782 return d_pool;
1783}
1784
1785// ACCESSORS
1786template <class KEY, class COMPARATOR, class ALLOCATOR>
1787inline
1788const typename multiset<KEY, COMPARATOR, ALLOCATOR>::NodeFactory&
1789multiset<KEY, COMPARATOR, ALLOCATOR>::DataWrapper::nodeFactory() const
1790{
1791 return d_pool;
1792}
1793 // --------------
1794 // class multiset
1795 // --------------
1796
1797// PRIVATE MANIPULATORS
1798template <class KEY, class COMPARATOR, class ALLOCATOR>
1799inline
1800typename multiset<KEY, COMPARATOR, ALLOCATOR>::Comparator&
1801multiset<KEY, COMPARATOR, ALLOCATOR>::comparator()
1802{
1803 return d_compAndAlloc;
1804}
1805
1806template <class KEY, class COMPARATOR, class ALLOCATOR>
1807inline
1808typename multiset<KEY, COMPARATOR, ALLOCATOR>::NodeFactory&
1809multiset<KEY, COMPARATOR, ALLOCATOR>::nodeFactory()
1810{
1811 return d_compAndAlloc.nodeFactory();
1812}
1813
1814template <class KEY, class COMPARATOR, class ALLOCATOR>
1815inline
1816void multiset<KEY, COMPARATOR, ALLOCATOR>::quickSwapExchangeAllocators(
1817 multiset& other)
1818{
1819 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &other.d_tree);
1820 nodeFactory().swapExchangeAllocators(other.nodeFactory());
1821
1822 // 'DataWrapper' contains a 'NodeFactory' object and inherits from
1823 // 'Comparator'. If the empty-base-class optimization has been applied to
1824 // 'Comparator', then we must not call 'swap' on it because
1825 // 'sizeof(Comparator) > 0' and, therefore, we will incorrectly swap bytes
1826 // of the 'NodeFactory' members!
1827
1828 if (sizeof(NodeFactory) != sizeof(DataWrapper)) {
1829 comparator().swap(other.comparator());
1830 }
1831}
1832
1833template <class KEY, class COMPARATOR, class ALLOCATOR>
1834inline
1835void multiset<KEY, COMPARATOR, ALLOCATOR>::quickSwapRetainAllocators(
1836 multiset& other)
1837{
1838 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &other.d_tree);
1839 nodeFactory().swapRetainAllocators(other.nodeFactory());
1840
1841 // See 'quickSwapExchangeAllocators' (above).
1842
1843 if (sizeof(NodeFactory) != sizeof(DataWrapper)) {
1844 comparator().swap(other.comparator());
1845 }
1846}
1847
1848template <class KEY, class COMPARATOR, class ALLOCATOR>
1849template <class INPUT_ITERATOR, class SENTINEL>
1850inline
1851void
1852multiset<KEY, COMPARATOR, ALLOCATOR>::constructFromRange(INPUT_ITERATOR first,
1853 SENTINEL last)
1854{
1855 if (first == last) {
1856 return; // RETURN
1857 }
1858
1860 BloombergLP::bslstl::IteratorUtil::
1861 canCalculateInsertDistance<INPUT_ITERATOR, SENTINEL>()) {
1862 const size_type numElements = static_cast<size_type>(
1863 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
1864 nodeFactory().reserveNodes(numElements);
1865 }
1866
1867 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
1868 &d_tree,
1869 &nodeFactory());
1870
1871 // The following loop guarantees amortized linear time to insert an ordered
1872 // sequence of values (as required by the standard). If the values are
1873 // in sorted order, we are guaranteed the next node can be inserted as the
1874 // right child of the previous node, and can call 'insertAt' without
1875 // 'findUniqueInsertLocation'.
1876
1877 insert(*first);
1878 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
1879
1880 while (++first != last) {
1881
1882 const value_type& value = *first;
1883 if (this->comparator()(value, *prevNode)) {
1884 // The values are not in order, so insert them normally.
1885 insert(value);
1886 insertFromRange(++first, last);
1887 break;
1888 }
1889
1890 if (this->comparator()(*prevNode, value)) {
1891 BloombergLP::bslalg::RbTreeNode *node =
1892 nodeFactory().emplaceIntoNewNode(value);
1893 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
1894 prevNode,
1895 false,
1896 node);
1897 prevNode = node;
1898 }
1899 }
1900
1901 proctor.release();
1902}
1903
1904#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
1905 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
1906
1907template <class KEY, class COMPARATOR, class ALLOCATOR>
1908template <class INPUT_ITERATOR, class SENTINEL>
1909inline
1910void multiset<KEY, COMPARATOR, ALLOCATOR>::constructFromRange(
1911 INPUT_ITERATOR first,
1912 SENTINEL last,
1913 size_t numElements)
1914
1915{
1917 !BloombergLP::bslstl::IteratorUtil
1918 ::canCalculateInsertDistance<INPUT_ITERATOR, SENTINEL>()
1919 || numElements == static_cast<size_type>(
1920 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last))));
1921
1922 if (first == last) {
1923 return; // RETURN
1924 }
1925
1926 if (0 < numElements) {
1927 nodeFactory().reserveNodes(numElements);
1928 }
1929
1930 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
1931 &d_tree,
1932 &nodeFactory());
1933
1934 // The following loop guarantees amortized linear time to insert an ordered
1935 // sequence of values (as required by the standard). If the values are
1936 // in sorted order, we are guaranteed the next node can be inserted as the
1937 // right child of the previous node, and can call 'insertAt' without
1938 // 'findUniqueInsertLocation'.
1939
1940 insert(*first); --numElements;
1941 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
1942
1943 while (++first != last) {
1944
1945 const value_type& value = *first;
1946 if (this->comparator()(value, *prevNode)) {
1947 // The values are not in order, so insert them normally.
1948 insert(value); --numElements;
1949 insertFromRange(++first, last, numElements);
1950 break;
1951 }
1952
1953 if (this->comparator()(*prevNode, value)) {
1954 BloombergLP::bslalg::RbTreeNode *node =
1955 nodeFactory().emplaceIntoNewNode(value);
1956 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
1957 prevNode,
1958 false,
1959 node);
1960 --numElements;
1961 prevNode = node;
1962 }
1963 }
1964
1965 proctor.release();
1966}
1967
1968#endif
1969
1970template <class KEY, class COMPARATOR, class ALLOCATOR>
1971template <class INPUT_ITERATOR, class SENTINEL>
1972inline
1973void
1974multiset<KEY, COMPARATOR, ALLOCATOR>::insertFromRange(INPUT_ITERATOR first,
1975 SENTINEL last)
1976{
1977 ///Implementation Notes
1978 ///--------------------
1979 // First, consume currently held free nodes. Free nodes may be available
1980 // from previous insertions that where skipped due to collisions with
1981 // keys already in the map or from nodes reserved in `constructFromRange`.
1982 //
1983 // If those nodes are insufficient *and* one can calculate the remaining
1984 // number of elements, then reserve exactly that many free nodes. There is
1985 // no more than one call to 'reserveNodes' per invocation of this method,
1986 // hence the use of 'BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY'.
1987 //
1988 // When reserving nodes, we assume the elements remaining to be inserted
1989 // have unique keys that do not duplicate any keys already in the container
1990 // If there are any duplicates, this container will have free nodes on
1991 // return from this method.
1992
1993 while (first != last) {
1994
1995 if (BloombergLP::bslstl::IteratorUtil
1996 ::canCalculateInsertDistance<INPUT_ITERATOR, SENTINEL>()
1998 !nodeFactory().hasFreeNodes())) {
1999 nodeFactory().reserveNodes(
2000 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
2001 }
2002
2003 insert(*first);
2004 ++first;
2005 }
2006}
2007
2008#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
2009 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
2010
2011template <class KEY, class COMPARATOR, class ALLOCATOR>
2012template <class INPUT_ITERATOR, class SENTINEL>
2013inline
2014void multiset<KEY, COMPARATOR, ALLOCATOR>::insertFromRange(
2015 INPUT_ITERATOR first,
2016 SENTINEL last,
2017 size_t numElements)
2018{
2020 !BloombergLP::bslstl::IteratorUtil
2021 ::canCalculateInsertDistance<INPUT_ITERATOR, SENTINEL>()
2022 || numElements == static_cast<size_type>(
2023 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last))));
2024
2025 while (first != last) {
2026
2028 !nodeFactory().hasFreeNodes())) {
2029 nodeFactory().reserveNodes(numElements);
2030 }
2031
2032 insert(*first);
2033 --numElements;
2034 ++first;
2035 }
2036}
2037
2038#endif
2039
2040// PRIVATE ACCESSORS
2041template <class KEY, class COMPARATOR, class ALLOCATOR>
2042inline
2043const typename multiset<KEY, COMPARATOR, ALLOCATOR>::Comparator&
2044multiset<KEY, COMPARATOR, ALLOCATOR>::comparator() const
2045{
2046 return d_compAndAlloc;
2047}
2048
2049template <class KEY, class COMPARATOR, class ALLOCATOR>
2050inline
2051const typename multiset<KEY, COMPARATOR, ALLOCATOR>::NodeFactory&
2052multiset<KEY, COMPARATOR, ALLOCATOR>::nodeFactory() const
2053{
2054 return d_compAndAlloc.nodeFactory();
2055}
2056
2057// CREATORS
2058template <class KEY, class COMPARATOR, class ALLOCATOR>
2059inline
2060multiset<KEY, COMPARATOR, ALLOCATOR>::multiset()
2061: d_compAndAlloc(COMPARATOR(), ALLOCATOR())
2062, d_tree()
2063{
2064}
2065
2066template <class KEY, class COMPARATOR, class ALLOCATOR>
2067inline
2068multiset<KEY, COMPARATOR, ALLOCATOR>::multiset(const ALLOCATOR& basicAllocator)
2069: d_compAndAlloc(COMPARATOR(), basicAllocator)
2070, d_tree()
2071{
2072}
2073
2074template <class KEY, class COMPARATOR, class ALLOCATOR>
2075inline
2076multiset<KEY, COMPARATOR, ALLOCATOR>::multiset(const multiset& original)
2077: d_compAndAlloc(original.comparator().keyComparator(),
2078 AllocatorTraits::select_on_container_copy_construction(
2079 original.nodeFactory().allocator()))
2080, d_tree()
2081{
2082 if (0 < original.size()) {
2083 nodeFactory().reserveNodes(original.size());
2084 BloombergLP::bslalg::RbTreeUtil::copyTree(&d_tree,
2085 original.d_tree,
2086 &nodeFactory());
2087 }
2088}
2089
2090template <class KEY, class COMPARATOR, class ALLOCATOR>
2091inline
2092multiset<KEY, COMPARATOR, ALLOCATOR>::multiset(
2093 BloombergLP::bslmf::MovableRef<multiset> original)
2094: d_compAndAlloc(MoveUtil::move(MoveUtil::access(original).d_compAndAlloc))
2095, d_tree()
2096{
2097 multiset& lvalue = original;
2098 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &lvalue.d_tree);
2099}
2100
2101template <class KEY, class COMPARATOR, class ALLOCATOR>
2102inline
2103multiset<KEY, COMPARATOR, ALLOCATOR>::multiset(const multiset& original,
2104 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2105: d_compAndAlloc(original.comparator().keyComparator(), basicAllocator)
2106, d_tree()
2107{
2108 if (0 < original.size()) {
2109 nodeFactory().reserveNodes(original.size());
2110 BloombergLP::bslalg::RbTreeUtil::copyTree(&d_tree,
2111 original.d_tree,
2112 &nodeFactory());
2113 }
2114}
2115
2116template <class KEY, class COMPARATOR, class ALLOCATOR>
2117inline
2118multiset<KEY, COMPARATOR, ALLOCATOR>::multiset(
2119 BloombergLP::bslmf::MovableRef<multiset> original,
2120 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2121: d_compAndAlloc(MoveUtil::access(original).comparator().keyComparator(),
2122 basicAllocator)
2123, d_tree()
2124{
2125 multiset& lvalue = original;
2126
2128 nodeFactory().allocator() == lvalue.nodeFactory().allocator())) {
2129 d_compAndAlloc.nodeFactory().adopt(
2130 MoveUtil::move(lvalue.d_compAndAlloc.nodeFactory()));
2131 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &lvalue.d_tree);
2132 }
2133 else {
2134 if (0 < lvalue.size()) {
2135 nodeFactory().reserveNodes(lvalue.size());
2136 BloombergLP::bslalg::RbTreeUtil::moveTree(&d_tree,
2137 &lvalue.d_tree,
2138 &nodeFactory(),
2139 &lvalue.nodeFactory());
2140 }
2141 }
2142}
2143
2144template <class KEY, class COMPARATOR, class ALLOCATOR>
2145template <class INPUT_ITERATOR>
2146inline
2147multiset<KEY, COMPARATOR, ALLOCATOR>::multiset(
2148 INPUT_ITERATOR first,
2149 INPUT_ITERATOR last,
2150 const COMPARATOR& comparator,
2151 const ALLOCATOR& basicAllocator)
2152: d_compAndAlloc(comparator, basicAllocator)
2153, d_tree()
2154{
2155 if (first != last) {
2156
2157 const size_type numElements = static_cast<size_type>(
2158 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
2159
2160 if (0 < numElements) {
2161 nodeFactory().reserveNodes(numElements);
2162 }
2163
2164 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
2165 &d_tree,
2166 &nodeFactory());
2167
2168 // The following loop guarantees amortized linear time to insert an
2169 // ordered sequence of values (as required by the standard). If the
2170 // values are in sorted order, we are guaranteed the next node can be
2171 // inserted as the right child of the previous node, and can call
2172 // 'insertAt' without 'findUniqueInsertLocation'.
2173
2174 insert(*first);
2175 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
2176 while (++first != last) {
2177 // The values are not in order, so insert them normally.
2178
2179 const value_type& value = *first;
2180 if (this->comparator()(value, *prevNode)) {
2181 insert(value);
2182 insert(++first, last);
2183 break;
2184 }
2185 BloombergLP::bslalg::RbTreeNode *node =
2186 nodeFactory().emplaceIntoNewNode(value);
2187 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2188 prevNode,
2189 false,
2190 node);
2191 prevNode = node;
2192 }
2193
2194 proctor.release();
2195 }
2196}
2197
2198template <class KEY, class COMPARATOR, class ALLOCATOR>
2199template <class INPUT_ITERATOR>
2200inline
2201multiset<KEY, COMPARATOR, ALLOCATOR>::multiset(
2202 INPUT_ITERATOR first,
2203 INPUT_ITERATOR last,
2204 const ALLOCATOR& basicAllocator)
2205: d_compAndAlloc(COMPARATOR(), basicAllocator)
2206, d_tree()
2207{
2208 if (first != last) {
2209
2210 const size_type numElements = static_cast<size_type>(
2211 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
2212
2213 if (0 < numElements) {
2214 nodeFactory().reserveNodes(numElements);
2215 }
2216
2217 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
2218 &d_tree,
2219 &nodeFactory());
2220
2221 // The following loop guarantees amortized linear time to insert an
2222 // ordered sequence of values (as required by the standard). If the
2223 // values are in sorted order, we are guaranteed the next node can be
2224 // inserted as the right child of the previous node, and can call
2225 // 'insertAt' without 'findUniqueInsertLocation'.
2226
2227 insert(*first);
2228 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
2229 while (++first != last) {
2230 // The values are not in order, so insert them normally.
2231
2232 const value_type& value = *first;
2233 if (this->comparator()(value, *prevNode)) {
2234 insert(value);
2235 insert(++first, last);
2236 break;
2237 }
2238 BloombergLP::bslalg::RbTreeNode *node =
2239 nodeFactory().emplaceIntoNewNode(value);
2240 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2241 prevNode,
2242 false,
2243 node);
2244 prevNode = node;
2245 }
2246
2247 proctor.release();
2248 }
2249}
2250
2251#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2252template <class KEY, class COMPARATOR, class ALLOCATOR>
2253inline
2254multiset<KEY, COMPARATOR, ALLOCATOR>::multiset(
2255 std::initializer_list<KEY> values,
2256 const COMPARATOR& comparator,
2257 const ALLOCATOR& basicAllocator)
2258: multiset(values.begin(), values.end(), comparator, basicAllocator)
2259{
2260}
2261
2262template <class KEY, class COMPARATOR, class ALLOCATOR>
2263inline
2264multiset<KEY, COMPARATOR, ALLOCATOR>::multiset(
2265 std::initializer_list<KEY> values,
2266 const ALLOCATOR& basicAllocator)
2267: multiset(values.begin(), values.end(), COMPARATOR(), basicAllocator)
2268{
2269}
2270#endif
2271
2272template <class KEY, class COMPARATOR, class ALLOCATOR>
2273inline
2274multiset<KEY, COMPARATOR, ALLOCATOR>::~multiset()
2275{
2276 clear();
2277}
2278
2279// MANIPULATORS
2280template <class KEY, class COMPARATOR, class ALLOCATOR>
2281inline
2282multiset<KEY, COMPARATOR, ALLOCATOR>&
2283multiset<KEY, COMPARATOR, ALLOCATOR>::operator=(const multiset& rhs)
2284{
2285 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &rhs)) {
2286 if (AllocatorTraits::propagate_on_container_copy_assignment::value) {
2287 multiset other(rhs, rhs.nodeFactory().allocator());
2288 quickSwapExchangeAllocators(other);
2289 }
2290 else {
2291 multiset other(rhs, nodeFactory().allocator());
2292 quickSwapRetainAllocators(other);
2293 }
2294 }
2295 return *this;
2296}
2297
2298template <class KEY, class COMPARATOR, class ALLOCATOR>
2299inline
2300multiset<KEY, COMPARATOR, ALLOCATOR>&
2301multiset<KEY, COMPARATOR, ALLOCATOR>::operator=(
2302 BloombergLP::bslmf::MovableRef<multiset> rhs)
2304 AllocatorTraits::is_always_equal::value
2305 && std::is_nothrow_move_assignable<COMPARATOR>::value)
2306{
2307 multiset& lvalue = rhs;
2308
2309 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &lvalue)) {
2310 if (nodeFactory().allocator() == lvalue.nodeFactory().allocator()) {
2311 multiset other(MoveUtil::move(lvalue));
2312 quickSwapRetainAllocators(other);
2313 }
2314 else if (
2315 AllocatorTraits::propagate_on_container_move_assignment::value) {
2316 multiset other(MoveUtil::move(lvalue));
2317 quickSwapExchangeAllocators(other);
2318 }
2319 else {
2320 multiset other(MoveUtil::move(lvalue), nodeFactory().allocator());
2321 quickSwapRetainAllocators(other);
2322 }
2323 }
2324 return *this;
2325}
2326
2327#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2328template <class KEY, class COMPARATOR, class ALLOCATOR>
2329inline
2330multiset<KEY, COMPARATOR, ALLOCATOR>&
2331multiset<KEY, COMPARATOR, ALLOCATOR>::operator=(
2332 std::initializer_list<KEY> values)
2333{
2334 clear();
2335 insert(values.begin(), values.end());
2336 return *this;
2337}
2338#endif
2339
2340template <class KEY, class COMPARATOR, class ALLOCATOR>
2341inline
2342typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2343multiset<KEY, COMPARATOR, ALLOCATOR>::begin() BSLS_KEYWORD_NOEXCEPT
2344{
2345 return iterator(d_tree.firstNode());
2346}
2347
2348template <class KEY, class COMPARATOR, class ALLOCATOR>
2349inline
2350typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2351multiset<KEY, COMPARATOR, ALLOCATOR>::end() BSLS_KEYWORD_NOEXCEPT
2352{
2353 return iterator(d_tree.sentinel());
2354}
2355
2356template <class KEY, class COMPARATOR, class ALLOCATOR>
2357inline
2358typename multiset<KEY, COMPARATOR, ALLOCATOR>::reverse_iterator
2359multiset<KEY, COMPARATOR, ALLOCATOR>::rbegin() BSLS_KEYWORD_NOEXCEPT
2360{
2361 return reverse_iterator(end());
2362}
2363
2364template <class KEY, class COMPARATOR, class ALLOCATOR>
2365inline
2366typename multiset<KEY, COMPARATOR, ALLOCATOR>::reverse_iterator
2367multiset<KEY, COMPARATOR, ALLOCATOR>::rend() BSLS_KEYWORD_NOEXCEPT
2368{
2369 return reverse_iterator(begin());
2370}
2371
2372template <class KEY, class COMPARATOR, class ALLOCATOR>
2373inline
2374typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2375multiset<KEY, COMPARATOR, ALLOCATOR>::insert(const value_type& value)
2376{
2377 bool leftChild;
2378
2379 BloombergLP::bslalg::RbTreeNode *insertLocation =
2380 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2381 &d_tree,
2382 this->comparator(),
2383 value);
2384
2385 BloombergLP::bslalg::RbTreeNode *node =
2386 nodeFactory().emplaceIntoNewNode(value);
2387
2388 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2389 insertLocation,
2390 leftChild,
2391 node);
2392 return iterator(node);
2393}
2394
2395template <class KEY, class COMPARATOR, class ALLOCATOR>
2396inline
2397typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2398multiset<KEY, COMPARATOR, ALLOCATOR>::insert(
2399 BloombergLP::bslmf::MovableRef<value_type> value)
2400{
2401 value_type& lvalue = value;
2402 bool leftChild;
2403
2404 BloombergLP::bslalg::RbTreeNode *insertLocation =
2405 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2406 &d_tree,
2407 this->comparator(),
2408 lvalue);
2409
2410 BloombergLP::bslalg::RbTreeNode *node =
2411 nodeFactory().emplaceIntoNewNode(MoveUtil::move(lvalue));
2412
2413 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2414 insertLocation,
2415 leftChild,
2416 node);
2417 return iterator(node);
2418}
2419
2420template <class KEY, class COMPARATOR, class ALLOCATOR>
2421inline
2422typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2423multiset<KEY, COMPARATOR, ALLOCATOR>::insert(const_iterator hint,
2424 const value_type& value)
2425{
2426 bool leftChild;
2427
2428 BloombergLP::bslalg::RbTreeNode *hintNode =
2429 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2430
2431 BloombergLP::bslalg::RbTreeNode *insertLocation =
2432 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2433 &d_tree,
2434 this->comparator(),
2435 value,
2436 hintNode);
2437
2438 BloombergLP::bslalg::RbTreeNode *node =
2439 nodeFactory().emplaceIntoNewNode(value);
2440
2441 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2442 insertLocation,
2443 leftChild,
2444 node);
2445 return iterator(node);
2446}
2447
2448template <class KEY, class COMPARATOR, class ALLOCATOR>
2449inline
2450typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2451multiset<KEY, COMPARATOR, ALLOCATOR>::insert(
2452 const_iterator hint,
2453 BloombergLP::bslmf::MovableRef<value_type> value)
2454{
2455 value_type& lvalue = value;
2456 bool leftChild;
2457
2458 BloombergLP::bslalg::RbTreeNode *hintNode =
2459 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2460
2461 BloombergLP::bslalg::RbTreeNode *insertLocation =
2462 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2463 &d_tree,
2464 this->comparator(),
2465 lvalue,
2466 hintNode);
2467
2468 BloombergLP::bslalg::RbTreeNode *node =
2469 nodeFactory().emplaceIntoNewNode(MoveUtil::move(lvalue));
2470
2471 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2472 insertLocation,
2473 leftChild,
2474 node);
2475 return iterator(node);
2476}
2477
2478template <class KEY, class COMPARATOR, class ALLOCATOR>
2479template <class INPUT_ITERATOR>
2480inline
2481void multiset<KEY, COMPARATOR, ALLOCATOR>::insert(INPUT_ITERATOR first,
2482 INPUT_ITERATOR last)
2483{
2484 ///Implementation Notes
2485 ///--------------------
2486 // First, consume currently held free nodes. If those nodes are
2487 // insufficient *and* one can calculate the remaining number of elements,
2488 // then reserve exactly that many free nodes. There is no more than one
2489 // call to 'reserveNodes' per invocation of this method, hence the use of
2490 // 'BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY'.
2491
2492 while (first != last) {
2493 if (BloombergLP::bslstl::IteratorUtil::
2494 canCalculateInsertDistance<INPUT_ITERATOR,INPUT_ITERATOR>()
2496 !nodeFactory().hasFreeNodes())) {
2497 const size_type numElements = static_cast<size_type>(
2498 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
2499
2500 nodeFactory().reserveNodes(numElements);
2501 }
2502 insert(*first);
2503 ++first;
2504 }
2505}
2506
2507#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2508template <class KEY, class COMPARATOR, class ALLOCATOR>
2509inline
2510void multiset<KEY, COMPARATOR, ALLOCATOR>::insert(
2511 std::initializer_list<KEY> values)
2512{
2513 insert(values.begin(), values.end());
2514}
2515#endif
2516
2517#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
2518// {{{ BEGIN GENERATED CODE
2519// Command line: sim_cpp11_features.pl bslstl_multiset.h
2520#ifndef BSLSTL_MULTISET_VARIADIC_LIMIT
2521#define BSLSTL_MULTISET_VARIADIC_LIMIT 10
2522#endif
2523#ifndef BSLSTL_MULTISET_VARIADIC_LIMIT_B
2524#define BSLSTL_MULTISET_VARIADIC_LIMIT_B BSLSTL_MULTISET_VARIADIC_LIMIT
2525#endif
2526#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 0
2527template <class KEY, class COMPARATOR, class ALLOCATOR>
2528inline
2529typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2530multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2531 )
2532{
2533 bool leftChild;
2534
2535 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2536 );
2537
2538 BloombergLP::bslalg::RbTreeNode *insertLocation =
2539 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2540 &d_tree,
2541 this->comparator(),
2542 static_cast<const Node *>(node)->value());
2543
2544 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2545 insertLocation,
2546 leftChild,
2547 node);
2548 return iterator(node);
2549}
2550#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 0
2551
2552#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 1
2553template <class KEY, class COMPARATOR, class ALLOCATOR>
2554template <class Args_01>
2555inline
2556typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2557multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2558 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01)
2559{
2560 bool leftChild;
2561
2562 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2563 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01));
2564
2565 BloombergLP::bslalg::RbTreeNode *insertLocation =
2566 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2567 &d_tree,
2568 this->comparator(),
2569 static_cast<const Node *>(node)->value());
2570
2571 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2572 insertLocation,
2573 leftChild,
2574 node);
2575 return iterator(node);
2576}
2577#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 1
2578
2579#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 2
2580template <class KEY, class COMPARATOR, class ALLOCATOR>
2581template <class Args_01,
2582 class Args_02>
2583inline
2584typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2585multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2586 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
2587 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02)
2588{
2589 bool leftChild;
2590
2591 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2592 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
2593 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02));
2594
2595 BloombergLP::bslalg::RbTreeNode *insertLocation =
2596 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2597 &d_tree,
2598 this->comparator(),
2599 static_cast<const Node *>(node)->value());
2600
2601 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2602 insertLocation,
2603 leftChild,
2604 node);
2605 return iterator(node);
2606}
2607#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 2
2608
2609#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 3
2610template <class KEY, class COMPARATOR, class ALLOCATOR>
2611template <class Args_01,
2612 class Args_02,
2613 class Args_03>
2614inline
2615typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2616multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2617 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
2618 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
2619 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03)
2620{
2621 bool leftChild;
2622
2623 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2624 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
2625 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
2626 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03));
2627
2628 BloombergLP::bslalg::RbTreeNode *insertLocation =
2629 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2630 &d_tree,
2631 this->comparator(),
2632 static_cast<const Node *>(node)->value());
2633
2634 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2635 insertLocation,
2636 leftChild,
2637 node);
2638 return iterator(node);
2639}
2640#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 3
2641
2642#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 4
2643template <class KEY, class COMPARATOR, class ALLOCATOR>
2644template <class Args_01,
2645 class Args_02,
2646 class Args_03,
2647 class Args_04>
2648inline
2649typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2650multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2651 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
2652 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
2653 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
2654 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04)
2655{
2656 bool leftChild;
2657
2658 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2659 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
2660 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
2661 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
2662 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04));
2663
2664 BloombergLP::bslalg::RbTreeNode *insertLocation =
2665 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2666 &d_tree,
2667 this->comparator(),
2668 static_cast<const Node *>(node)->value());
2669
2670 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2671 insertLocation,
2672 leftChild,
2673 node);
2674 return iterator(node);
2675}
2676#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 4
2677
2678#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 5
2679template <class KEY, class COMPARATOR, class ALLOCATOR>
2680template <class Args_01,
2681 class Args_02,
2682 class Args_03,
2683 class Args_04,
2684 class Args_05>
2685inline
2686typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2687multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2688 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
2689 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
2690 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
2691 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
2692 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05)
2693{
2694 bool leftChild;
2695
2696 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2697 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
2698 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
2699 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
2700 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
2701 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05));
2702
2703 BloombergLP::bslalg::RbTreeNode *insertLocation =
2704 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2705 &d_tree,
2706 this->comparator(),
2707 static_cast<const Node *>(node)->value());
2708
2709 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2710 insertLocation,
2711 leftChild,
2712 node);
2713 return iterator(node);
2714}
2715#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 5
2716
2717#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 6
2718template <class KEY, class COMPARATOR, class ALLOCATOR>
2719template <class Args_01,
2720 class Args_02,
2721 class Args_03,
2722 class Args_04,
2723 class Args_05,
2724 class Args_06>
2725inline
2726typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2727multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2728 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
2729 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
2730 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
2731 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
2732 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
2733 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06)
2734{
2735 bool leftChild;
2736
2737 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2738 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
2739 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
2740 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
2741 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
2742 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
2743 BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06));
2744
2745 BloombergLP::bslalg::RbTreeNode *insertLocation =
2746 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2747 &d_tree,
2748 this->comparator(),
2749 static_cast<const Node *>(node)->value());
2750
2751 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2752 insertLocation,
2753 leftChild,
2754 node);
2755 return iterator(node);
2756}
2757#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 6
2758
2759#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 7
2760template <class KEY, class COMPARATOR, class ALLOCATOR>
2761template <class Args_01,
2762 class Args_02,
2763 class Args_03,
2764 class Args_04,
2765 class Args_05,
2766 class Args_06,
2767 class Args_07>
2768inline
2769typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2770multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2771 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
2772 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
2773 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
2774 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
2775 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
2776 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
2777 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07)
2778{
2779 bool leftChild;
2780
2781 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2782 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
2783 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
2784 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
2785 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
2786 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
2787 BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
2788 BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07));
2789
2790 BloombergLP::bslalg::RbTreeNode *insertLocation =
2791 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2792 &d_tree,
2793 this->comparator(),
2794 static_cast<const Node *>(node)->value());
2795
2796 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2797 insertLocation,
2798 leftChild,
2799 node);
2800 return iterator(node);
2801}
2802#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 7
2803
2804#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 8
2805template <class KEY, class COMPARATOR, class ALLOCATOR>
2806template <class Args_01,
2807 class Args_02,
2808 class Args_03,
2809 class Args_04,
2810 class Args_05,
2811 class Args_06,
2812 class Args_07,
2813 class Args_08>
2814inline
2815typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2816multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2817 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
2818 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
2819 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
2820 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
2821 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
2822 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
2823 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
2824 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08)
2825{
2826 bool leftChild;
2827
2828 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2829 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
2830 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
2831 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
2832 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
2833 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
2834 BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
2835 BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07),
2836 BSLS_COMPILERFEATURES_FORWARD(Args_08,args_08));
2837
2838 BloombergLP::bslalg::RbTreeNode *insertLocation =
2839 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2840 &d_tree,
2841 this->comparator(),
2842 static_cast<const Node *>(node)->value());
2843
2844 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2845 insertLocation,
2846 leftChild,
2847 node);
2848 return iterator(node);
2849}
2850#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 8
2851
2852#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 9
2853template <class KEY, class COMPARATOR, class ALLOCATOR>
2854template <class Args_01,
2855 class Args_02,
2856 class Args_03,
2857 class Args_04,
2858 class Args_05,
2859 class Args_06,
2860 class Args_07,
2861 class Args_08,
2862 class Args_09>
2863inline
2864typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2865multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2866 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
2867 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
2868 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
2869 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
2870 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
2871 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
2872 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
2873 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
2874 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09)
2875{
2876 bool leftChild;
2877
2878 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2879 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
2880 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
2881 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
2882 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
2883 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
2884 BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
2885 BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07),
2886 BSLS_COMPILERFEATURES_FORWARD(Args_08,args_08),
2887 BSLS_COMPILERFEATURES_FORWARD(Args_09,args_09));
2888
2889 BloombergLP::bslalg::RbTreeNode *insertLocation =
2890 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2891 &d_tree,
2892 this->comparator(),
2893 static_cast<const Node *>(node)->value());
2894
2895 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2896 insertLocation,
2897 leftChild,
2898 node);
2899 return iterator(node);
2900}
2901#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 9
2902
2903#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 10
2904template <class KEY, class COMPARATOR, class ALLOCATOR>
2905template <class Args_01,
2906 class Args_02,
2907 class Args_03,
2908 class Args_04,
2909 class Args_05,
2910 class Args_06,
2911 class Args_07,
2912 class Args_08,
2913 class Args_09,
2914 class Args_10>
2915inline
2916typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2917multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
2918 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
2919 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
2920 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
2921 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
2922 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
2923 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
2924 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
2925 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
2926 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09,
2927 BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) args_10)
2928{
2929 bool leftChild;
2930
2931 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2932 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
2933 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
2934 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
2935 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
2936 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
2937 BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
2938 BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07),
2939 BSLS_COMPILERFEATURES_FORWARD(Args_08,args_08),
2940 BSLS_COMPILERFEATURES_FORWARD(Args_09,args_09),
2941 BSLS_COMPILERFEATURES_FORWARD(Args_10,args_10));
2942
2943 BloombergLP::bslalg::RbTreeNode *insertLocation =
2944 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2945 &d_tree,
2946 this->comparator(),
2947 static_cast<const Node *>(node)->value());
2948
2949 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2950 insertLocation,
2951 leftChild,
2952 node);
2953 return iterator(node);
2954}
2955#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 10
2956
2957
2958#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 0
2959template <class KEY, class COMPARATOR, class ALLOCATOR>
2960inline
2961typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2962multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint)
2963{
2964 bool leftChild;
2965
2966 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2967 );
2968
2969 BloombergLP::bslalg::RbTreeNode *hintNode =
2970 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2971
2972 BloombergLP::bslalg::RbTreeNode *insertLocation =
2973 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2974 &d_tree,
2975 this->comparator(),
2976 static_cast<const Node *>(node)->value(),
2977 hintNode);
2978
2979 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2980 insertLocation,
2981 leftChild,
2982 node);
2983 return iterator(node);
2984}
2985#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 0
2986
2987#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 1
2988template <class KEY, class COMPARATOR, class ALLOCATOR>
2989template <class Args_01>
2990inline
2991typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
2992multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
2993 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01)
2994{
2995 bool leftChild;
2996
2997 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2998 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01));
2999
3000 BloombergLP::bslalg::RbTreeNode *hintNode =
3001 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3002
3003 BloombergLP::bslalg::RbTreeNode *insertLocation =
3004 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3005 &d_tree,
3006 this->comparator(),
3007 static_cast<const Node *>(node)->value(),
3008 hintNode);
3009
3010 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3011 insertLocation,
3012 leftChild,
3013 node);
3014 return iterator(node);
3015}
3016#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 1
3017
3018#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 2
3019template <class KEY, class COMPARATOR, class ALLOCATOR>
3020template <class Args_01,
3021 class Args_02>
3022inline
3023typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3024multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
3025 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
3026 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02)
3027{
3028 bool leftChild;
3029
3030 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3031 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
3032 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02));
3033
3034 BloombergLP::bslalg::RbTreeNode *hintNode =
3035 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3036
3037 BloombergLP::bslalg::RbTreeNode *insertLocation =
3038 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3039 &d_tree,
3040 this->comparator(),
3041 static_cast<const Node *>(node)->value(),
3042 hintNode);
3043
3044 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3045 insertLocation,
3046 leftChild,
3047 node);
3048 return iterator(node);
3049}
3050#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 2
3051
3052#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 3
3053template <class KEY, class COMPARATOR, class ALLOCATOR>
3054template <class Args_01,
3055 class Args_02,
3056 class Args_03>
3057inline
3058typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3059multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
3060 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
3061 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
3062 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03)
3063{
3064 bool leftChild;
3065
3066 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3067 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
3068 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
3069 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03));
3070
3071 BloombergLP::bslalg::RbTreeNode *hintNode =
3072 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3073
3074 BloombergLP::bslalg::RbTreeNode *insertLocation =
3075 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3076 &d_tree,
3077 this->comparator(),
3078 static_cast<const Node *>(node)->value(),
3079 hintNode);
3080
3081 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3082 insertLocation,
3083 leftChild,
3084 node);
3085 return iterator(node);
3086}
3087#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 3
3088
3089#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 4
3090template <class KEY, class COMPARATOR, class ALLOCATOR>
3091template <class Args_01,
3092 class Args_02,
3093 class Args_03,
3094 class Args_04>
3095inline
3096typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3097multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
3098 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
3099 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
3100 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
3101 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04)
3102{
3103 bool leftChild;
3104
3105 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3106 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
3107 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
3108 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
3109 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04));
3110
3111 BloombergLP::bslalg::RbTreeNode *hintNode =
3112 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3113
3114 BloombergLP::bslalg::RbTreeNode *insertLocation =
3115 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3116 &d_tree,
3117 this->comparator(),
3118 static_cast<const Node *>(node)->value(),
3119 hintNode);
3120
3121 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3122 insertLocation,
3123 leftChild,
3124 node);
3125 return iterator(node);
3126}
3127#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 4
3128
3129#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 5
3130template <class KEY, class COMPARATOR, class ALLOCATOR>
3131template <class Args_01,
3132 class Args_02,
3133 class Args_03,
3134 class Args_04,
3135 class Args_05>
3136inline
3137typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3138multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
3139 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
3140 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
3141 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
3142 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
3143 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05)
3144{
3145 bool leftChild;
3146
3147 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3148 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
3149 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
3150 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
3151 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
3152 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05));
3153
3154 BloombergLP::bslalg::RbTreeNode *hintNode =
3155 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3156
3157 BloombergLP::bslalg::RbTreeNode *insertLocation =
3158 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3159 &d_tree,
3160 this->comparator(),
3161 static_cast<const Node *>(node)->value(),
3162 hintNode);
3163
3164 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3165 insertLocation,
3166 leftChild,
3167 node);
3168 return iterator(node);
3169}
3170#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 5
3171
3172#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 6
3173template <class KEY, class COMPARATOR, class ALLOCATOR>
3174template <class Args_01,
3175 class Args_02,
3176 class Args_03,
3177 class Args_04,
3178 class Args_05,
3179 class Args_06>
3180inline
3181typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3182multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
3183 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
3184 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
3185 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
3186 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
3187 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
3188 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06)
3189{
3190 bool leftChild;
3191
3192 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3193 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
3194 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
3195 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
3196 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
3197 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
3198 BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06));
3199
3200 BloombergLP::bslalg::RbTreeNode *hintNode =
3201 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3202
3203 BloombergLP::bslalg::RbTreeNode *insertLocation =
3204 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3205 &d_tree,
3206 this->comparator(),
3207 static_cast<const Node *>(node)->value(),
3208 hintNode);
3209
3210 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3211 insertLocation,
3212 leftChild,
3213 node);
3214 return iterator(node);
3215}
3216#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 6
3217
3218#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 7
3219template <class KEY, class COMPARATOR, class ALLOCATOR>
3220template <class Args_01,
3221 class Args_02,
3222 class Args_03,
3223 class Args_04,
3224 class Args_05,
3225 class Args_06,
3226 class Args_07>
3227inline
3228typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3229multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
3230 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
3231 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
3232 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
3233 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
3234 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
3235 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
3236 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07)
3237{
3238 bool leftChild;
3239
3240 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3241 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
3242 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
3243 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
3244 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
3245 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
3246 BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
3247 BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07));
3248
3249 BloombergLP::bslalg::RbTreeNode *hintNode =
3250 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3251
3252 BloombergLP::bslalg::RbTreeNode *insertLocation =
3253 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3254 &d_tree,
3255 this->comparator(),
3256 static_cast<const Node *>(node)->value(),
3257 hintNode);
3258
3259 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3260 insertLocation,
3261 leftChild,
3262 node);
3263 return iterator(node);
3264}
3265#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 7
3266
3267#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 8
3268template <class KEY, class COMPARATOR, class ALLOCATOR>
3269template <class Args_01,
3270 class Args_02,
3271 class Args_03,
3272 class Args_04,
3273 class Args_05,
3274 class Args_06,
3275 class Args_07,
3276 class Args_08>
3277inline
3278typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3279multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
3280 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
3281 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
3282 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
3283 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
3284 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
3285 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
3286 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
3287 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08)
3288{
3289 bool leftChild;
3290
3291 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3292 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
3293 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
3294 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
3295 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
3296 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
3297 BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
3298 BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07),
3299 BSLS_COMPILERFEATURES_FORWARD(Args_08,args_08));
3300
3301 BloombergLP::bslalg::RbTreeNode *hintNode =
3302 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3303
3304 BloombergLP::bslalg::RbTreeNode *insertLocation =
3305 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3306 &d_tree,
3307 this->comparator(),
3308 static_cast<const Node *>(node)->value(),
3309 hintNode);
3310
3311 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3312 insertLocation,
3313 leftChild,
3314 node);
3315 return iterator(node);
3316}
3317#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 8
3318
3319#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 9
3320template <class KEY, class COMPARATOR, class ALLOCATOR>
3321template <class Args_01,
3322 class Args_02,
3323 class Args_03,
3324 class Args_04,
3325 class Args_05,
3326 class Args_06,
3327 class Args_07,
3328 class Args_08,
3329 class Args_09>
3330inline
3331typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3332multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
3333 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
3334 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
3335 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
3336 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
3337 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
3338 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
3339 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
3340 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
3341 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09)
3342{
3343 bool leftChild;
3344
3345 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3346 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
3347 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
3348 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
3349 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
3350 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
3351 BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
3352 BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07),
3353 BSLS_COMPILERFEATURES_FORWARD(Args_08,args_08),
3354 BSLS_COMPILERFEATURES_FORWARD(Args_09,args_09));
3355
3356 BloombergLP::bslalg::RbTreeNode *hintNode =
3357 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3358
3359 BloombergLP::bslalg::RbTreeNode *insertLocation =
3360 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3361 &d_tree,
3362 this->comparator(),
3363 static_cast<const Node *>(node)->value(),
3364 hintNode);
3365
3366 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3367 insertLocation,
3368 leftChild,
3369 node);
3370 return iterator(node);
3371}
3372#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 9
3373
3374#if BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 10
3375template <class KEY, class COMPARATOR, class ALLOCATOR>
3376template <class Args_01,
3377 class Args_02,
3378 class Args_03,
3379 class Args_04,
3380 class Args_05,
3381 class Args_06,
3382 class Args_07,
3383 class Args_08,
3384 class Args_09,
3385 class Args_10>
3386inline
3387typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3388multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
3389 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
3390 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
3391 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
3392 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
3393 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
3394 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
3395 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
3396 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
3397 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09,
3398 BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) args_10)
3399{
3400 bool leftChild;
3401
3402 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3403 BSLS_COMPILERFEATURES_FORWARD(Args_01,args_01),
3404 BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
3405 BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
3406 BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
3407 BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
3408 BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
3409 BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07),
3410 BSLS_COMPILERFEATURES_FORWARD(Args_08,args_08),
3411 BSLS_COMPILERFEATURES_FORWARD(Args_09,args_09),
3412 BSLS_COMPILERFEATURES_FORWARD(Args_10,args_10));
3413
3414 BloombergLP::bslalg::RbTreeNode *hintNode =
3415 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3416
3417 BloombergLP::bslalg::RbTreeNode *insertLocation =
3418 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3419 &d_tree,
3420 this->comparator(),
3421 static_cast<const Node *>(node)->value(),
3422 hintNode);
3423
3424 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3425 insertLocation,
3426 leftChild,
3427 node);
3428 return iterator(node);
3429}
3430#endif // BSLSTL_MULTISET_VARIADIC_LIMIT_B >= 10
3431
3432#else
3433// The generated code below is a workaround for the absence of perfect
3434// forwarding in some compilers.
3435template <class KEY, class COMPARATOR, class ALLOCATOR>
3436template <class... Args>
3437inline
3438typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3439multiset<KEY, COMPARATOR, ALLOCATOR>::emplace(
3441{
3442 bool leftChild;
3443
3444 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3445 BSLS_COMPILERFEATURES_FORWARD(Args,args)...);
3446
3447 BloombergLP::bslalg::RbTreeNode *insertLocation =
3448 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3449 &d_tree,
3450 this->comparator(),
3451 static_cast<const Node *>(node)->value());
3452
3453 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3454 insertLocation,
3455 leftChild,
3456 node);
3457 return iterator(node);
3458}
3459
3460template <class KEY, class COMPARATOR, class ALLOCATOR>
3461template <class... Args>
3462inline
3463typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3464multiset<KEY, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
3466{
3467 bool leftChild;
3468
3469 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3470 BSLS_COMPILERFEATURES_FORWARD(Args,args)...);
3471
3472 BloombergLP::bslalg::RbTreeNode *hintNode =
3473 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3474
3475 BloombergLP::bslalg::RbTreeNode *insertLocation =
3476 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
3477 &d_tree,
3478 this->comparator(),
3479 static_cast<const Node *>(node)->value(),
3480 hintNode);
3481
3482 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3483 insertLocation,
3484 leftChild,
3485 node);
3486 return iterator(node);
3487}
3488// }}} END GENERATED CODE
3489#endif
3490
3491template <class KEY, class COMPARATOR, class ALLOCATOR>
3492inline
3493typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3494multiset<KEY, COMPARATOR, ALLOCATOR>::erase(const_iterator position)
3495{
3496 BSLS_ASSERT_SAFE(position != end());
3497
3498 BloombergLP::bslalg::RbTreeNode *node =
3499 const_cast<BloombergLP::bslalg::RbTreeNode *>(position.node());
3500 BloombergLP::bslalg::RbTreeNode *result =
3501 BloombergLP::bslalg::RbTreeUtil::next(node);
3502 BloombergLP::bslalg::RbTreeUtil::remove(&d_tree, node);
3503 nodeFactory().deleteNode(node);
3504 return iterator(result);
3505}
3506
3507template <class KEY, class COMPARATOR, class ALLOCATOR>
3508inline
3509typename multiset<KEY, COMPARATOR, ALLOCATOR>::size_type
3510multiset<KEY, COMPARATOR, ALLOCATOR>::erase(const key_type& key)
3511{
3512 size_type count = 0;
3513 const_iterator first = find(key);
3514 if (first != end()) {
3515 const_iterator last = upper_bound(key);
3516 while (first != last) {
3517 first = erase(first);
3518 ++count;
3519 }
3520 }
3521 return count;
3522}
3523
3524template <class KEY, class COMPARATOR, class ALLOCATOR>
3525inline
3526typename multiset<KEY, COMPARATOR, ALLOCATOR>::iterator
3527multiset<KEY, COMPARATOR, ALLOCATOR>::erase(const_iterator first,
3528 const_iterator last)
3529{
3530 while (first != last) {
3531 first = erase(first);
3532 }
3533 return iterator(last.node());
3534}
3535
3536template <class KEY, class COMPARATOR, class ALLOCATOR>
3537inline
3538void multiset<KEY, COMPARATOR, ALLOCATOR>::swap(multiset& other)
3540 AllocatorTraits::is_always_equal::value
3541 && bsl::is_nothrow_swappable<COMPARATOR>::value)
3542{
3543 if (AllocatorTraits::propagate_on_container_swap::value) {
3544 quickSwapExchangeAllocators(other);
3545 }
3546 else {
3547 // C++11 behavior for member 'swap': undefined for unequal allocators.
3548 // BSLS_ASSERT(allocator() == other.allocator());
3549
3551 nodeFactory().allocator() == other.nodeFactory().allocator())) {
3552 quickSwapRetainAllocators(other);
3553 }
3554 else {
3556
3557 multiset toOtherCopy(MoveUtil::move(*this),
3558 other.nodeFactory().allocator());
3559 multiset toThisCopy(MoveUtil::move(other),
3560 nodeFactory().allocator());
3561
3562 other.quickSwapRetainAllocators(toOtherCopy);
3563 this->quickSwapRetainAllocators(toThisCopy);
3564 }
3565 }
3566}
3567
3568template <class KEY, class COMPARATOR, class ALLOCATOR>
3569inline
3570void multiset<KEY, COMPARATOR, ALLOCATOR>::clear() BSLS_KEYWORD_NOEXCEPT
3571{
3572 BSLS_ASSERT_SAFE(d_tree.firstNode());
3573
3574 if (d_tree.rootNode()) {
3575 BSLS_ASSERT_SAFE(0 < d_tree.numNodes());
3576 BSLS_ASSERT_SAFE(d_tree.firstNode() != d_tree.sentinel());
3577
3578 BloombergLP::bslalg::RbTreeUtil::deleteTree(&d_tree, &nodeFactory());
3579 }
3580#if defined(BSLS_ASSERT_SAFE_IS_USED)
3581 else {
3582 BSLS_ASSERT_SAFE(0 == d_tree.numNodes());
3583 BSLS_ASSERT_SAFE(d_tree.firstNode() == d_tree.sentinel());
3584 }
3585#endif
3586}
3587
3588// ACCESSORS
3589template <class KEY, class COMPARATOR, class ALLOCATOR>
3590inline
3591typename multiset<KEY, COMPARATOR, ALLOCATOR>::allocator_type
3592multiset<KEY, COMPARATOR, ALLOCATOR>::get_allocator() const
3594{
3595 return nodeFactory().allocator();
3596}
3597
3598template <class KEY, class COMPARATOR, class ALLOCATOR>
3599inline
3600typename multiset<KEY, COMPARATOR, ALLOCATOR>::const_iterator
3601multiset<KEY, COMPARATOR, ALLOCATOR>::begin() const BSLS_KEYWORD_NOEXCEPT
3602{
3603 return cbegin();
3604}
3605
3606template <class KEY, class COMPARATOR, class ALLOCATOR>
3607inline
3608typename multiset<KEY, COMPARATOR, ALLOCATOR>::const_iterator
3609multiset<KEY, COMPARATOR, ALLOCATOR>::end() const BSLS_KEYWORD_NOEXCEPT
3610{
3611 return cend();
3612}
3613
3614template <class KEY, class COMPARATOR, class ALLOCATOR>
3615inline
3616typename multiset<KEY, COMPARATOR, ALLOCATOR>::const_reverse_iterator
3617multiset<KEY, COMPARATOR, ALLOCATOR>::rbegin() const BSLS_KEYWORD_NOEXCEPT
3618{
3619 return crbegin();
3620}
3621
3622template <class KEY, class COMPARATOR, class ALLOCATOR>
3623inline
3624typename multiset<KEY, COMPARATOR, ALLOCATOR>::const_reverse_iterator
3625multiset<KEY, COMPARATOR, ALLOCATOR>::rend() const BSLS_KEYWORD_NOEXCEPT
3626{
3627 return crend();
3628}
3629
3630template <class KEY, class COMPARATOR, class ALLOCATOR>
3631inline
3632typename multiset<KEY, COMPARATOR, ALLOCATOR>::const_iterator
3633multiset<KEY, COMPARATOR, ALLOCATOR>::cbegin() const BSLS_KEYWORD_NOEXCEPT
3634{
3635 return const_iterator(d_tree.firstNode());
3636}
3637
3638template <class KEY, class COMPARATOR, class ALLOCATOR>
3639inline
3640typename multiset<KEY, COMPARATOR, ALLOCATOR>::const_iterator
3641multiset<KEY, COMPARATOR, ALLOCATOR>::cend() const BSLS_KEYWORD_NOEXCEPT
3642{
3643 return const_iterator(d_tree.sentinel());
3644}
3645
3646template <class KEY, class COMPARATOR, class ALLOCATOR>
3647inline
3648typename multiset<KEY, COMPARATOR, ALLOCATOR>::const_reverse_iterator
3649multiset<KEY, COMPARATOR, ALLOCATOR>::crbegin() const BSLS_KEYWORD_NOEXCEPT
3650{
3651 return const_reverse_iterator(end());
3652}
3653
3654template <class KEY, class COMPARATOR, class ALLOCATOR>
3655inline
3656typename multiset<KEY, COMPARATOR, ALLOCATOR>::const_reverse_iterator
3657multiset<KEY, COMPARATOR, ALLOCATOR>::crend() const BSLS_KEYWORD_NOEXCEPT
3658{
3659 return const_reverse_iterator(begin());
3660}
3661
3662template <class KEY, class COMPARATOR, class ALLOCATOR>
3663inline
3664bool multiset<KEY, COMPARATOR, ALLOCATOR>::contains(const key_type& key) const
3665{
3666 return find(key) != end();
3667}
3668
3669// capacity:
3670template <class KEY, class COMPARATOR, class ALLOCATOR>
3671inline
3672bool multiset<KEY, COMPARATOR, ALLOCATOR>::empty() const BSLS_KEYWORD_NOEXCEPT
3673{
3674 return 0 == d_tree.numNodes();
3675}
3676
3677template <class KEY, class COMPARATOR, class ALLOCATOR>
3678inline
3679typename multiset<KEY, COMPARATOR, ALLOCATOR>::size_type
3680multiset<KEY, COMPARATOR, ALLOCATOR>::size() const BSLS_KEYWORD_NOEXCEPT
3681{
3682 return d_tree.numNodes();
3683}
3684
3685template <class KEY, class COMPARATOR, class ALLOCATOR>
3686inline
3687typename multiset<KEY, COMPARATOR, ALLOCATOR>::size_type
3688multiset<KEY, COMPARATOR, ALLOCATOR>::max_size() const BSLS_KEYWORD_NOEXCEPT
3689{
3690 return AllocatorTraits::max_size(get_allocator());
3691}
3692
3693template <class KEY, class COMPARATOR, class ALLOCATOR>
3694inline
3695typename multiset<KEY, COMPARATOR, ALLOCATOR>::key_compare
3696multiset<KEY, COMPARATOR, ALLOCATOR>::key_comp() const
3697{
3698 return comparator().keyComparator();
3699}
3700
3701template <class KEY, class COMPARATOR, class ALLOCATOR>
3702inline
3703typename multiset<KEY, COMPARATOR, ALLOCATOR>::value_compare
3704multiset<KEY, COMPARATOR, ALLOCATOR>::value_comp() const
3705{
3706 return value_compare(key_comp());
3707}
3708
3709} // close namespace bsl
3710
3711// FREE OPERATORS
3712template <class KEY, class COMPARATOR, class ALLOCATOR>
3713inline
3716{
3717 return BloombergLP::bslalg::RangeCompare::equal(lhs.begin(),
3718 lhs.end(),
3719 lhs.size(),
3720 rhs.begin(),
3721 rhs.end(),
3722 rhs.size());
3723}
3724
3725#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
3726template <class KEY, class COMPARATOR, class ALLOCATOR>
3727inline
3730{
3731 return !(lhs == rhs);
3732}
3733#endif
3734
3735#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
3736
3737template <class KEY, class COMPARATOR, class ALLOCATOR>
3738inline
3739BloombergLP::bslalg::SynthThreeWayUtil::Result<KEY>
3740bsl::operator<=>(const multiset<KEY, COMPARATOR, ALLOCATOR>& lhs,
3741 const multiset<KEY, COMPARATOR, ALLOCATOR>& rhs)
3742{
3743 return bsl::lexicographical_compare_three_way(
3744 lhs.begin(),
3745 lhs.end(),
3746 rhs.begin(),
3747 rhs.end(),
3748 BloombergLP::bslalg::SynthThreeWayUtil::compare);
3749}
3750
3751#else
3752
3753template <class KEY, class COMPARATOR, class ALLOCATOR>
3754inline
3757{
3758 return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.begin(),
3759 lhs.end(),
3760 lhs.size(),
3761 rhs.begin(),
3762 rhs.end(),
3763 rhs.size());
3764}
3765
3766template <class KEY, class COMPARATOR, class ALLOCATOR>
3767inline
3770{
3771 return rhs < lhs;
3772}
3773
3774template <class KEY, class COMPARATOR, class ALLOCATOR>
3775inline
3778{
3779 return !(rhs < lhs);
3780}
3781
3782template <class KEY, class COMPARATOR, class ALLOCATOR>
3783inline
3786{
3787 return !(lhs < rhs);
3788}
3789
3790#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
3791
3792// FREE FUNCTIONS
3793template <class KEY, class COMPARATOR, class ALLOCATOR, class PREDICATE>
3794inline
3796bsl::erase_if(multiset<KEY, COMPARATOR, ALLOCATOR>& ms, PREDICATE predicate)
3797{
3798 return BloombergLP::bslstl::AlgorithmUtil::containerEraseIf(ms, predicate);
3799}
3800
3801template <class KEY, class COMPARATOR, class ALLOCATOR>
3802inline
3807{
3808 a.swap(b);
3809}
3810
3811// ============================================================================
3812// TYPE TRAITS
3813// ============================================================================
3814
3815// Type traits for STL *ordered* containers:
3816//: o An ordered container defines STL iterators.
3817//: o An ordered container uses 'bslma' allocators if the (template parameter)
3818//: type 'ALLOCATOR' is convertible from 'bslma::Allocator *'.
3819
3820
3821
3822namespace bslalg {
3823
3824template <class KEY, class COMPARATOR, class ALLOCATOR>
3825struct HasStlIterators<bsl::multiset<KEY, COMPARATOR, ALLOCATOR> >
3827{};
3828
3829} // close namespace bslalg
3830
3831namespace bslma {
3832
3833template <class KEY, class COMPARATOR, class ALLOCATOR>
3834struct UsesBslmaAllocator<bsl::multiset<KEY, COMPARATOR, ALLOCATOR> >
3835 : bsl::is_convertible<Allocator*, ALLOCATOR>
3836{};
3837
3838} // close namespace bslma
3839
3840
3841
3842#else // if ! defined(DEFINED_BSLSTL_MULTISET_H)
3843# error Not valid except when included from bslstl_multiset.h
3844#endif // ! defined(COMPILING_BSLSTL_MULTISET_H)
3845
3846#endif // ! defined(INCLUDED_BSLSTL_MULTISET_CPP03)
3847
3848// ----------------------------------------------------------------------------
3849// Copyright 2019 Bloomberg Finance L.P.
3850//
3851// Licensed under the Apache License, Version 2.0 (the "License");
3852// you may not use this file except in compliance with the License.
3853// You may obtain a copy of the License at
3854//
3855// http://www.apache.org/licenses/LICENSE-2.0
3856//
3857// Unless required by applicable law or agreed to in writing, software
3858// distributed under the License is distributed on an "AS IS" BASIS,
3859// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3860// See the License for the specific language governing permissions and
3861// limitations under the License.
3862// ----------------------------- END-OF-FILE ----------------------------------
3863
3864/** @} */
3865/** @} */
3866/** @} */
Definition bslma_bslallocator.h:588
Definition bslstl_multiset.h:644
const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:2997
multiset &operator=(BloombergLP::bslmf::MovableRef< multiset > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:2610
bool empty() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:3020
void swap(multiset &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:1310
size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:3036
BloombergLP::bslstl::TreeIterator< const value_type, Node, difference_type > const_iterator
Definition bslstl_multiset.h:748
value_type & reference
Definition bslstl_multiset.h:735
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_multiset.h:750
const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:3005
COMPARATOR key_compare
Definition bslstl_multiset.h:732
BloombergLP::bslstl::TreeIterator< const value_type, Node, difference_type > iterator
Definition bslstl_multiset.h:745
const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:2989
COMPARATOR value_compare
Definition bslstl_multiset.h:733
iterator erase(const_iterator position)
Definition bslstl_multiset.h:2842
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:2618
iterator find(const key_type &key)
Definition bslstl_multiset.h:1322
key_compare key_comp() const
Definition bslstl_multiset.h:3044
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this multiset.
Definition bslstl_multiset.h:3028
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:2940
multiset()
Definition bslstl_multiset.h:2327
iterator insert(const value_type &value)
Definition bslstl_multiset.h:2642
iterator lower_bound(const key_type &key)
Definition bslstl_multiset.h:1356
KEY value_type
Definition bslstl_multiset.h:731
void insert_range(BSLS_COMPILERFEATURES_FORWARD_REF(RANGE) range)
Definition bslstl_multiset.h:1186
~multiset()
Destroy this object.
Definition bslstl_multiset.h:2541
const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:2981
bool contains(const key_type &key) const
Definition bslstl_multiset.h:3012
pair< iterator, iterator > equal_range(const key_type &key)
Definition bslstl_multiset.h:1433
iterator emplace(Args &&... args)
Definition bslstl_multiset.h:2789
value_compare value_comp() const
Definition bslstl_multiset.h:3052
multiset & operator=(const multiset &rhs)
Definition bslstl_multiset.h:2550
KEY key_type
Definition bslstl_multiset.h:730
reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:2634
iterator upper_bound(const key_type &key)
Definition bslstl_multiset.h:1395
iterator emplace_hint(const_iterator hint, Args &&... args)
Definition bslstl_multiset.h:2813
AllocatorTraits::const_pointer const_pointer
Definition bslstl_multiset.h:741
AllocatorTraits::difference_type difference_type
Definition bslstl_multiset.h:739
size_type count(const key_type &key) const
Definition bslstl_multiset.h:1604
AllocatorTraits::pointer pointer
Definition bslstl_multiset.h:740
ALLOCATOR allocator_type
Definition bslstl_multiset.h:734
reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multiset.h:2626
bsl::reverse_iterator< iterator > reverse_iterator
Definition bslstl_multiset.h:749
const value_type & const_reference
Definition bslstl_multiset.h:736
AllocatorTraits::size_type size_type
Definition bslstl_multiset.h:738
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_KEYWORD_CONSTEXPR_CPP17
Definition bsls_keyword.h:639
#define BSLS_KEYWORD_NOEXCEPT_OPERATOR(...)
Definition bsls_keyword.h:677
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:676
#define BSLS_PERFORMANCEHINT_PREDICT_LIKELY(expr)
Definition bsls_performancehint.h:451
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
#define BSLSTL_MULTISET_REQUIRES_CONTAINER_COMPATIBLE_RANGE(R, T)
Definition bslstl_multiset.h:606
void swap(OptionValue &a, OptionValue &b)
Definition bdlat_valuetypefunctions.h:939
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
T::const_iterator cend(const T &container)
Definition bslstl_iterator.h:1709
bool operator<(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
T::const_reverse_iterator crbegin(const T &container)
Definition bslstl_iterator.h:1695
bool operator>(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator>=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator<=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
deque< VALUE_TYPE, ALLOCATOR >::size_type erase(deque< VALUE_TYPE, ALLOCATOR > &deq, const BDE_OTHER_TYPE &value)
Definition bslstl_deque.h:4424
T::iterator begin(T &container)
Definition bslstl_iterator.h:1593
const from_range_t from_range
bool operator==(const memory_resource &a, const memory_resource &b)
T::const_iterator cbegin(const T &container)
Definition bslstl_iterator.h:1651
ALLOCATOR & lhs
Definition bslstl_string.h:3917
T::iterator end(T &container)
Definition bslstl_iterator.h:1621
deque< VALUE_TYPE, ALLOCATOR >::size_type erase_if(deque< VALUE_TYPE, ALLOCATOR > &deq, PREDICATE predicate)
Definition bslstl_deque.h:4433
bool operator!=(const memory_resource &a, const memory_resource &b)
T::const_reverse_iterator crend(const T &container)
Definition bslstl_iterator.h:1752
Definition bdlc_flathashmap.h:2218
Definition baljsn_encoder_testtypes.h:76
Definition bdlbb_blob.h:579
Definition bslma_allocatortraits.h:1089
BloombergLP::bslma::AllocatorTraits_ConstPointerType< ALLOCATOR >::type const_pointer
Definition bslma_allocatortraits.h:1183
BloombergLP::bslma::AllocatorTraits_SizeType< ALLOCATOR >::type size_type
Definition bslma_allocatortraits.h:1196
BloombergLP::bslma::AllocatorTraits_PointerType< ALLOCATOR >::type pointer
Definition bslma_allocatortraits.h:1180
BloombergLP::bslma::AllocatorTraits_DifferenceType< ALLOCATOR >::type difference_type
Definition bslma_allocatortraits.h:1193
Definition bslmf_enableif.h:530
Definition bslstl_ranges.h:301
Definition bslmf_isconvertible.h:875