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