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