BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_list.h
Go to the documentation of this file.
1/// @file bslstl_list.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_list.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_LIST
9#define INCLUDED_BSLSTL_LIST
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_list bslstl_list
15/// @brief Provide an STL-compliant list class.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_list
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_list-purpose"> Purpose</a>
25/// * <a href="#bslstl_list-classes"> Classes </a>
26/// * <a href="#bslstl_list-description"> Description </a>
27/// * <a href="#bslstl_list-requirements-on-value"> Requirements on VALUE </a>
28/// * <a href="#bslstl_list-memory-allocation"> Memory Allocation </a>
29/// * <a href="#bslstl_list-bslma-style-allocators"> bslma-Style Allocators </a>
30/// * <a href="#bslstl_list-comparators-and-strict-weak-ordering"> Comparators and Strict Weak Ordering </a>
31/// * <a href="#bslstl_list-glossary"> Glossary </a>
32/// * <a href="#bslstl_list-operations"> Operations </a>
33/// * <a href="#bslstl_list-usage"> Usage </a>
34/// * <a href="#bslstl_list-example-1-filter-twinkle-star"> Example 1: Filter "Twinkle Star" </a>
35/// * <a href="#bslstl_list-example-2-combine-two-star-surveys"> Example 2: Combine Two Star Surveys </a>
36///
37/// # Purpose {#bslstl_list-purpose}
38/// Provide an STL-compliant list class.
39///
40/// # Classes {#bslstl_list-classes}
41///
42/// - bsl::list: STL-compatible list template
43///
44/// **Canonical header:** bsl_list.h
45///
46/// @see bslstl_deque
47///
48/// # Description {#bslstl_list-description}
49/// This component defines a single class template, `bsl::list`,
50/// implementing the standard container holding a sequence of elements (of a
51/// template parameter type, `VALUE`). All list operations involving a single
52/// element are constant-time, including insertion and removal of an element
53/// anywhere in the list. Operations that do not change the number of elements
54/// are performed without calling constructors, destructors, swap, or assignment
55/// on the individual elements. (I.e., they are performed by
56/// pointer-manipulation alone.) A `list` does not provide random access to its
57/// elements; although access to the first and last elements of a `list` is
58/// constant-time, other elements can be accessed only by traversing the list
59/// (forwards or backwards) from the beginning or end.
60///
61/// An instantiation of `list` is an allocator-aware, in-core value-semantic
62/// type whose salient attributes are its size (number of elements) and the
63/// sequence of its contained element values (in order). If `list` is
64/// instantiated with a type that is not itself value-semantic, then it will not
65/// retain all of its value-semantic qualities. In particular, if a type cannot
66/// be tested for equality, then a `list` containing that type cannot be tested
67/// for equality. It is even possible to instantiate `list` with a type that
68/// does not have a copy-constructor, in which case the `list` will not be
69/// copyable.
70///
71/// A `list` meets the requirements of a sequence container with bidirectional
72/// iterators in the C++ standard [23.3]. The `list` implemented here adheres
73/// to the C++11 standard when compiled with a C++11 compiler, and makes the
74/// best approximation when compiled with a C++03 compiler. In particular, for
75/// C++03 we emulate move semantics, but limit forwarding (in `emplace`) to
76/// `const` lvalues, and make no effort to emulate `noexcept` or
77/// initializer-lists.
78///
79/// ## Requirements on VALUE {#bslstl_list-requirements-on-value}
80///
81///
82/// A `list` is a fully Value-Semantic Type (see @ref bsldoc_glossary ) only if
83/// the supplied `VALUE` template parameter is itself fully value-semantic. It
84/// is possible to instantiate a `list` with a `VALUE` parameter argument that
85/// does not provide a full set of value-semantic operations, but then some
86/// methods of the container may not be instantiable. The following
87/// terminology, adopted from the C++11 standard, is used in the function
88/// documentation of `list` to describe a function's requirements for the
89/// `VALUE` template parameter. These terms are also defined in sections
90/// [utility.arg.requirements] and [container.requirements.general] of the C++11
91/// standard.
92///
93/// ## Memory Allocation {#bslstl_list-memory-allocation}
94///
95///
96/// The type supplied as a list's `ALLOCATOR` template parameter determines how
97/// that list will allocate memory. The `list` template supports allocators
98/// meeting the requirements of the C++11 standard [17.6.3.5]; in addition, it
99/// supports scoped-allocators derived from the `bslma::Allocator` memory
100/// allocation protocol. Clients intending to use `bslma`-style allocators
101/// should use the template's default `ALLOCATOR` type: The default type for the
102/// `ALLOCATOR` template parameter, `bsl::allocator`, provides a C++11
103/// standard-compatible adapter for a `bslma::Allocator` object.
104///
105/// ### bslma-Style Allocators {#bslstl_list-bslma-style-allocators}
106///
107///
108/// If the (template parameter) type `ALLOCATOR` of a `list` instantiation is
109/// `bsl::allocator`, then objects of that list type will conform to the
110/// standard behavior of a `bslma`-allocator-enabled type. Such a list accepts
111/// an optional `bslma::Allocator` argument at construction. If the address of
112/// a `bslma::Allocator` object is explicitly supplied at construction, the list
113/// uses it to supply memory for the list throughout its lifetime; otherwise,
114/// the list will use the default allocator installed at the time of the list's
115/// construction (see @ref bslma_default ). In addition to directly allocating
116/// memory from the indicated `bslma::Allocator`, a list supplies that
117/// allocator's address to the constructors of contained objects of the
118/// (template parameter) `VALUE` type if it defines the
119/// `bslma::UsesBslmaAllocator` trait.
120///
121/// ### Comparators and Strict Weak Ordering {#bslstl_list-comparators-and-strict-weak-ordering}
122///
123///
124/// A comparator function `comp(a, b)` defines a *strict* *weak* *ordering* if
125/// * `comp(a, b)` && `comp(b, c)` implies `comp(a, c)`
126/// * `comp(a, b)` implies `!comp(b, a)`
127/// * `!comp(a, b)` does not imply that `comp(b, a)`
128///
129/// ## Glossary {#bslstl_list-glossary}
130///
131///
132/// @code
133/// Legend
134/// ------
135/// 'X' - denotes an allocator-aware container type (e.g., 'list')
136/// 'T' - 'value_type' associated with 'X'
137/// 'A' - type of the allocator used by 'X'
138/// 'm' - lvalue of type 'A' (allocator)
139/// 'p', - address ('T *') of uninitialized storage for a 'T' within an 'X'
140/// 'rv' - rvalue of type (non-'const') 'T&&'
141/// 'v' - rvalue or lvalue of type (possibly 'const') 'T'
142/// 'args' - 0 or more arguments
143/// @endcode
144/// The following terms are used to more precisely specify the requirements on
145/// template parameter types in function-level documentation.
146///
147/// *default-insertable*: `T` has a default constructor. More precisely, `T`
148/// is `default-insertable` into `X` means that the following expression is
149/// well-formed:
150/// `allocator_traits<A>::construct(m, p)`
151///
152/// *move-insertable*: `T` provides a constructor that takes an rvalue of type
153/// (non-`const`) `T`. More precisely, `T` is `move-insertable` into `X`
154/// means that the following expression is well-formed:
155/// `allocator_traits<A>::construct(m, p, rv)`
156///
157/// *copy-insertable*: `T` provides a constructor that takes an lvalue or
158/// rvalue of type (possibly `const`) `T`. More precisely, `T` is
159/// `copy-insertable` into `X` means that the following expression is
160/// well-formed:
161/// `allocator_traits<A>::construct(m, p, v)`
162///
163/// *move-assignable*: `T` provides an assignment operator that takes an rvalue
164/// of type (non-`const`) `T`.
165///
166/// *copy-assignable*: `T` provides an assignment operator that takes an lvalue
167/// or rvalue of type (possibly `const`) `T`.
168///
169/// *emplace-constructible*: `T` is `emplace-constructible` into `X` from
170/// `args` means that the following expression is well-formed:
171/// `allocator_traits<A>::construct(m, p, args)`
172///
173/// *erasable*: `T` provides a destructor. More precisely, `T` is `erasable`
174/// from `X` means that the following expression is well-formed:
175/// `allocator_traits<A>::destroy(m, p)`
176///
177/// *equality-comparable*: The type provides an equality-comparison operator
178/// that defines an equivalence relationship and is both reflexive and
179/// transitive.
180///
181/// ## Operations {#bslstl_list-operations}
182///
183///
184/// This section describes the run-time complexity of operations on instances
185/// of `list`:
186/// @code
187/// Legend
188/// ------
189/// 'V' - template parameter 'VALUE' type of the list
190/// 'A' - template parameter 'ALLOCATOR' type of the list
191/// 'a', 'b' - distinct objects of type 'list<V>'
192/// 'k' - unsigned integral constant
193/// 'ra','rb' - distinct modifiable rvalue objects of type 'list<V>&&'
194/// 'n', 'm' - number of elements in 'a' and 'b', respectively
195/// 'al' - an STL-style memory allocator
196/// 'i1', 'i2' - two iterators defining a sequence of 'V' objects
197/// 'v' - an object of type 'V'
198/// 'rv' - modifiable rvalue object of type 'V&&'
199/// 'p1', 'p2' - two iterators belonging to 'a'
200/// 's1', 's2' - two iterators belonging to 'b'
201/// 'pred' - a unary predicate
202/// 'binary_pred' - a binary predicate
203/// 'comp' - a binary predicate implementing a strict-weak ordering
204/// 'args...' - a variadic list of (up to 10) arguments
205/// '{*}' - C++11-style initializer list of length 'ni'
206/// distance(i1,i2) - the number of elements in the range '[i1 .. i2)'
207///
208/// +----------------------------------------------------+--------------------+
209/// | Operation | Complexity |
210/// +====================================================+====================+
211/// | list<V> a; (default construction) | O[1] |
212/// | list<V> a(al); | |
213/// +----------------------------------------------------+--------------------+
214/// | list<V> a(b); (copy construction) | O[m] |
215/// | list<V> a(b, al); | |
216/// +----------------------------------------------------+--------------------+
217/// | list<V> a(rb); (move construction) | O[1] |
218/// | list<V> a(rb, al); | O[1] if 'a' and 'b'|
219/// | | use the same |
220/// | | allocator, |
221/// | | O[m] otherwise |
222/// +----------------------------------------------------+--------------------+
223/// | list<V> a(k); | O[k] |
224/// | list<V> a(k, v); | |
225/// | list<V> a(k, v, al); | |
226/// +----------------------------------------------------+--------------------+
227/// | list<V> a(i1, i2); | O[distance(i1, i2)]|
228/// | list<V> a(i1, i2, al); | |
229/// +----------------------------------------------------+--------------------+
230/// | list<V> a({*}, al = A()) | O[ni] |
231/// +----------------------------------------------------+--------------------+
232/// | a.~list<V>(); (destruction) | O[n] |
233/// +----------------------------------------------------+--------------------+
234/// | a = b; (copy assignment) | O[max(n, m)] |
235/// +----------------------------------------------------+--------------------+
236/// | a = {*}; (copy assignment) | O[max(n, ni)] |
237/// +----------------------------------------------------+--------------------+
238/// | a = rb; (move assignment) | O[1] if 'a' and 'b'|
239/// | | use the same |
240/// | | allocator, |
241/// | | O[max(n, m)] |
242/// | | otherwise |
243/// +----------------------------------------------------+--------------------+
244/// | a.begin(), a.end(), a.cbegin(), a.cend(), | O[1] |
245/// | a.rbegin(), a.rend(), a.crbegin(), a.crend() | |
246/// +----------------------------------------------------+--------------------+
247/// | a == b, a != b | O[n] |
248/// +----------------------------------------------------+--------------------+
249/// | a < b, a <= b, a > b, a >= b | O[n] |
250/// +----------------------------------------------------+--------------------+
251/// | a.swap(b), swap(a, b) | O[1] if 'a' and 'b'|
252/// | | use the same |
253/// | | allocator, |
254/// | | O[n + m] otherwise |
255/// +----------------------------------------------------+--------------------+
256/// | a.size() | O[1] |
257/// +----------------------------------------------------+--------------------+
258/// | a.max_size() | O[1] |
259/// +----------------------------------------------------+--------------------+
260/// | a.empty() | O[1] |
261/// +----------------------------------------------------+--------------------+
262/// | a.get_allocator() | O[1] |
263/// +----------------------------------------------------+--------------------+
264/// | a.emplace(p1, args...) | O[1] |
265/// +----------------------------------------------------+--------------------+
266/// | a.insert(p1, v) | O[1] |
267/// +----------------------------------------------------+--------------------+
268/// | a.insert(p1, k, v) | O[k] |
269/// +----------------------------------------------------+--------------------+
270/// | a.insert(p1, i1, i2) | O[distance(i1, i2)]|
271/// +----------------------------------------------------+--------------------+
272/// | a.insert(p1, rv) | O[1] |
273/// +----------------------------------------------------+--------------------+
274/// | a.insert(p1, {*}) | O[ni] |
275/// +----------------------------------------------------+--------------------|
276/// | a.erase(p1) | O[1] |
277/// +----------------------------------------------------+--------------------+
278/// | a.erase(p1, p2) | O[distance(p1, p2)]|
279/// +----------------------------------------------------+--------------------+
280/// | a.clear() | O[n] |
281/// +----------------------------------------------------+--------------------+
282/// | a.assign(i1,i2) | O[distance(i1, i2)]|
283/// +----------------------------------------------------+--------------------+
284/// | a.assign(k, v) | O[max(n, k)] |
285/// +----------------------------------------------------+--------------------+
286/// | a.assign({*}) | O[max(n, ni)] |
287/// +----------------------------------------------------+--------------------+
288/// | a.front(), a.back() | O[1] |
289/// +----------------------------------------------------+--------------------+
290/// | a.emplace_front(args...), a.emplace_back(args...) | O[1] |
291/// +----------------------------------------------------+--------------------+
292/// | a.push_front(v), | |
293/// | a.push_back(v) | O[1] |
294/// +----------------------------------------------------+--------------------+
295/// | a.push_front(rv), | |
296/// | a.push_back(rv) | O[1] |
297/// +----------------------------------------------------+--------------------+
298/// | a.pop_front(), a.pop_back() | O[1] |
299/// +----------------------------------------------------+--------------------+
300/// | a.resize(k), a.resize(k, v) | O[k] |
301/// +----------------------------------------------------+--------------------+
302/// | a.splice(p, b), a.splice(p, b, s1) | O[1] |
303/// +----------------------------------------------------+--------------------+
304/// | a.splice(p, rb), a.splice(p, rb, s1) | O[1] |
305/// +----------------------------------------------------+--------------------+
306/// | a.splice(p, b, s1, s2) | O[distance(s1, s2)]|
307/// +----------------------------------------------------+--------------------+
308/// | a.splice(p, rb, s1, s2) | O[distance(s1, s2)]|
309/// +----------------------------------------------------+--------------------+
310/// | a.remove(t), a.remove_if(pred) | O[n] |
311/// +----------------------------------------------------+--------------------+
312/// | a.unique(), a.unique(binary_pred) | O[n] |
313/// +----------------------------------------------------+--------------------+
314/// | a.merge(b), a.merge(b, comp) | O[n] |
315/// +----------------------------------------------------+--------------------+
316/// | a.merge(rb), a.merge(rb, comp) | O[n] |
317/// +----------------------------------------------------+--------------------+
318/// | a.sort(), a.sort(comp) | O[n*log(n)] |
319/// +----------------------------------------------------+--------------------+
320/// | a.reverse() | O[n] |
321/// +----------------------------------------------------+--------------------+
322/// @endcode
323///
324/// ## Usage {#bslstl_list-usage}
325///
326///
327/// This section illustrates intended usage of this component.
328///
329/// ### Example 1: Filter "Twinkle Star" {#bslstl_list-example-1-filter-twinkle-star}
330///
331///
332/// Suppose an observatory needs to analyze the results of a sky survey. The
333/// raw data is a text file of star observations where each star is represented
334/// by a tuple of three numbers: (x, y, b), where x and y represent the angular
335/// coordinates of the star in the sky and b represents its brightness on a
336/// scale of 0 to 100. A star having brightness 75 or higher is of particular
337/// interest, which is called "twinkle star".
338///
339/// Our first example will read such a data file as described above, filter out
340/// the dim stars (brightness less than 75), and count the twinkle stars left
341/// in the list. Our test data set has been selected such that there are 10
342/// stars in the set, of which 4 are sufficiently bright as to pass our filter.
343///
344/// First, we define the class `Star` that encapsulates a single tuple, and
345/// provides accessors functions `x`, `y`, and `brightness`, file I/O functions
346/// `read` and `write`, and free operators `==`, `!=`, and `<`:
347/// @code
348/// #include <cstdio>
349/// using namespace std;
350///
351/// /// This class represents a star as seen through a digital telescope.
352/// class Star
353/// {
354/// // DATA
355/// double d_x, d_y; // coordinates
356///
357/// int d_brightness; // brightness on a scale of 0 to 100
358///
359/// public:
360/// // CREATORS
361///
362/// /// Create a `Star` object located at coordinates `(0, 0)` having
363/// /// `0` brightness.
364/// Star()
365/// : d_x(0), d_y(0), d_brightness(0)
366/// {
367/// }
368///
369/// /// Create a `Star` object located at the specified coordinates
370/// /// `(x, y)` having the specified `b` brightness.
371/// Star(double x, double y, int b)
372/// : d_x(x), d_y(y), d_brightness(b)
373/// {
374/// }
375///
376/// // Compiler-generated copy construction, assignment, and destructor
377/// // Star(const Star&) = default;
378/// // Star& operator=(const Star&) = default;
379/// // ~Star() = default;
380///
381/// // MANIPULATORS
382///
383/// /// Read x, y, and brightness from the specified `input` file.
384/// /// Return `true` if the read succeeded and `false` otherwise.
385/// bool read(FILE *input);
386///
387/// /// Write x, y, and brightness to the specified `output` file
388/// /// followed by a newline.
389/// void write(FILE *output) const;
390///
391/// // ACCESSORS
392///
393/// /// Return the x coordinate of this `Star` object.
394/// double x() const
395/// {
396/// return d_x;
397/// }
398///
399/// /// Return the y coordinate of this `Star` object.
400/// double y() const
401/// {
402/// return d_y;
403/// }
404///
405/// /// Return the brightness of this `Star` object.
406/// int brightness() const
407/// {
408/// return d_brightness;
409/// }
410/// };
411///
412/// // FREE FUNCTIONS
413/// bool operator==(const Star& lhs, const Star& rhs);
414/// bool operator!=(const Star& lhs, const Star& rhs);
415/// bool operator< (const Star& lhs, const Star& rhs);
416/// @endcode
417/// Then, we define a `readData` method that reads a file of data points and
418/// appends each onto a list. The stars are stored in the data file in
419/// ascending sorted order by x and y coordinates.
420/// @code
421/// void readData(list<Star> *starList, FILE *input)
422/// {
423/// Star s;
424/// while (s.read(input)) {
425/// starList->push_back(s);
426/// }
427/// }
428/// @endcode
429/// Now, we define the `filter` method, which is responsible for removing stars
430/// with a brightness of less than 75 from the data set. It does this by
431/// iterating over the list and erasing any element that does not pass the
432/// filter. The list object features a fast `erase` member function. The
433/// return value of `erase` is an iterator to the element immediately following
434/// the erased element:
435/// @code
436/// void filter(list<Star> *starList)
437/// {
438/// static const int threshold = 75;
439///
440/// list<Star>::iterator i = starList->begin();
441/// while (i != starList->end()) {
442/// if (i->brightness() < threshold) {
443/// i = starList->erase(i); // Erase and advance to next element.
444/// }
445/// else {
446/// ++i; // Advance to next element without erasing
447/// }
448/// }
449/// }
450/// @endcode
451/// Finally, we use the methods defined in above steps to put together our
452/// program to find twinkle stars:
453/// @code
454/// int usageExample1(int verbose)
455/// {
456/// FILE *input = fopen("star_data1.txt", "r"); // Open input file.
457/// assert(input);
458///
459/// list<Star> starList; // Define a list of stars.
460/// assert(starList.empty()); // A list should be empty
461/// // after default
462/// // construction.
463///
464/// readData(&starList, input); // Read input to the list.
465/// assert(10 == starList.size()); // Verify correct reading.
466/// fclose(input); // Close input file.
467///
468/// filter(&starList); // Pick twinkle stars.
469/// assert(4 == starList.size()); // Verify correct filter.
470///
471/// // Print out twinkle stars.
472/// if (verbose) {
473/// for (list<Star>::const_iterator i = starList.begin();
474/// i != starList.end(); ++i) {
475/// i->write(stdout);
476/// }
477/// }
478/// return 0;
479/// }
480/// @endcode
481///
482/// ### Example 2: Combine Two Star Surveys {#bslstl_list-example-2-combine-two-star-surveys}
483///
484///
485/// In the second example, we want to combine the results from two star surveys
486/// into a single list, using the same `Star` class defined in the first usage
487/// example.
488///
489/// First, we begin by reading both lists and filtering them. (Our test data is
490/// selected so that the second data file contains 8 stars of which 3 are
491/// sufficiently bright as to pass our filter:
492/// @code
493/// int usageExample2(int verbose)
494/// {
495/// FILE *input = fopen("star_data1.txt", "r"); // Open first input file.
496/// assert(input);
497///
498/// list<Star> starList1; // Define first star list.
499/// assert(starList1.empty());
500///
501/// readData(&starList1, input); // Read input into list.
502/// assert(10 == starList1.size());
503/// fclose(input); // Close first input file.
504///
505/// input = fopen("star_data2.txt", "r"); // Open second input file.
506/// assert(input);
507///
508/// list<Star> starList2; // Define second list.
509/// assert(starList2.empty());
510///
511/// readData(&starList2, input); // Read input into list.
512/// assert(8 == starList2.size());
513/// fclose(input); // Close input file.
514///
515/// filter(&starList1); // Pick twinkle stars from
516/// // the first star list.
517/// assert(4 == starList1.size());
518///
519/// filter(&starList2); // Pick twinkle stars from
520/// // the second star list.
521/// assert(3 == starList2.size());
522/// @endcode
523/// Then, we combine the two lists, `starList1` and `starList2`. One way to do
524/// this is to simply insert the second list at the end of the first:
525/// @code
526/// list<Star> tmp1(starList1); // Make a copy of the first list
527/// list<Star> tmp2(starList2); // Make a copy of the second list
528/// tmp1.insert(tmp1.end(), tmp2.begin(), tmp2.end());
529/// assert(7 == tmp1.size()); // Verify combined size.
530/// assert(3 == tmp2.size()); // 'tmp2' should be unchanged.
531/// @endcode
532/// Next, let's have a closer look of the above code and see if we can improve
533/// the combination performance. The above `insert` method appends a copy of
534/// each element in `tmp2` onto the end of `tmp1`. This copy is unnecessary
535/// because we have no need for `tmp2` after the lists have been combined. A
536/// faster and less-memory-intensive technique is to use the `splice` function,
537/// which *moves* rather than *copies* elements from one list to another:
538/// @code
539/// tmp1 = starList1;
540/// tmp2 = starList2;
541/// tmp1.splice(tmp1.begin(), tmp2);
542/// assert(7 == tmp1.size()); // Verify combined size.
543/// assert(0 == tmp2.size()); // 'tmp2' should be emptied by the splice.
544/// @endcode
545/// Notice that, while the original lists were sorted in ascending order
546/// (because the data files were originally sorted), the combined list is no
547/// longer sorted. To fix it, we sort `tmp1` using the `sort` member function:
548/// @code
549/// tmp1.sort();
550/// @endcode
551/// Then, we suggest a third, and also the best approach to combine two lists,
552/// which is to take advantage of the fact that the lists were originally
553/// sorted, using the `merge` function:
554/// @code
555/// starList1.merge(starList2); // Merge 'starList2' into 'starList1'.
556/// assert(7 == starList1.size()); // Verify combined size.
557/// assert(0 == starList2.size()); // starList2 should be emptied by the
558/// // merge.
559/// @endcode
560/// Now, since the two star surveys may overlap, we want to eliminate
561/// duplicates. We accomplish this by using the `unique` member function:
562/// @code
563/// starList1.unique(); // Eliminate duplicates in 'starList1'.
564/// assert(6 == starList1.size()); // Verify size after elimination.
565/// @endcode
566/// Finally, we print the result:
567/// @code
568/// if (verbose) {
569/// for (list<Star>::const_iterator i = starList1.begin();
570/// i != starList1.end(); ++i) {
571/// i->write(stdout);
572/// }
573/// }
574/// return 0;
575/// }
576/// @endcode
577/// For completeness, the implementations of the `read`, `write`, and comparison
578/// functions for class `Star` are shown below:
579/// @code
580/// bool Star::read(FILE *input)
581/// {
582/// int ret = fscanf(input, "%lf %lf %d", &d_x, &d_y, &d_brightness);
583/// return 3 == ret;
584/// }
585///
586/// void Star::write(FILE *output) const
587/// {
588/// fprintf(output, "%f %f %d\n", d_x, d_y, d_brightness);
589/// }
590///
591/// bool operator==(const Star& lhs, const Star& rhs)
592/// {
593/// return lhs.x() == rhs.x()
594/// && lhs.y() == rhs.y()
595/// && lhs.brightness() == rhs.brightness();
596/// }
597///
598/// bool operator!=(const Star& lhs, const Star& rhs)
599/// {
600/// return ! (lhs == rhs);
601/// }
602///
603/// bool operator<(const Star& lhs, const Star& rhs)
604/// {
605/// if (lhs.x() < rhs.x())
606/// return true;
607/// else if (rhs.x() < lhs.x())
608/// return false;
609/// else if (lhs.y() < rhs.y())
610/// return true;
611/// else if (rhs.y() < lhs.y())
612/// return true;
613/// else
614/// return lhs.brightness() < rhs.brightness();
615/// }
616/// @endcode
617/// @}
618/** @} */
619/** @} */
620
621/** @addtogroup bsl
622 * @{
623 */
624/** @addtogroup bslstl
625 * @{
626 */
627/** @addtogroup bslstl_list
628 * @{
629 */
630
631#include <bslscm_version.h>
632
633#include <bslstl_algorithm.h>
634#include <bslstl_iterator.h>
635#include <bslstl_iteratorutil.h>
636
637#include <bslalg_rangecompare.h>
640
641#include <bslma_allocator.h>
643#include <bslma_allocatorutil.h>
644#include <bslma_isstdallocator.h>
645#include <bslma_bslallocator.h>
647
648#include <bslmf_assert.h>
649#include <bslmf_enableif.h>
650#include <bslmf_isarithmetic.h>
652#include <bslmf_isconvertible.h>
653#include <bslmf_isenum.h>
654#include <bslmf_issame.h>
655#include <bslmf_movableref.h>
657#include <bslmf_removecv.h>
658#include <bslmf_typeidentity.h>
659#include <bslmf_util.h> // 'forward(V)'
660
661#include <bsls_assert.h>
663#include <bsls_keyword.h>
664#include <bsls_libraryfeatures.h>
665#include <bsls_performancehint.h>
666#include <bsls_types.h>
667#include <bsls_util.h>
668
669#include <algorithm> // for std::swap in C++03 or earlier
670
671#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
672#include <initializer_list>
673#endif
674
675#include <utility> // for std::swap in C++11 or later
676
677#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
678// Include version that can be compiled with C++03
679// Generated on Thu Oct 21 10:11:37 2021
680// Command line: sim_cpp11_features.pl bslstl_list.h
681# define COMPILING_BSLSTL_LIST_H
682# include <bslstl_list_cpp03.h>
683# undef COMPILING_BSLSTL_LIST_H
684#else
685
686namespace bsl {
687
688 // =====================
689 // struct bsl::List_Node
690 // =====================
691
692/// PRIVATE CLASS TEMPLATE. For use only by `bsl::list` implementation.
693/// An instance of `List_Node<T>` is a single node in a doubly-linked list
694/// used to implement `bsl::list<T,A>`, for a given element type `T` and
695/// allocator type `A`. Note that an instantiation of this `class` for a
696/// given `bsl::list` is independent of the allocator type.
697///
698/// See @ref bslstl_list
699template <class VALUE>
701
702 // DATA
703 List_Node *d_prev_p; // pointer to the previous node in the list
704 List_Node *d_next_p; // pointer to the next node in the list
705 VALUE d_value; // list element
706
707 // FRIENDS
708 template <class LIST_VALUE, class LIST_ALLOCATOR>
709 friend class list;
710
711 template <class ITER_VALUE>
712 friend class List_Iterator;
713
714 private:
715 // NOT IMPLEMENTED
716 List_Node(); // = delete;
717 List_Node(const List_Node&); // = delete;
718 ~List_Node(); // = delete;
719 List_Node& operator=(const List_Node&); // = delete;
720
721 // A 'List_Node' is never constructed, copied, destroyed, or assigned to.
722 // The 'd_value' field is constructed directly by 'list::emplace', and
723 // destroyed directly by 'list::erase'.
724};
725
726 // ========================
727 // class bsl::List_Iterator
728 // ========================
729
730#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
731// On Solaris studio12-v4, <algorithm> is compatible only with iterators
732// inheriting from 'std::iterator'.
733
734template <class VALUE>
735class List_Iterator :
736 public std::iterator<std::bidirectional_iterator_tag, VALUE> {
737#else
738template <class VALUE>
740#endif
741 // Implementation of 'bsl::list::iterator'.
742
743 // PRIVATE TYPES
744 typedef typename remove_cv<VALUE>::type NcType;
746 typedef List_Node<NcType> Node;
747
748 // DATA
749 Node *d_node_p; // pointer to list node
750
751 // FRIENDS
752 template <class LIST_VALUE, class LIST_ALLOCATOR>
753 friend class list;
754
755 template <class ITER_VALUE> // This 'friend' statement is needed for the
756 friend class List_Iterator; // case where 'VALUE' != 'ITER_VALUE'.
757
758 template <class T1, class T2>
760
761 private:
762 // PRIVATE ACCESSORS
763
764 /// Return an iterator providing modifiable access to the list element
765 /// that this list iterator refers to.
766 NcIter unconst() const;
767
768 public:
769 // PUBLIC TYPES
770 typedef std::bidirectional_iterator_tag iterator_category;
771 typedef NcType value_type;
772 typedef BloombergLP::bsls::Types::IntPtr difference_type;
773 typedef VALUE *pointer;
774 typedef VALUE& reference;
775
776 // CREATORS
777
778 /// Create a singular iterator (i.e., one that cannot be incremented,
779 /// decremented, or dereferenced until assigned a non-singular value).
781
782 /// Create an iterator that references the value pointed to by the
783 /// specified `nodePtr`. If `0 == nodePtr` the iterator will be
784 /// singular.
785 explicit List_Iterator(Node *nodePtr);
786
787 /// Create an iterator that has the same value as the specified `other`
788 /// iterator. If the (template parameter) type `VALUE` is not
789 /// `const`-qualified, then this constructor is the copy constructor;
790 /// otherwise, the copy constructor is implicitly generated. Note that
791 /// this method is marked "IMPLICIT" in case it is not the copy
792 /// constructor.
793 ///
794 /// Note that this means that a `List_Iterator<const VALUE>` can be copy
795 /// constructed or assigned to from a `List_Iterator<VALUE>`, but not
796 /// vice-versa.
797 List_Iterator(const NcIter& other); // IMPLICIT
798
799 // Compiler-generated copy constructor, destructor, and copy-assignment
800 // operator:
801 //: o List_Iterator(const List_Iterator&); // Maybe defaulted (see above).
802 //: o ~List_Iterator() = default;
803 //: o List_Iterator& operator=(const List_Iterator&) = default;
804
805#if defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS)
806 /// Default compiler-generated destructor.
807 ~List_Iterator() = default;
808
809 /// Default compiler-generated copy-assignment operator.
810 List_Iterator& operator=(const List_Iterator&) = default;
811#endif
812
813 // MANIPULATORS
814
815 /// Advance this iterator to the next element in the list and return its
816 /// new value. The behavior is undefined unless this iterator is in the
817 /// range `[begin() .. end())` for some list (i.e., the iterator is not
818 /// singular, is not `end()`, and has not been invalidated).
820
821 /// Regress this iterator to the previous element in the list and return
822 /// its new value. The behavior is undefined unless this iterator is in
823 /// the range `(begin() .. end()]` for some list (i.e., the iterator is
824 /// not singular, is not `begin()`, and has not been invalidated).
826
827 /// Advance this iterator to the next element in the list and return its
828 /// previous value. The behavior is undefined unless this iterator is
829 /// in the range `[begin() .. end())` for some list (i.e., the iterator
830 /// is not singular, is not `end()`, and has not been invalidated).
832
833 /// Regress this iterator to the previous element in the list and return
834 /// its previous value. The behavior is undefined unless this iterator
835 /// is in the range `(begin() .. end()]` for some list (i.e., the
836 /// iterator is not singular, is not `begin()`, and has not been
837 /// invalidated).
839
840 // ACCESSORS
841
842 /// Return a reference providing modifiable access to the element
843 /// referenced by this iterator. The behavior is undefined unless this
844 /// iterator is in the range `[begin() .. end())` for some list (i.e.,
845 /// the iterator is not singular, is not `end()`, and has not been
846 /// invalidated).
847 reference operator*() const;
848
849 /// Return a pointer providing modifiable access to the element
850 /// referenced by this iterator. The behavior is undefined unless this
851 /// iterator is in the range `[begin() .. end())` for some list (i.e.,
852 /// the iterator is not singular, is not `end()`, and has not been
853 /// invalidated).
854 pointer operator->() const;
855};
856
857// FREE OPERATORS
858
859/// Return `true` if the specified `lhs` and `rhs` iterators have the same
860/// value, and `false` otherwise. Two iterators have the same value if both
861/// refer to the same element of the same list or both are the `end()`
862/// iterator of the same list. The behavior is undefined unless both `lhs`
863/// and `rhs` refer to the same list. Note that the different types `T1`
864/// and `T2` are to facilitate comparisons between `const` and non-`const`
865/// iterators and there will be a compilation error if `T1` and `T2` differ
866/// in any way other than `const`-ness.
867template <class T1, class T2>
869
870#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
871template <class T1, class T2>
872bool operator!=(List_Iterator<T1> lhs, List_Iterator<T2> rhs);
873 // Return 'true' if the specified 'lhs' and 'rhs' iterators do not have the
874 // same value, and 'false' otherwise. Two iterators do not have the same
875 // value unless both refer to the same element of the same list or unless
876 // both are the 'end()' iterator of the same list. The behavior is
877 // undefined unless both 'lhs' and 'rhs' refer to the same list. Note that
878 // the different types 'T1' and 'T2' are to facilitate comparisons between
879 // 'const' and non-'const' iterators and there will be a compilation error
880 // if 'T1' and 'T2' differ in any way other than 'const'-ness.
881#endif
882
883 // ===========================
884 // struct List_DefaultLessThan
885 // ===========================
886
887/// Binary predicate type for comparing two `VALUE` objects using
888/// `operator<`. This operation is usually, but not always, the same as
889/// that provided by `std::less<VALUE>`. The standard requires that certain
890/// functions use `operator<`, which means that divergent specializations of
891/// `std::less` are to be ignored.
892template <class VALUE>
894
895 // ACCESSORS
896
897 /// Return `true` if the value of the specified `lhs` is less than that
898 /// of the specified `rhs`, and `false` otherwise.
899 bool operator()(const VALUE& lhs, const VALUE& rhs) const;
900};
901
902 // ==============================
903 // class List_AllocAndSizeWrapper
904 // ==============================
905
906/// This struct is a wrapper around the allocator and size data members of a
907/// `list`. It takes advantage of the empty-base optimization (EBO) so that
908/// if the allocator is stateless, it takes up no space.
909///
910/// TBD: This struct should eventually be replaced by the use of a general
911/// EBO-enabled component that provides a `pair`-like interface. (A
912/// properly-optimized `tuple` would do the job.)
913template <class VALUE, class ALLOCATOR>
915 template rebind_traits<List_Node<VALUE> >::allocator_type {
916
917 // PRIVATE TYPES
918 typedef List_Node<VALUE> Node;
919
920 /// Alias for the allocator traits type associated with the `bsl::list`
921 /// container.
922 typedef typename allocator_traits<ALLOCATOR>::template rebind_traits<Node>
923 AllocTraits;
924
925 typedef typename AllocTraits::allocator_type NodeAlloc; // base class
926
927 typedef typename AllocTraits::size_type size_type;
928
929 // DATA
930 size_type d_size; // Number of elements in the list (not including the
931 // sentinel).
932
933 private:
934 // NOT IMPLEMENTED
937
938 public:
939 // CREATORS
940
941 /// Create an allocator and size wrapper having the specified
942 /// `basicAllocator` and (initial) `size`.
943 List_AllocAndSizeWrapper(const NodeAlloc& basicAllocator,
944 size_type size);
945
946 // ~List_AllocAndSizeWrapper() = default;
947
948 // MANIPULATORS
949
950 /// Return a reference providing modifiable access to the `size` field
951 /// of this object.
952 size_type& size();
953
954 // ACCESSORS
955
956 /// Return a reference providing non-modifiable access to the `size`
957 /// field of this object.
958 const size_type& size() const;
959};
960
961/// Forward declaration required by `List_NodeProctor`.
962template <class VALUE, class ALLOCATOR>
963class list;
964
965 // ======================
966 // class List_NodeProctor
967 // ======================
968
969/// This class provides a proctor to free a node containing an uninitialized
970/// `VALUE` object in the event that an exception is thrown.
971///
972/// See @ref bslstl_list
973template <class VALUE, class ALLOCATOR>
975
976 // PRIVATE TYPES
977 typedef List_Node<VALUE> Node;
978
979 /// Alias for the allocator traits type associated with the `bsl::list`
980 /// container.
981 typedef typename allocator_traits<ALLOCATOR>::template rebind_traits<Node>
982 AllocTraits;
983
984 public:
985 // PUBLIC TYPES
986
987 // In C++11 'NodePtr' would be generalized as follows:
988 // 'typedef pointer_traits<VoidPtr>::template rebind<List_Node> NodePtr;'
989
990 typedef typename AllocTraits::pointer NodePtr;
991
992 private:
993 // DATA
994 list<VALUE, ALLOCATOR> *d_list_p; // list to proctor
995 NodePtr d_node_p; // node to free upon destruction
996
997 private:
998 // NOT IMPLEMENTED
1000 List_NodeProctor &operator=(const List_NodeProctor&);
1001
1002 public:
1003 // CREATORS
1004
1005 /// Create a node proctor object that will use the specified list
1006 /// `listPtr` to free the specified `nodePtr`. The behavior is
1007 /// undefined unless `nodePtr` was allocated by the allocator of
1008 /// `*listPtr`.
1010
1011 /// Destroy this node proctor, and free the node it contains unless the
1012 /// `release` method has been called before. Note that the `d_value`
1013 /// field of the node is not destroyed.
1015
1016 // MANIPULATORS
1017
1018 /// Detach the node contained in this proctor from the proctor. After
1019 /// calling this `release` method, the proctor no longer frees any node
1020 /// upon its destruction.
1021 void release();
1022};
1023
1024 // ===============
1025 // class bsl::list
1026 // ===============
1027
1028/// This class template implements a value-semantic container type holding a
1029/// sequence of elements of the (template parameter) `VALUE` type.
1030///
1031/// See @ref bslstl_list
1032template <class VALUE, class ALLOCATOR = bsl::allocator<VALUE> >
1033class list {
1034
1035 // PRIVATE TYPES
1036
1037 /// Default comparator.
1039
1040 /// Alias for the node type in this list.
1041 typedef List_Node<VALUE> Node;
1042
1043 /// Proctor for guarding a newly allocated node.
1045
1046 /// Alias for the allocator traits type associated with this container.
1047 typedef typename allocator_traits<ALLOCATOR>::template rebind_traits<Node>
1048 AllocTraits;
1049
1050 /// Alias for the utility associated with movable references.
1051 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
1052
1053 /// Alias for the wrapper containing the (usually stateless) allocator
1054 /// and number of elements stored in this container.
1057
1058 /// Base class of `List_AllocAndSizeWrapper` containing the allocator.
1059 typedef typename AllocTraits::allocator_type NodeAlloc;
1060
1061 // In C++11 'NodePtr' would be generalized as follows:
1062 // 'typedef pointer_traits<VoidPtr>::template rebind<List_Node> NodePtr;'
1063
1064 typedef typename AllocTraits::pointer NodePtr;
1065
1066 public:
1067 // PUBLIC TYPES
1068 typedef VALUE& reference;
1069 typedef const VALUE& const_reference;
1075
1079 typedef VALUE value_type;
1080 typedef ALLOCATOR allocator_type;
1081 typedef bsl::reverse_iterator<iterator> reverse_iterator;
1082 typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;
1083
1084 private:
1085 // DATA
1086 NodePtr d_sentinel; // node pointer of sentinel element
1087 AllocAndSizeWrapper d_alloc_and_size; // node allocator
1088
1089 // FRIENDS
1090 friend class List_NodeProctor<VALUE, ALLOCATOR>;
1091
1092 // PRIVATE MANIPULATORS
1093
1094 /// Return a reference providing modifiable access to the allocator used
1095 /// to allocate nodes.
1096 NodeAlloc& allocatorImp();
1097
1098 /// Return a pointer to a node allocated from the container's allocator.
1099 /// Before returning, the node's pointers are zeroed, but the
1100 /// constructor of the `value_type` is not called.
1101 NodePtr allocateNode();
1102
1103 /// Create the sentinel node of this list. The sentinel node does not
1104 /// hold a value. When first created, its forward and backward pointers
1105 /// point to itself, creating a circular linked list. This function
1106 /// also sets this list's size to 0.
1107 void createSentinel();
1108
1109 /// Destroy the value part of the specified `node` and free the node's
1110 /// memory. Do not do any pointer fix-up of the node or its neighbors,
1111 /// and do not update `sizeRef`. The behavior is undefined unless
1112 /// `node` was allocated using the allocator of this list.
1113 void deleteNode(NodePtr node);
1114
1115 /// Erase all elements and deallocate the sentinel node, leaving this
1116 /// list in an invalid but destructible state (i.e., with `size == -1`).
1117 void destroyAll();
1118
1119 /// Zero out the pointers and deallocate the node pointed to by the
1120 /// specified `node`. The behavior is undefined unless `node` was
1121 /// allocated using the allocator of this list. Note that `node`s
1122 /// destructor is not called, and, importantly, the value field of
1123 /// `node` is not destroyed.
1124 void freeNode(NodePtr node);
1125
1126 /// Insert the specified `node` prior to the specified `position` in
1127 /// this list. The behavior is undefined unless `node` was allocated
1128 /// using the allocator of this list and `position` is in the range
1129 /// `[begin() .. end()]`.
1130 iterator insertNode(const_iterator position, NodePtr node);
1131
1132 /// Modify the forward pointer of the specified `prev` to point to the
1133 /// specified `next` and the backward pointer of `next` to point to
1134 /// `prev`. The behavior is undefined unless `prev` and `next` point to
1135 /// nodes created with `allocateNode`.
1136 void linkNodes(NodePtr prev, NodePtr next);
1137
1138 /// Given a specified pair of nodes `node1` and `finish` specifying the
1139 /// range `[node1 .. finish)`, with the specified `node2` pointing
1140 /// somewhere in the middle of the sequence, merge sequence
1141 /// `[node2 .. finish)` into `[node1 .. node2)`, and return a pointer to
1142 /// the beginning of the merged sequence, using the specified
1143 /// `comparator` to determine order. If an exception is thrown, all
1144 /// nodes remain in this list, but their order is unspecified. If any
1145 /// nodes in the range `[node1 .. node2)` compare equivalent to any
1146 /// nodes in the range `[node2 .. finish)`, the nodes from
1147 /// `[node1 .. node2)` will be merged first. The behavior is undefined
1148 /// unless `[node1 .. node2)` and `[node2 .. finish)` each describe a
1149 /// contiguous sequence of nodes.
1150 template <class COMPARE>
1151 NodePtr mergeImp(NodePtr node1,
1152 NodePtr node2,
1153 NodePtr finish,
1154 COMPARE comparator);
1155
1156 /// Efficiently exchange the value of this object with that of the
1157 /// specified `other` object. This method provides the no-throw
1158 /// exception-safety guarantee. The behavior is undefined unless this
1159 /// object was created with the same allocator as `other`.
1160 void quickSwap(list *other);
1161
1162 /// Return a reference providing modifiable access to the data element
1163 /// holding the size of this list.
1164 typename AllocTraits::size_type& sizeRef() BSLS_KEYWORD_NOEXCEPT;
1165
1166 /// Sort the sequence of the specified `size` nodes starting with the
1167 /// specified `*nodePtrPtr`, and modify `*nodePtrPtr` to refer to the
1168 /// first node of the sorted sequence. Return the pointer to the node
1169 /// following the sequence of nodes to be sorted. Use the specified
1170 /// `comparator` to compare `VALUE` type objects. If an exception is
1171 /// thrown, all nodes remain properly linked, but their order is
1172 /// unspecified. The behavior is undefined unless `*nodePtrPtr` begins
1173 /// a sequence of at least `size` nodes, none of which is the sentinel
1174 /// node, and `0 < size`.
1175 template <class COMPARE>
1176 NodePtr sortImp(NodePtr *nodePtrPtr,
1178 const COMPARE& comparator);
1179
1180 // PRIVATE ACCESSORS
1181
1182 /// Return a reference providing non-modifiable access to the allocator
1183 /// used to allocate nodes.
1184 const NodeAlloc& allocatorImp() const;
1185
1186 /// Return a pointer providing modifiable access to the first node in
1187 /// this list or the sentinel node if this list is empty.
1188 NodePtr headNode() const;
1189
1190 /// Return a reference providing non-modifiable access to the data
1191 /// element holding the size of this list.
1192 const typename AllocTraits::size_type& sizeRef() const
1194
1195 public:
1196 // CREATORS
1197
1198 /// Create an empty list. A default-constructed object of the (template
1199 /// parameter) type `ALLOCATOR` is used. If the type `ALLOCATOR` is
1200 /// `bsl::allocator`, the currently installed default allocator is used.
1202
1203 /// Create an empty list. Use the specified `basicAllocator` to supply
1204 /// memory. If the type `ALLOCATOR` is `bsl::allocator` (the default),
1205 /// then `basicAllocator` shall be convertible to `bslma::Allocator *`.
1206 explicit list(const ALLOCATOR& basicAllocator);
1207
1208 /// Create a list of the specified `numElements` size whose every
1209 /// element is default-constructed. A default-constructed object of the
1210 /// (template parameter) type `ALLOCATOR` is used. If the type
1211 /// `ALLOCATOR` is `bsl::allocator`, the currently installed default
1212 /// allocator is used. Throw `bsl::length_error` if
1213 /// `numElements > max_size()`. This method requires that the (template
1214 /// parameter) `VALUE` be `default-insertable` into this list (see
1215 /// {Requirements on `VALUE`}).
1216 explicit list(size_type numElements);
1217
1218 /// Create a list of the specified `numElements` size whose every
1219 /// element is default-constructed. Use the specified `basicAllocator`
1220 /// to supply memory. If the type `ALLOCATOR` is `bsl::allocator` (the
1221 /// default), then `basicAllocator` shall be convertible to
1222 /// `bslma::Allocator *`. Throw `bsl::length_error` if
1223 /// `numElements > max_size()`. This method requires that the (template
1224 /// parameter) `VALUE` be `default-insertable` into this list (see
1225 /// {Requirements on `VALUE`}).
1226 list(size_type numElements,
1227 const ALLOCATOR& basicAllocator);
1228
1229 /// Create a list of the specified `numElements` size whose every
1230 /// element has the specified `value`. Optionally specify a
1231 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
1232 /// supplied, a default-constructed object of the (template parameter)
1233 /// type `ALLOCATOR` is used. If the type `ALLOCATOR` is
1234 /// `bsl::allocator` (the default), then `basicAllocator`, if supplied,
1235 /// shall be convertible to `bslma::Allocator *`. If the type
1236 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
1237 /// supplied, the currently installed default allocator is used. Throw
1238 /// `bsl::length_error` if `numElements > max_size()`. This method
1239 /// requires that the (template parameter) `VALUE` be `copy-insertable`
1240 /// into this list (see {Requirements on `VALUE`}).
1241 list(size_type numElements,
1242 const value_type& value,
1243 const ALLOCATOR& basicAllocator = ALLOCATOR());
1244
1245 /// Create a list initially containing copies of the values in the range
1246 /// starting at the specified `first` and ending immediately before the
1247 /// specified `last` iterators of the (template parameter) type
1248 /// `INPUT_ITERATOR`. Optionally specify a `basicAllocator` used to
1249 /// supply memory. If `basicAllocator` is not supplied, a
1250 /// default-constructed object of the (template parameter) type
1251 /// `ALLOCATOR` is used. If the type `ALLOCATOR` is `bsl::allocator`
1252 /// (the default), then `basicAllocator`, if supplied, shall be
1253 /// convertible to `bslma::Allocator *`. If the type `ALLOCATOR` is
1254 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
1255 /// installed default allocator is used. Throw `bsl::length_error` if
1256 /// the number of elements in `[first .. last)` exceeds the size
1257 /// returned by @ref max_size . The (template parameter) type
1258 /// `INPUT_ITERATOR` shall meet the requirements of an input iterator
1259 /// defined in the C++11 standard [input.iterators] providing access to
1260 /// values of a type convertible to `value_type`, and `value_type` must
1261 /// be `emplace-constructible` from `*i` into this list, where `i` is a
1262 /// dereferenceable iterator in the range `[first .. last)` (see
1263 /// {Requirements on `VALUE`}). The behavior is undefined unless
1264 /// `first` and `last` refer to a sequence of valid values where `first`
1265 /// is at a position at or before `last`.
1266 template <class INPUT_ITERATOR>
1267 list(INPUT_ITERATOR first,
1268 INPUT_ITERATOR last,
1269 const ALLOCATOR& basicAllocator = ALLOCATOR(),
1270 typename enable_if<
1271 !is_arithmetic<INPUT_ITERATOR>::value &&
1272 !is_enum<INPUT_ITERATOR>::value
1273 >::type * = 0)
1274 : d_alloc_and_size(basicAllocator, size_type(-1))
1275 {
1276 // MS Visual Studio 2008 compiler requires that a function using
1277 // enable_if be in-place inline.
1278
1279 // '*this' is in an invalid but destructible state (size == -1).
1280 // Create a temporary list, 'tmp' with the specified data. If an
1281 // exception is thrown, 'tmp's destructor will clean up. Otherwise,
1282 // swap 'tmp' with '*this', leaving 'tmp' in an invalid but
1283 // destructible state and leaving '*this' fully constructed.
1284
1285 list tmp(this->allocatorImp());
1286 tmp.insert(tmp.cbegin(), first, last);
1287 quickSwap(&tmp);
1288 }
1289
1290 /// Create a list having the same value as the specified `original`
1291 /// object. Use the allocator returned by
1292 /// 'bsl::allocator_traits<ALLOCATOR>::
1293 /// select_on_container_copy_construction(original.get_allocator())' to
1294 /// allocate memory. This method requires that the (template parameter)
1295 /// type `VALUE` be `copy-insertable` into this list (see {Requirements
1296 /// on `VALUE`}).
1297 list(const list& original);
1298
1299 /// Create a list that has the same value as the specified `original`
1300 /// object. Use the specified `basicAllocator` to supply memory. This
1301 /// method requires that the (template parameter) `VALUE` be
1302 /// `copy-insertable` into this list (see {Requirements on `VALUE`}).
1303 /// Note that a `bslma::Allocator *` can be supplied for
1304 /// `basicAllocator` if the (template parameter) type `ALLOCATOR` is
1305 /// `bsl::allocator` (the default).
1306 list(const list& original,
1307 const typename type_identity<ALLOCATOR>::type& basicAllocator);
1308
1309 /// Create a list having the same value as the specified `original`
1310 /// object by moving (in constant time) the contents of `original` to
1311 /// the new list. The allocator associated with `original` is
1312 /// propagated for use in the newly-created list. `original` is left in
1313 /// a valid but unspecified state.
1314 list(BloombergLP::bslmf::MovableRef<list> original); // IMPLICIT
1315
1316 /// Create a list having the same value as the specified `original`
1317 /// object that uses the specified `basicAllocator` to supply memory.
1318 /// The contents of `original` are moved (in constant time) to the new
1319 /// list if `basicAllocator == original.get_allocator()`, and are move-
1320 /// inserted (in linear time) using `basicAllocator` otherwise.
1321 /// `original` is left in a valid but unspecified state. This method
1322 /// requires that the (template parameter) `VALUE` be `move-insertable`
1323 /// into this list (see {Requirements on `VALUE`}). Note that a
1324 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
1325 /// (template parameter) `ALLOCATOR` is `bsl::allocator` (the default).
1326 list(BloombergLP::bslmf::MovableRef<list> original,
1327 const typename type_identity<ALLOCATOR>::type& basicAllocator);
1328
1329#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1330 list(std::initializer_list<value_type> values,
1331 const ALLOCATOR& basicAllocator = ALLOCATOR());
1332 // IMPLICIT
1333 // Create a list and append each 'value_type' object in the specified
1334 // 'values' initializer list. Optionally specify a 'basicAllocator'
1335 // used to supply memory. If 'basicAllocator' is not supplied, a
1336 // default-constructed object of the (template parameter) type
1337 // 'ALLOCATOR' is used. If the type 'ALLOCATOR' is 'bsl::allocator'
1338 // (the default), then 'basicAllocator', if supplied, shall be
1339 // convertible to 'bslma::Allocator *'. If the type 'ALLOCATOR' is
1340 // 'bsl::allocator' and 'basicAllocator' is not supplied, the currently
1341 // installed default allocator is used. This method requires that the
1342 // (template parameter) 'VALUE' be 'copy-insertable' into this list
1343 // (see {Requirements on 'VALUE'}).
1344#endif
1345
1346 /// Destroy this list by calling the destructor for each element and
1347 /// deallocating all allocated storage.
1349
1350 // MANIPULATORS
1351
1352 // *** assignment ***
1353
1354 /// Assign to this object the value of the specified `rhs` object,
1355 /// propagate to this object the allocator of `rhs` if the `ALLOCATOR`
1356 /// type has trait `propagate_on_container_copy_assignment`, and return
1357 /// a reference providing modifiable access to this object. If an
1358 /// exception is thrown, `*this` is left in a valid but unspecified
1359 /// state. This method requires that the (template parameter) type
1360 /// `VALUE` be `copy-assignable` and `copy-insertable` into this list.
1361 /// Note that, to the extent possible, existing elements of this list
1362 /// are copy-assigned to, to minimize the number of nodes that need to
1363 /// be copy-inserted or erased.
1364 list& operator=(const list& rhs);
1365
1366 list& operator=(BloombergLP::bslmf::MovableRef<list> rhs)
1368 AllocTraits::is_always_equal::value);
1369 // Assign to this object the value of the specified 'rhs' object,
1370 // propagate to this object the allocator of 'rhs' if the 'ALLOCATOR'
1371 // type has trait 'propagate_on_container_move_assignment', and return
1372 // a reference providing modifiable access to this object. The
1373 // contents of 'rhs' are moved (in constant time) to this list if
1374 // 'get_allocator() == rhs.get_allocator()' (after accounting for the
1375 // aforementioned trait); otherwise, all elements in this list are
1376 // either destroyed or move-assigned to and each additional element in
1377 // 'rhs' is move-inserted into this list. 'rhs' is left in a valid but
1378 // unspecified state, and if an exception is thrown, '*this' is left in
1379 // a valid but unspecified state. This method requires that the
1380 // (template parameter) type 'VALUE' be 'move-assignable' and
1381 // 'move-insertable' into this list (see {Requirements on 'VALUE'}).
1382
1383#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1384 /// Assign to this list, in order, the sequence of values in the
1385 /// specified `rhs` initializer list, and return a reference providing
1386 /// modifiable access to this list. This method requires that the
1387 /// (template parameter) type `VALUE` be `copy-assignable` and
1388 /// `copy-insertable` into this list. Note that, to the extent
1389 /// possible, existing elements of this list are copy-assigned to, to
1390 /// minimize the number of nodes that need to be copy-inserted or
1391 /// erased.
1392 list& operator=(std::initializer_list<value_type> rhs);
1393#endif
1394
1395 /// Assign to this list the sequence of values, in order, of the
1396 /// elements of the specified range `[first .. last)`. The (template
1397 /// parameter) type `INPUT_ITERATOR` shall meet the requirements of an
1398 /// input iterator defined in the C++11 standard [24.2.3] providing
1399 /// access to values of a type convertible to `value_type`, and
1400 /// `value_type` must be `emplace-constructible` from `*i` into this
1401 /// list, where `i` is a dereferenceable iterator in the range
1402 /// `[first .. last)`. The behavior is undefined unless `first` and
1403 /// `last` refer to a sequence of valid values where `first` is at a
1404 /// position at or before `last`. Note that, to the extent possible,
1405 /// existing elements of this list are copy-assigned to, to minimize the
1406 /// number of nodes that need to be copy-inserted or erased. If an
1407 /// exception is thrown, `*this` is left in a valid but unspecified
1408 /// state.
1409 template <class INPUT_ITERATOR>
1410 void assign(INPUT_ITERATOR first,
1411 INPUT_ITERATOR last,
1412 typename enable_if<
1415 >::type * = 0)
1416 {
1417 // MS Visual Studio 2008 compiler requires that a function using
1418 // enable_if be in-place inline.
1419
1420 iterator dstIt = this->begin();
1421 const iterator dstEnd = this->end();
1422
1423 for (; first != last && dstEnd != dstIt; ++first, ++dstIt) {
1424 *dstIt = *first;
1425 }
1426
1427 erase(dstIt, dstEnd);
1428
1429 for (; first != last; ++first) {
1430 emplace(dstEnd, *first);
1431 }
1432 }
1433
1434 /// Replace the contents of this list with the specified `numElements`
1435 /// copies of the specified `value`. Note that, to the extent possible,
1436 /// existing elements of this list are copy-assigned to, to minimize the
1437 /// number of nodes that need to be copy-inserted or erased.
1438 void assign(size_type numElements, const value_type& value);
1439
1440#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1441 /// Assign to this list, in order, the sequence of values in the
1442 /// specified `values` initializer list. This method requires that the
1443 /// (template parameter) type `VALUE` be `copy-assignable` and
1444 /// `copy-insertable` into this list. Note that, to the extent
1445 /// possible, existing elements of this list are copy-assigned to, to
1446 /// minimize the number of nodes that need to be copy-inserted or
1447 /// erased.
1448 void assign(std::initializer_list<value_type> values);
1449#endif
1450
1451 // *** iterators ***
1452
1453 /// Return an iterator providing modifiable access to the first element
1454 /// in this list, and the past-the-end iterator if this list is empty.
1456
1457 /// Return the past-the-end (forward) iterator providing modifiable
1458 /// access to this list.
1460
1461 /// Return a reverse iterator providing modifiable access to the last
1462 /// element in this list, and the past-the-end reverse iterator if this
1463 /// list is empty.
1465
1466 /// Return the past-the-end reverse iterator providing modifiable access
1467 /// to this list.
1469
1470 // *** modify size ***
1471
1472 /// Remove all the elements from this list.
1474
1475 void resize(size_type newSize);
1476 /// Change the size of this list to the specified `newSize`. Erase
1477 /// `size() - newSize` elements at the back if `newSize < size()`.
1478 /// Append `newSize - size()` elements at the back having the optionally
1479 /// specified `value` if `newSize > size()`; if `value` is not
1480 /// specified, default-constructed objects of the (template parameter)
1481 /// `VALUE` are emplaced. This method has no effect if
1482 /// `newSize == size()`. Throw `bsl::length_error` if
1483 /// `newSize > max_size()`.
1484 void resize(size_type newSize, const value_type& value);
1485
1486 // *** element access ***
1487
1488 /// Return a reference providing modifiable access to the last element
1489 /// of this list. The behavior is undefined unless this list contains
1490 /// at least one element.
1492
1493 /// Return a reference providing modifiable access to the first element
1494 /// of this list. The behavior is undefined unless this list contains
1495 /// at least one element.
1496 reference front();
1497
1498 // *** end erase ***
1499
1500 /// Remove and destroy the last element of this list. The behavior is
1501 /// undefined unless this list contains at least one element.
1502 void pop_back();
1503
1504 /// Remove and destroy the first element of this list. The behavior is
1505 /// undefined unless this list contains at least one element.
1506 void pop_front();
1507
1508 // *** random access erase ***
1509
1510 /// Remove from this list the element at the specified `position`, and
1511 /// return an iterator providing modifiable access to the element
1512 /// immediately following the removed element, or to the position
1513 /// returned by the `end` method if the removed element was the last in
1514 /// the sequence. The behavior is undefined unless `position` refers to
1515 /// an element in this list.
1517
1518 /// Remove from this list the elements starting at the specified
1519 /// `dstBegin` position up to, but not including, the specified `dstEnd`
1520 /// position, and return a non-`const` iterator equivalent to `dstEnd`.
1521 /// The behavior is undefined unless `dstBegin` is an iterator in the
1522 /// range `[begin() .. end()]` and `dstEnd` is an iterator in the range
1523 /// `[dstBegin .. end()]` (both endpoints included). Note that
1524 /// `dstBegin` may be equal to `dstEnd`, in which case the list is not
1525 /// modified.
1527
1528 // *** end inserts ***
1529
1530#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1531 /// Append to the back of this list a newly created `value_type` object,
1532 /// constructed by forwarding `get_allocator()` (if required) and the
1533 /// specified (variable number of) `arguments` to the corresponding
1534 /// constructor of `value_type`. Return a reference providing
1535 /// modifiable access to the inserted element. If an exception is
1536 /// thrown (other than by the move constructor of a non-copy-insertable
1537 /// `value_type`), this method has no effect. This method requires that
1538 /// the (template parameter) `VALUE` be `move-insertable` into this list
1539 /// and `emplace-constructible` from `arguments` (see {Requirements on
1540 /// `VALUE`}).
1541 template <class... ARGS>
1542 reference emplace_back(ARGS&&... arguments);
1543#endif
1544
1545#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1546 /// Prepend to the front of this list a newly created `value_type`
1547 /// object, constructed by forwarding `get_allocator()` (if required)
1548 /// and the specified (variable number of) `arguments` to the
1549 /// corresponding constructor of `value_type`. Return a reference
1550 /// providing modifiable access to the inserted element. If an
1551 /// exception is thrown (other than by the move constructor of a
1552 /// non-copy-insertable `value_type`), this method has no effect. This
1553 /// method requires that the (template parameter) `VALUE` be
1554 /// `move-insertable` into this list and `emplace-constructible` from
1555 /// `arguments` (see {Requirements on `VALUE`}).
1556 template <class... ARGS>
1557 reference emplace_front(ARGS&&... arguments);
1558#endif
1559
1560 /// Append to the back of this list a copy of the specified `value`.
1561 /// This method offers full guarantee of rollback in case an exception
1562 /// is thrown. This method requires that the (template parameter)
1563 /// `VALUE` be `copy-constructible` (see {Requirements on `VALUE`}).
1564 void push_back(const value_type& value);
1565
1566 /// Append to the back of this list the specified move-insertable
1567 /// `value`. `value` is left in a valid but unspecified state. If an
1568 /// exception is thrown (other than by the move constructor of a
1569 /// non-copy-insertable `value_type`), this method has no effect. This
1570 /// method requires that the (template parameter) `VALUE` be
1571 /// `move-insertable` into this list (see {Requirements on `VALUE`}).
1572 void push_back(BloombergLP::bslmf::MovableRef<value_type> value);
1573
1574 /// Prepend to the front of this list a copy of the specified `value`.
1575 /// This method offers full guarantee of rollback in case an exception
1576 /// is thrown. This method requires that the (template parameter)
1577 /// `VALUE` be `copy-constructible` (see {Requirements on `VALUE`}).
1578 void push_front(const value_type& value);
1579
1580 /// Prepend to the front of this list the specified move-insertable
1581 /// `value`. `value` is left in a valid but unspecified state. If an
1582 /// exception is thrown (other than by the move constructor of a
1583 /// non-copy-insertable `value_type`), this method has no effect. This
1584 /// method requires that the (template parameter) `VALUE` be
1585 /// `move-insertable` into this list (see {Requirements on `VALUE`}).
1586 void push_front(BloombergLP::bslmf::MovableRef<value_type> value);
1587
1588 // *** random access inserts ***
1589
1590#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1591 /// Insert at the specified `position` in this list a newly created
1592 /// `value_type` object, constructed by forwarding `get_allocator()` (if
1593 /// required) and the specified (variable number of) `arguments` to the
1594 /// corresponding constructor of `value_type`, and return an iterator
1595 /// providing modifiable access to the newly created and inserted
1596 /// element. If an exception is thrown (other than by the copy
1597 /// constructor, move constructor, assignment operator, or move
1598 /// assignment operator of `value_type`), this method has no effect.
1599 /// This method requires that the (template parameter) `VALUE` be
1600 /// `move-insertable` into this list and `emplace-constructible` from
1601 /// `arguments` (see {Requirements on `VALUE`}). The behavior is
1602 /// undefined unless `position` is an iterator in the range
1603 /// `[cbegin() .. cend()]` (both endpoints included).
1604 template <class... ARGS>
1605 iterator emplace(const_iterator position, ARGS&&... arguments);
1606#endif
1607
1608 /// Insert at the specified `dstPosition` in this list a copy of the
1609 /// specified `value`, and return an iterator providing modifiable
1610 /// access to the newly inserted element. This method offers full
1611 /// guarantee of rollback in case an exception is thrown other than by
1612 /// the `VALUE` copy constructor or assignment operator. This method
1613 /// requires that the (template parameter) `VALUE` be `copy-insertable`
1614 /// into this list (see {Requirements on `VALUE`}). The behavior is
1615 /// undefined unless `dstPosition` is an iterator in the range
1616 /// `[cbegin() .. cend()] (both endpoints included)`.
1617 iterator insert(const_iterator dstPosition, const value_type& value);
1618
1619 /// Insert at the specified `dstPosition` in this list the specified
1620 /// move-insertable `value`, and return an iterator providing modifiable
1621 /// access to the newly inserted element. `value` is left in a valid
1622 /// but unspecified state. If an exception is thrown (other than by the
1623 /// copy constructor, move constructor, assignment operator, or move
1624 /// assignment operator of `value_type`), this method has no effect.
1625 /// This method requires that the (template parameter) `VALUE` be
1626 /// `move-insertable` into this list (see {Requirements on `VALUE`}).
1627 /// The behavior is undefined unless `dstPosition` is an iterator in the
1628 /// range `[cbegin() .. cend()]` (both endpoints included).
1630 BloombergLP::bslmf::MovableRef<value_type> value);
1631
1632 /// Insert at the specified `dstPosition` in this list the specified
1633 /// `numElements` copies of the specified `value`, and return an
1634 /// iterator providing modifiable access to the first element in the
1635 /// newly inserted sequence of elements. This method requires that the
1636 /// (template parameter) `VALUE` be `copy-insertable` into this list
1637 /// (see {Requirements on `VALUE`}). The behavior is undefined unless
1638 /// `dstPosition` is an iterator in the range `[cbegin() .. cend()]`
1639 /// (both endpoints included).
1641 size_type numElements,
1642 const value_type& value);
1643
1644 /// Insert at the specified `dstPosition` in this list the values in the
1645 /// range starting at the specified `first` and ending immediately
1646 /// before the specified `last` iterators of the (template parameter)
1647 /// type `INPUT_ITERATOR`, and return an iterator providing modifiable
1648 /// access to the first element in the newly inserted sequence of
1649 /// elements. The (template parameter) type `INPUT_ITERATOR` shall meet
1650 /// the requirements of an input iterator defined in the C++11 standard
1651 /// [input.iterators] providing access to values of a type convertible
1652 /// to `value_type`, and `value_type` must be `emplace-constructible`
1653 /// from `*i` into this list, where `i` is a dereferenceable iterator in
1654 /// the range `[first .. last)` (see {Requirements on `VALUE`}). The
1655 /// behavior is undefined unless `dstPosition` is an iterator in the
1656 /// range `[cbegin() .. cend()]` (both endpoints included), and `first`
1657 /// and `last` refer to a sequence of valid values where `first` is at a
1658 /// position at or before `last`.
1659 template <class INPUT_ITERATOR>
1661 INPUT_ITERATOR first,
1662 INPUT_ITERATOR last,
1663 typename enable_if<
1666 >::type * = 0)
1667 {
1668 // MS Visual Studio 2008 compiler requires that a function using
1669 // enable_if be in place inline.
1670
1671 if (first == last) {
1672 return dstPosition.unconst(); // RETURN
1673 }
1674
1675 // The return value should indicate the first node inserted. We can't
1676 // assume 'INPUT_ITERATOR' has a post-increment available.
1677
1678 iterator ret = insert(dstPosition, *first);
1679 for (++first; first != last; ++first) {
1680 insert(dstPosition, *first);
1681 }
1682
1683 return ret;
1684 }
1685
1686#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1687 /// Insert at the specified `dstPosition` in this list the value of each
1688 /// `value_type` object in the specified `values` initializer list, and
1689 /// return an iterator providing modifiable access to the first element
1690 /// in the newly inserted sequence of elements. This method requires
1691 /// that the (template parameter) `VALUE` be `copy-insertable` into this
1692 /// list (see {Requirements on `VALUE`}). The behavior is undefined
1693 /// unless `dstPosition` is an iterator in the range
1694 /// `[cbegin() .. cend()]` (both endpoints included).
1695 iterator insert(const_iterator dstPosition,
1696 std::initializer_list<value_type> values);
1697#endif
1698
1699 // *** list operations ***
1700
1701 void merge(list& other);
1702 /// Merge the specified sorted `other` list into this sorted list. This
1703 /// method has no effect if `other` is this list; otherwise, `other` is
1704 /// left empty. The behavior is undefined unless both `other` and this
1705 /// list are sorted in non-decreasing order according to the ordering
1706 /// provided by `operator<`, and unless both `other` and this list use
1707 /// the same allocator. `operator<` must define a strict weak ordering
1708 /// per `value_type` (see {Comparators and Strict Weak Ordering}).
1709 void merge(BloombergLP::bslmf::MovableRef<list> other);
1710
1711 /// Merge the specified sorted `other` list into this sorted list, using
1712 /// the specified binary `comparator` predicate to order elements. This
1713 /// method has no effect if `other` is this list; otherwise, `other` is
1714 /// left empty. The behavior is undefined unless both `other` and this
1715 /// list are sorted in non-decreasing order according to the ordering
1716 /// provided by `comparator`, and unless both `other` and this list use
1717 /// the same allocator.
1718 template <class COMPARE>
1719 void merge(list& other, COMPARE comparator);
1720 template <class COMPARE>
1721 void merge(BloombergLP::bslmf::MovableRef<list> other, COMPARE comparator);
1722
1723 /// Erase all the elements having the specified `value` from this list
1724 /// and return the number of erased elements.
1726
1727 /// Erase all the elements in this list for which the specified unary
1728 /// `predicate` returns `true` and return the number of erased elements.
1729 template <class PREDICATE>
1730 size_type remove_if(PREDICATE predicate);
1731
1732 /// Reverse the order of the elements in this list.
1734
1735 /// Sort this list in non-decreasing order according to the order
1736 /// provided by `operator<`. `operator<` must provide a strict weak
1737 /// ordering over `value_type` (see {Comparators and Strict Weak
1738 /// Ordering}). The sort is stable, meaning that if
1739 /// `!(a < b) && !(b < a)`, then the ordering of elements `a` and `b` in
1740 /// the sequence is preserved.
1741 void sort();
1742
1743 /// Sort this list in non-decreasing order according to the order
1744 /// provided by the specified `comparator` predicate. `comparator` must
1745 /// define a strict weak ordering over `value_type` (see {Comparators
1746 /// and Strict Weak Ordering}). The sort is stable, meaning that if
1747 /// `!comparator(a, b) && !comparator(b, a)`, then the ordering of
1748 /// elements `a` and `b` in the sequence is preserved.
1749 template <class COMPARE>
1750 void sort(COMPARE comparator);
1751
1752 void splice(const_iterator dstPosition,
1753 list& src);
1754 /// Remove all elements of the specified `src` list and insert them, in
1755 /// the same order, in this list at the specified `dstPosition`. The
1756 /// behavior is undefined unless `src` is not this list, this list and
1757 /// `src` use the same allocator, and `dstPosition` is in the range
1758 /// `[begin() .. end()]` (note both endpoints included).
1759 void splice(const_iterator dstPosition,
1760 BloombergLP::bslmf::MovableRef<list> src);
1761
1762 void splice(const_iterator dstPosition,
1763 list& src,
1764 const_iterator srcNode);
1765 /// Remove the single element at the specified `srcNode` from the
1766 /// specified `src` list, and insert it at the specified `dstPosition`
1767 /// in this list. The behavior is undefined unless `srcNode` refers to
1768 /// a valid element in `src`, this list and `src` use the same
1769 /// allocator, and `dstPosition` is in the range `[begin() .. end()]`
1770 /// (note both endpoints included). Note that `src` and `*this` may be
1771 /// the same list, in which case the element is moved to a (possibly)
1772 /// new position in the list.
1773 void splice(const_iterator dstPosition,
1774 BloombergLP::bslmf::MovableRef<list> src,
1775 const_iterator srcNode);
1776
1777 void splice(const_iterator dstPosition,
1778 list& src,
1779 const_iterator first,
1780 const_iterator last);
1781 /// Remove the elements in the specified range `[first .. last)` from
1782 /// the specified `src` list, and insert them, in the same order, at the
1783 /// specified `dstPosition` in this list. The behavior is undefined
1784 /// unless `[first .. last)` represents a range of valid elements in
1785 /// `src`, `dstPosition` is not in the range `[first .. last)`, this
1786 /// list and `src` use the same allocator, and `dstPosition` is in the
1787 /// range `[begin() .. end()]` (note both endpoints included). Note
1788 /// that `src` and `*this` may be the same list, in which case an entire
1789 /// sequence of nodes is moved to a (possibly) new position in this
1790 /// list.
1791 void splice(const_iterator dstPosition,
1792 BloombergLP::bslmf::MovableRef<list> src,
1793 const_iterator first,
1794 const_iterator last);
1795
1796 /// Erase from this list all but the first element of every consecutive
1797 /// group of elements that have the same value.
1798 void unique();
1799
1800 /// Erase from this list all but the first element of every consecutive
1801 /// group of elements for which the specified `binaryPredicate` returns
1802 /// `true` for any two consecutive elements in the group.
1803 template <class EQ_PREDICATE>
1804 void unique(EQ_PREDICATE binaryPredicate);
1805
1806 // *** misc ***
1807
1808 void swap(list& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(
1809 AllocTraits::is_always_equal::value);
1810 // Exchange the value of this object with that of the specified 'other'
1811 // object; also exchange the allocator of this object with that of
1812 // 'other' if the (template parameter) type 'ALLOCATOR' has the
1813 // 'propagate_on_container_swap' trait, and do not modify either
1814 // allocator otherwise. This method provides the no-throw
1815 // exception-safety guarantee. This operation has 'O[1]' complexity if
1816 // either this object was created with the same allocator as 'other' or
1817 // 'ALLOCATOR' has the 'propagate_on_container_swap' trait; otherwise,
1818 // it has 'O[n + m]' complexity, where 'n' and 'm' are the number of
1819 // elements in this object and 'other', respectively. Note that this
1820 // method's support for swapping objects created with different
1821 // allocators when 'ALLOCATOR' does not have the
1822 // 'propagate_on_container_swap' trait is a departure from the
1823 // C++ Standard.
1824
1825 // ACCESSORS
1826
1827 // *** iterators ***
1828
1830
1831 /// Return an iterator providing non-modifiable access to the first
1832 /// `value_type` object in the ordered sequence of `value_type` objects
1833 /// maintained by this list, or the `end` iterator if this list is
1834 /// empty.
1836
1838
1839 /// Return the past-the-end (forward) iterator providing non-modifiable
1840 /// access to this list.
1842
1844
1845 /// Return a reverse iterator providing non-modifiable access to the
1846 /// last element in this list, and the past-the-end reverse iterator if
1847 /// this list is empty.
1849
1851
1852 /// Return the past-the-end reverse iterator providing non-modifiable
1853 /// access to this list.
1855
1856 // *** size ***
1857
1858 /// Return `true` if this list has no elements, and `false` otherwise.
1860
1861 /// Return an upper bound on the largest number of elements that this
1862 /// list could possibly hold. Note that the return value of this
1863 /// function does not guarantee that this list can successfully grow
1864 /// that large, or even close to that large without running out of
1865 /// resources.
1867
1868 /// Return the number of elements in this list.
1870
1871 // *** element access ***
1872
1873 /// Return a reference providing non-modifiable access to the last
1874 /// element of this list. The behavior is undefined unless this list
1875 /// contains at least one element.
1876 const_reference back() const;
1877
1878 /// Return a reference providing non-modifiable access to the first
1879 /// element of this list. The behavior is undefined unless this list
1880 /// contains at least one element.
1881 const_reference front() const;
1882
1883 // *** misc ***
1884
1885 /// Return a copy of the allocator used for memory allocation by this
1886 /// list.
1888};
1889
1890#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1891// CLASS TEMPLATE DEDUCTION GUIDES
1892
1893/// Deduce the template parameter `VALUE` from the corresponding parameter
1894/// supplied to the constructor of `list`. This deduction guide does not
1895/// participate unless the supplied allocator is convertible to
1896/// `bsl::allocator<VALUE>`.
1897template <
1898 class SIZE_TYPE,
1899 class VALUE,
1900 class ALLOC,
1901 class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
1902 class = bsl::enable_if_t<
1903 bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>,
1904 class = bsl::enable_if_t<
1905 bsl::is_convertible_v<
1906 SIZE_TYPE,
1908 >
1909list(SIZE_TYPE, VALUE, ALLOC *) -> list<VALUE>;
1910
1911/// Deduce the template parameter `VALUE` from the `value_type` of the
1912/// iterators supplied to the constructor of `list`.
1913template <
1914 class INPUT_ITERATOR,
1915 class VALUE = typename
1916 BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>
1917 >
1918list(INPUT_ITERATOR, INPUT_ITERATOR) -> list<VALUE>;
1919
1920/// Deduce the template parameter `VALUE` from the `value_type` of the
1921/// iterators supplied to the constructor of `list`. Deduce the template
1922/// parameter `ALLOCATOR` from the allocator supplied to the constructor of
1923/// `list`. This deduction guide does not participate unless the supplied
1924/// allocator meets the requirements of a standard allocator.
1925template<
1926 class INPUT_ITERATOR,
1927 class ALLOCATOR,
1928 class VALUE = typename
1929 BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1930 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>>
1931list(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR) -> list<VALUE, ALLOCATOR>;
1932
1933/// Deduce the template parameter `VALUE` from the value_type of the
1934/// iterators supplied to the constructor of `list`. This deduction guide
1935/// does not participate unless the specified `ALLOC` is convertible to
1936/// `bsl::allocator<CHAR_TYPE>`.
1937template<
1938 class INPUT_ITERATOR,
1939 class ALLOC,
1940 class VALUE = typename
1941 BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1942 class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
1943 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1944 >
1945list(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
1946-> list<VALUE>;
1947
1948/// Deduce the template parameter `VALUE` from the value_type of the
1949/// intializer_list supplied to the constructor of `list`. This deduction
1950/// guide does not participate unless the specified `ALLOC` is convertible
1951/// to `bsl::allocator<CHAR_TYPE>`.
1952template<
1953 class VALUE,
1954 class ALLOC,
1955 class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
1956 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1957 >
1958list(std::initializer_list<VALUE>, ALLOC *)
1959-> list<VALUE>;
1960#endif
1961
1962// FREE OPERATORS
1963
1964/// Return `true` if the specified `lhs` and `rhs` objects have the same
1965/// value, and `false` otherwise. Two `list` objects `lhs` and `rhs` have
1966/// the same value if they have the same number of elements, and each
1967/// element in the ordered sequence of elements of `lhs` has the same value
1968/// as the corresponding element in the ordered sequence of elements of
1969/// `rhs`. This method requires that the (template parameter) type `VALUE`
1970/// be `equality-comparable` (see {Requirements on `VALUE`}).
1971template <class VALUE, class ALLOCATOR>
1973 const list<VALUE, ALLOCATOR>& rhs);
1974
1975#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1976
1977template <class VALUE, class ALLOCATOR>
1978bool operator!=(const list<VALUE, ALLOCATOR>& lhs,
1979 const list<VALUE, ALLOCATOR>& rhs);
1980 // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the
1981 // same value, and 'false' otherwise. Two 'list' objects 'lhs' and 'rhs'
1982 // do not have the same value if they do not have the same number of
1983 // elements, or some element in the ordered sequence of elements of 'lhs'
1984 // does not have the same value as the corresponding element in the ordered
1985 // sequence of elements of 'rhs'. This method requires that the
1986 // (template parameter) type 'VALUE' be 'equality-comparable' (see
1987 // {Requirements on 'VALUE'}).
1988
1989#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1990
1991#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1992
1993/// Perform a lexicographic three-way comparison of the specified `lhs` and
1994/// the specified `rhs` lists by using the comparison operators of `VALUE`
1995/// on each element; return the result of that comparison.
1996template <class VALUE, class ALLOCATOR>
1997BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE> operator<=>(
1998 const list<VALUE, ALLOCATOR>& lhs,
1999 const list<VALUE, ALLOCATOR>& rhs);
2000
2001#else
2002
2003template <class VALUE, class ALLOCATOR>
2004bool operator< (const list<VALUE, ALLOCATOR>& lhs,
2005 const list<VALUE, ALLOCATOR>& rhs);
2006 // Return 'true' if the value of the specified 'lhs' list is
2007 // lexicographically less than that of the specified 'rhs' list, and
2008 // 'false' otherwise. Given iterators 'i' and 'j' over the respective
2009 // sequences '[lhs.begin() .. lhs.end())' and '[rhs.begin() .. rhs.end())',
2010 // the value of list 'lhs' is lexicographically less than that of list
2011 // 'rhs' if 'true == *i < *j' for the first pair of corresponding iterator
2012 // positions where '*i < *j' and '*j < *i' are not both 'false'. If no
2013 // such corresponding iterator position exists, the value of 'lhs' is
2014 // lexicographically less than that of 'rhs' if 'lhs.size() < rhs.size()'.
2015 // This method requires that 'operator<', inducing a total order, be
2016 // defined for 'value_type'.
2017
2018template <class VALUE, class ALLOCATOR>
2019bool operator> (const list<VALUE, ALLOCATOR>& lhs,
2020 const list<VALUE, ALLOCATOR>& rhs);
2021 // Return 'true' if the value of the specified 'lhs' list is
2022 // lexicographically greater than that of the specified 'rhs' list, and
2023 // 'false' otherwise. The value of list 'lhs' is lexicographically greater
2024 // than that of list 'rhs' if 'rhs' is lexicographically less than 'lhs'
2025 // (see 'operator<'). This method requires that 'operator<', inducing a
2026 // total order, be defined for 'value_type'. Note that this operator
2027 // returns 'rhs < lhs'.
2028
2029template <class VALUE, class ALLOCATOR>
2030bool operator<=(const list<VALUE, ALLOCATOR>& lhs,
2031 const list<VALUE, ALLOCATOR>& rhs);
2032 // Return 'true' if the value of the specified 'lhs' list is
2033 // lexicographically less than or equal to that of the specified 'rhs'
2034 // list, and 'false' otherwise. The value of list 'lhs' is
2035 // lexicographically less than or equal to that of list 'rhs' if 'rhs' is
2036 // not lexicographically less than 'lhs' (see 'operator<'). This method
2037 // requires that 'operator<', inducing a total order, be defined for
2038 // 'value_type'. Note that this operator returns '!(rhs < lhs)'.
2039
2040template <class VALUE, class ALLOCATOR>
2041bool operator>=(const list<VALUE, ALLOCATOR>& lhs,
2042 const list<VALUE, ALLOCATOR>& rhs);
2043 // Return 'true' if the value of the specified 'lhs' list is
2044 // lexicographically greater than or equal to that of the specified 'rhs'
2045 // list, and 'false' otherwise. The value of list 'lhs' is
2046 // lexicographically greater than or equal to that of list 'rhs' if 'lhs'
2047 // is not lexicographically less than 'rhs' (see 'operator<'). This method
2048 // requires that 'operator<', inducing a total order, be defined for
2049 // 'value_type'. Note that this operator returns '!(lhs < rhs)'.
2050
2051#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2052
2053// FREE FUNCTIONS
2054
2055/// Erase all the elements in the specified list `l` that compare equal to
2056/// the specified `value`. Return the number of elements erased.
2057template <class VALUE, class ALLOCATOR, class BDE_OTHER_TYPE>
2059erase(list<VALUE, ALLOCATOR>& l, const BDE_OTHER_TYPE& value);
2060
2061/// Erase all the elements in the specified list `l` that satisfy the
2062/// specified predicate `predicate`. Return the number of elements erased.
2063template <class VALUE, class ALLOCATOR, class PREDICATE>
2065erase_if(list<VALUE, ALLOCATOR>& l, PREDICATE predicate);
2066
2067template <class VALUE, class ALLOCATOR>
2070 a.swap(b)));
2071 // Exchange the value of the specified 'a' object with that of the
2072 // specified 'b' object; also exchange the allocator of 'a' with that of
2073 // 'b' if the (template parameter) type 'ALLOCATOR' has the
2074 // 'propagate_on_container_swap' trait, and do not modify either allocator
2075 // otherwise. This function provides the no-throw exception-safety
2076 // guarantee. This operation has 'O[1]' complexity if either 'a' was
2077 // created with the same allocator as 'b' or 'ALLOCATOR' has the
2078 // 'propagate_on_container_swap' trait; otherwise, it has 'O[n + m]'
2079 // complexity, where 'n' and 'm' are the number of elements in 'a' and 'b',
2080 // respectively. Note that this function's support for swapping objects
2081 // created with different allocators when 'ALLOCATOR' does not have the
2082 // 'propagate_on_container_swap' trait is a departure from the C++
2083 // Standard.
2084
2085// ============================================================================
2086// INLINE AND TEMPLATE FUNCTION DEFINITIONS
2087// ============================================================================
2088
2089 // ------------------------
2090 // class bsl::List_Iterator
2091 // ------------------------
2092
2093// PRIVATE ACCESSORS
2094template <class VALUE>
2095inline
2097{
2098 return NcIter(d_node_p);
2099}
2100
2101// CREATORS
2102template <class VALUE>
2103inline
2105: d_node_p()
2106{
2107}
2108
2109template <class VALUE>
2110inline
2112: d_node_p(nodePtr)
2113{
2114}
2115
2116template <class VALUE>
2117inline
2119: d_node_p(other.d_node_p)
2120{
2121}
2122
2123// MANIPULATORS
2124template <class VALUE>
2125inline
2127{
2128 this->d_node_p = this->d_node_p->d_next_p;
2129 return *this;
2130}
2131
2132template <class VALUE>
2133inline
2135{
2136 this->d_node_p = this->d_node_p->d_prev_p;
2137 return *this;
2138}
2139
2140template <class VALUE>
2141inline
2143{
2144 List_Iterator temp = *this;
2145 this->operator++();
2146 return temp;
2147}
2148
2149template <class VALUE>
2150inline
2152{
2153 List_Iterator temp = *this;
2154 this->operator--();
2155 return temp;
2156}
2157
2158// ACCESSORS
2159template <class VALUE>
2160inline
2163{
2164 return this->d_node_p->d_value;
2165}
2166
2167template <class VALUE>
2168inline
2171{
2172 return BloombergLP::bsls::Util::addressOf(this->d_node_p->d_value);
2173}
2174
2175// FREE OPERATORS
2176template <class T1, class T2>
2177inline
2179{
2180 // Make sure that this comparison will only compile if 'T1' and 'T2' match
2181 // except for a possible difference in 'const'-ness.
2182
2184 typename bsl::remove_cv<T2>::type>::value));
2185
2186 return lhs.d_node_p == rhs.d_node_p;
2187}
2188
2189#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2190template <class T1, class T2>
2191inline
2193{
2194 // Make sure that this comparison will only compile if 'T1' and 'T2' match
2195 // except for a possible difference in 'const'-ness.
2196
2198 typename bsl::remove_cv<T2>::type>::value));
2199
2200 return ! (lhs == rhs);
2201}
2202#endif
2203
2204 // ------------------------------
2205 // class List_AllocAndSizeWrapper
2206 // ------------------------------
2207
2208// CREATOR
2209template <class VALUE, class ALLOCATOR>
2210inline
2212 const NodeAlloc& basicAllocator,
2213 size_type size)
2214: NodeAlloc(basicAllocator)
2215, d_size(size)
2216{
2217}
2218
2219// MANIPULATORS
2220template <class VALUE, class ALLOCATOR>
2221inline
2222typename List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::size_type&
2227
2228// ACCESSORS
2229template <class VALUE, class ALLOCATOR>
2230inline
2231const typename List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::size_type&
2233{
2234 return d_size;
2235}
2236
2237 // ----------------------
2238 // class List_NodeProctor
2239 // ----------------------
2240
2241// CREATORS
2242template <class VALUE, class ALLOCATOR>
2243inline
2245 list<VALUE, ALLOCATOR> *listPtr,
2246 NodePtr nodePtr)
2247: d_list_p(listPtr)
2248, d_node_p(nodePtr)
2249{
2250 BSLS_ASSERT_SAFE(listPtr);
2251 BSLS_ASSERT_SAFE(nodePtr);
2252}
2253
2254template <class VALUE, class ALLOCATOR>
2255inline
2257{
2258 if (d_node_p) {
2259 d_list_p->freeNode(d_node_p);
2260 }
2261}
2262
2263// MANIPULATORS
2264template <class VALUE, class ALLOCATOR>
2265inline
2267{
2268 d_node_p = 0;
2269}
2270
2271 // --------------------------
2272 // class List_DefaultLessThan
2273 // --------------------------
2274
2275// ACCESSORS
2276template <class VALUE>
2277inline
2279 const VALUE& lhs, const VALUE& rhs) const
2280{
2281 return lhs < rhs;
2282}
2283
2284 // ---------------
2285 // class bsl::list
2286 // ---------------
2287
2288// PRIVATE MANIPULATORS
2289template <class VALUE, class ALLOCATOR>
2290inline
2291typename list<VALUE, ALLOCATOR>::NodeAlloc&
2293{
2294 return d_alloc_and_size; // implicit cast to base class
2295}
2296
2297template <class VALUE, class ALLOCATOR>
2298inline
2299typename list<VALUE, ALLOCATOR>::NodePtr list<VALUE, ALLOCATOR>::allocateNode()
2300{
2301 NodePtr ret = AllocTraits::allocate(allocatorImp(), 1);
2302 ret->d_prev_p = 0;
2303 ret->d_next_p = 0;
2304 return ret;
2305}
2306
2307template <class VALUE, class ALLOCATOR>
2308inline
2309void list<VALUE, ALLOCATOR>::createSentinel()
2310{
2311 BSLS_ASSERT_SAFE(size_type(-1) == sizeRef() || 0 == sizeRef());
2312
2313 d_sentinel = allocateNode();
2314 linkNodes(d_sentinel, d_sentinel); // circular
2315 sizeRef() = 0;
2316}
2317
2318template <class VALUE, class ALLOCATOR>
2319inline
2320void list<VALUE, ALLOCATOR>::deleteNode(NodePtr node)
2321{
2322 BSLS_ASSERT_SAFE(node);
2323
2324 AllocTraits::destroy(allocatorImp(),
2325 BloombergLP::bsls::Util::addressOf(node->d_value));
2326 AllocTraits::deallocate(allocatorImp(), node, 1);
2327}
2328
2329template <class VALUE, class ALLOCATOR>
2330inline
2331void list<VALUE, ALLOCATOR>::destroyAll()
2332{
2333 clear();
2334 freeNode(d_sentinel);
2335 sizeRef() = size_type(-1);
2336}
2337
2338template <class VALUE, class ALLOCATOR>
2339inline
2340void list<VALUE, ALLOCATOR>::freeNode(NodePtr node)
2341{
2342 AllocTraits::deallocate(allocatorImp(), node, 1);
2343}
2344
2345template <class VALUE, class ALLOCATOR>
2346inline
2347typename list<VALUE, ALLOCATOR>::iterator
2348list<VALUE, ALLOCATOR>::insertNode(const_iterator position, NodePtr node)
2349{
2350 NodePtr next = position.d_node_p;
2351 NodePtr prev = next->d_prev_p;
2352 linkNodes(prev, node);
2353 linkNodes(node, next);
2354 ++sizeRef();
2355 return iterator(node);
2356}
2357
2358template <class VALUE, class ALLOCATOR>
2359inline
2360void list<VALUE, ALLOCATOR>::linkNodes(NodePtr prev, NodePtr next)
2361{
2362 prev->d_next_p = next;
2363 next->d_prev_p = prev;
2364}
2365
2366template <class VALUE, class ALLOCATOR>
2367template <class COMPARE>
2368typename list<VALUE, ALLOCATOR>::NodePtr
2370 NodePtr node2,
2371 NodePtr finish,
2372 COMPARE comparator)
2373{
2374 NodePtr pre = node1->d_prev_p;
2375
2376 // The only possible throwing operation is the comparator. Exception
2377 // neutrality is achieved by ensuring that this list is in a valid state,
2378 // with no disconnected nodes, before the comparator is called.
2379
2380 // Having the two sublists be contiguous parts of the same list has the
2381 // following advantages:
2382 //: 1 When we reach the end of a sublist, there is no "finalization" step
2383 //: where the end of the remaining sublist must be spliced onto the
2384 //: merged list.
2385 //: 2 No cleanup needed if an exception is thrown; the size and validity of
2386 //: the resulting list needs no adjustment.
2387
2388 while (node1 != node2 && node2 != finish) {
2389 // Loop invariants:
2390 // - The open range (pre, node1) is the current merged result
2391 // - The half-open range [node1, node2) is the 1st unmerged sequence
2392 // - The half-open range [node2, finish) is the 2nd unmerged sequence
2393
2394 if (comparator(node2->d_value, node1->d_value)) {
2395 // 'node2' should come before 'node1'.
2396
2397 // Find the end of the sequence of elements that belong before
2398 // node1 so that we can splice them all at once.
2399
2400 NodePtr lastMove = node2;
2401 NodePtr next2 = node2->d_next_p;
2402 while (next2 != finish && comparator(next2->d_value,
2403 node1->d_value)) {
2404 lastMove = next2;
2405 next2 = lastMove->d_next_p;
2406 }
2407
2408 linkNodes(node2->d_prev_p, next2);
2409 linkNodes(node1->d_prev_p, node2);
2410 linkNodes(lastMove, node1);
2411
2412 // Advance to next node in the 2nd unmerged sequence.
2413
2414 node2 = next2;
2415 }
2416 else {
2417 // Advance to next node in the 1st unmerged sequence.
2418
2419 node1 = node1->d_next_p;
2420 }
2421 }
2422
2423 return pre->d_next_p;
2424}
2425
2426template <class VALUE, class ALLOCATOR>
2427inline
2429{
2430 BSLS_ASSERT_SAFE(allocatorImp() == other->allocatorImp());
2431
2432 using std::swap;
2433
2434 swap(d_sentinel, other->d_sentinel);
2435 swap(sizeRef(), other->sizeRef());
2436}
2437
2438template <class VALUE, class ALLOCATOR>
2439inline
2440typename list<VALUE, ALLOCATOR>::AllocTraits::size_type&
2441list<VALUE, ALLOCATOR>::sizeRef() BSLS_KEYWORD_NOEXCEPT
2442{
2443 return d_alloc_and_size.size();
2444}
2445
2446template <class VALUE, class ALLOCATOR>
2447template <class COMPARE>
2448typename list<VALUE, ALLOCATOR>::NodePtr
2451 const COMPARE& comparator)
2452{
2453 BSLS_ASSERT(size > 0);
2454
2455 NodePtr node1 = *nodePtrPtr;
2456 if (size < 2) {
2457 return node1->d_next_p; // RETURN
2458 }
2459
2460 size_type half = size / 2;
2461
2462 NodePtr node2 = sortImp(&node1, half, comparator);
2463 NodePtr next = sortImp(&node2, size - half, comparator);
2464
2465 *nodePtrPtr = mergeImp(node1, node2, next, comparator);
2466 return next;
2467}
2468
2469// PRIVATE ACCESSORS
2470template <class VALUE, class ALLOCATOR>
2471inline
2472const typename list<VALUE, ALLOCATOR>::NodeAlloc&
2474{
2475 return d_alloc_and_size; // implicit cast to base class
2476}
2477
2478template <class VALUE, class ALLOCATOR>
2479inline
2480typename list<VALUE, ALLOCATOR>::NodePtr list<VALUE, ALLOCATOR>::headNode()
2481 const
2482{
2483 return d_sentinel->d_next_p;
2484}
2485
2486template <class VALUE, class ALLOCATOR>
2487inline
2488const typename list<VALUE, ALLOCATOR>::AllocTraits::size_type&
2489list<VALUE, ALLOCATOR>::sizeRef() const BSLS_KEYWORD_NOEXCEPT
2490{
2491 return d_alloc_and_size.size();
2492}
2493
2494// CREATORS
2495template <class VALUE, class ALLOCATOR>
2497: d_sentinel()
2498, d_alloc_and_size(ALLOCATOR(), 0)
2499{
2501 typename AllocTraits::size_type>::value));
2503 typename AllocTraits::difference_type>::value));
2504 createSentinel();
2505}
2506
2507template <class VALUE, class ALLOCATOR>
2508list<VALUE, ALLOCATOR>::list(const ALLOCATOR& basicAllocator)
2509: d_sentinel()
2510, d_alloc_and_size(basicAllocator, 0)
2511{
2512 createSentinel();
2513}
2514
2515template <class VALUE, class ALLOCATOR>
2517: d_sentinel()
2518, d_alloc_and_size(ALLOCATOR(), size_type(-1))
2519{
2520 // '*this' is in an invalid but destructible state (size == -1).
2521
2522 list tmp(this->allocatorImp());
2523
2524 // Default-construct (value-initialize) 'n' elements into 'tmp'. 'tmp's
2525 // destructor will clean up if an exception is thrown.
2526
2527 iterator pos = tmp.end();
2528 for (size_type i = 0; i < numElements; ++i) {
2529 tmp.emplace(pos);
2530 }
2531
2532 quickSwap(&tmp); // Leave 'tmp' in an invalid but destructible state.
2533}
2534
2535template <class VALUE, class ALLOCATOR>
2537 const ALLOCATOR& basicAllocator)
2538: d_sentinel()
2539, d_alloc_and_size(basicAllocator, size_type(-1))
2540{
2541 // '*this' is in an invalid but destructible state (size == -1).
2542
2543 list tmp(this->allocatorImp());
2544
2545 // Default-construct (value-initialize) 'n' elements into 'tmp'. 'tmp's
2546 // destructor will clean up if an exception is thrown.
2547
2548 const_iterator pos = tmp.cend();
2549 for (size_type i = 0; i < numElements; ++i) {
2550 tmp.emplace(pos);
2551 }
2552
2553 quickSwap(&tmp); // Leave 'tmp' in an invalid but destructible state.
2554}
2555
2556template <class VALUE, class ALLOCATOR>
2558 const VALUE& value,
2559 const ALLOCATOR& basicAllocator)
2560: d_sentinel()
2561, d_alloc_and_size(basicAllocator, size_type(-1))
2562{
2563 // '*this' is in an invalid but destructible state (size == -1).
2564
2565 list tmp(this->allocatorImp());
2566 tmp.insert(tmp.cbegin(), numElements, value); // 'tmp's destructor will
2567 // clean up on throw.
2568 quickSwap(&tmp); // Leave 'tmp' in an invalid but destructible state.
2569}
2570
2571template <class VALUE, class ALLOCATOR>
2573: d_sentinel()
2574, d_alloc_and_size(
2575 AllocTraits::select_on_container_copy_construction(original.allocatorImp()),
2576 size_type(-1))
2577{
2578 list tmp(this->allocatorImp());
2579
2580 tmp.insert(tmp.cbegin(), original.begin(), original.end());
2581
2582 quickSwap(&tmp); // Leave 'tmp' in an invalid but destructible state.
2583}
2584
2585template <class VALUE, class ALLOCATOR>
2587 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2588: d_sentinel()
2589, d_alloc_and_size(basicAllocator, size_type(-1))
2590{
2591 list tmp(this->allocatorImp());
2592
2593 tmp.insert(tmp.cbegin(), original.begin(), original.end());
2594
2595 quickSwap(&tmp); // Leave 'tmp' in an invalid but destructible state.
2596}
2597
2598template <class VALUE, class ALLOCATOR>
2599list<VALUE, ALLOCATOR>::list(BloombergLP::bslmf::MovableRef<list> original)
2600: d_sentinel()
2601, d_alloc_and_size(MoveUtil::access(original).allocatorImp(), 0)
2602{
2603 // Allocator should be copied, not moved, to ensure identical allocators
2604 // between this and 'original', otherwise 'swap' is undefined.
2605
2606 // An rvalue must be left in a valid state after a move.
2607
2608 createSentinel();
2609
2610 // '*this' is now in a valid state.
2611
2612 quickSwap(&MoveUtil::access(original));
2613}
2614
2615template <class VALUE, class ALLOCATOR>
2617 BloombergLP::bslmf::MovableRef<list> original,
2618 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2619: d_sentinel()
2620, d_alloc_and_size(basicAllocator, size_type(-1))
2621{
2622 // '*this' is in an invalid but destructible state (size == -1).
2623
2624 list& lvalue = original;
2625 if (this->allocatorImp() == lvalue.allocatorImp()) {
2626 // An rvalue must be left in a valid state after a move.
2627
2628 createSentinel(); // '*this' is now in a valid state.
2629 quickSwap(&lvalue);
2630 }
2631 else {
2632 // different allocators, must copy
2633
2634 list tmp(this->allocatorImp());
2635
2636 // Avoid relying on VALUE's copy c'tor unless no move c'tor is
2637 // available.
2638
2639 NodePtr endPtr = lvalue.d_sentinel;
2640 for (NodePtr p = lvalue.headNode(); endPtr != p; p = p->d_next_p) {
2641 tmp.emplace_back(MoveUtil::move(p->d_value));
2642 }
2643
2644 // Leave 'tmp' with all elements in a moved-from (but destructible)
2645 // state.
2646 quickSwap(&tmp);
2647 }
2648}
2649
2650#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2651template <class VALUE, class ALLOCATOR>
2652inline
2653list<VALUE, ALLOCATOR>::list(std::initializer_list<VALUE> values,
2654 const ALLOCATOR& basicAllocator)
2655: d_alloc_and_size(basicAllocator, size_type(-1))
2656{
2657 // '*this' is in an invalid but destructible state (size == -1). Create a
2658 // temporary list, 'tmp', with the specified data. If an exception is
2659 // thrown, 'tmp's destructor will clean up. Otherwise, swap 'tmp' with
2660 // '*this', leaving 'tmp' in an invalid but destructible state and leaving
2661 // '*this' fully constructed.
2662
2663 list tmp(this->allocatorImp());
2664 tmp.insert(tmp.cbegin(), values.begin(), values.end());
2665
2666 quickSwap(&tmp);
2667}
2668#endif
2669
2670template <class VALUE, class ALLOCATOR>
2672{
2673 // A size of -1 means a special incompletely-initialized state with no
2674 // sentinel, which requires no destruction.
2675
2676 if (sizeRef() != size_type(-1)) {
2677 destroyAll();
2678 }
2679}
2680
2681// MANIPULATORS
2682
2683 // *** assignment ***
2684
2685template <class VALUE, class ALLOCATOR>
2687{
2688 typedef typename
2689 AllocTraits::propagate_on_container_copy_assignment Propagate;
2690
2691 if (this != &rhs) {
2692 if (Propagate::value && allocatorImp() != rhs.allocatorImp()) {
2693 // Fully destroy old list before assigning allocator, then reset to
2694 // the empty list state.
2695 destroyAll();
2696 BloombergLP::bslma::AllocatorUtil::assign(&allocatorImp(),
2697 rhs.allocatorImp(),
2698 Propagate());
2699 createSentinel();
2700 }
2701 assign(rhs.begin(), rhs.end()); // Copy elements
2702 }
2703
2704 return *this;
2705}
2706
2707template <class VALUE, class ALLOCATOR>
2709 BloombergLP::bslmf::MovableRef<list> rhs)
2710 BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocTraits::is_always_equal::value)
2711{
2712 typedef typename
2713 AllocTraits::propagate_on_container_move_assignment Propagate;
2714
2715 list& lvalue = rhs;
2716
2717 if (this == &lvalue) {
2718 return *this; // RETURN
2719 }
2720
2721 if (this->allocatorImp() == lvalue.allocatorImp()) {
2722 // Equal allocators, just swap contents, will never throw.
2723
2724 quickSwap(&lvalue);
2725 }
2726 else if (Propagate::value) {
2727 // An rvalue must be left in a valid state after a move. Both '*this'
2728 // and 'rhs' must be left in valid states after a throw.
2729
2730 // Note: tearing everything down, then changing the allocator, then
2731 // doing 'quickSwap(&lvalue)' has a problem in that it could leave
2732 // 'rhs' in an invalid state, since if 'this->createSentinel()' were
2733 // called after the tearing down to render '*this' to a valid value,
2734 // 'createSentinel' might throw, leaving '*this' in an invalid state.
2735
2736 // Swap everything, including the allocator (here we are relying on the
2737 // C++11 standard, which requires that the allocator type not throw on
2738 // copy or assign).
2739
2740 list other(MoveUtil::move(lvalue));
2741
2742 using std::swap;
2743 using BloombergLP::bslma::AllocatorUtil;
2744
2745 AllocatorUtil::swap( // won't throw
2746 &allocatorImp(), &other.allocatorImp(), Propagate());
2747 swap(d_sentinel, other.d_sentinel); // swap of pointer type
2748 swap(sizeRef(), other.sizeRef()); // swap of fundamental type
2749 }
2750 else {
2751 // Unequal allocators and the allocator of the destination is to remain
2752 // unchanged. Copy using 'move', which will use copy functions where
2753 // 'value_type' doesn't support moving. Note that if this throws part
2754 // way through, both '*this' and 'rhs' may be left changed.
2755
2756 NodePtr dstPtr = this->headNode();
2757 const const_iterator dstEnd = this->cend();
2758 const NodePtr dstEndPtr = dstEnd.d_node_p;
2759
2760 NodePtr srcPtr = lvalue.headNode();
2761 const NodePtr srcEndPtr = lvalue.d_sentinel;
2762
2763 for (; srcEndPtr != srcPtr && dstEndPtr != dstPtr;
2764 srcPtr = srcPtr->d_next_p, dstPtr = dstPtr->d_next_p) {
2765 dstPtr->d_value = MoveUtil::move(srcPtr->d_value);
2766 }
2767
2768 erase(const_iterator(dstPtr), dstEnd);
2769
2770 for (; srcEndPtr != srcPtr; srcPtr = srcPtr->d_next_p) {
2771 emplace(dstEnd, MoveUtil::move(srcPtr->d_value));
2772 }
2773 }
2774
2775 return *this;
2776}
2777
2778#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2779template <class VALUE, class ALLOCATOR>
2780inline
2781list<VALUE, ALLOCATOR>& list<VALUE, ALLOCATOR>::operator=(
2782 std::initializer_list<VALUE> rhs)
2783{
2784 assign(rhs.begin(), rhs.end());
2785 return *this;
2786}
2787#endif
2788
2789template <class VALUE, class ALLOCATOR>
2790void list<VALUE, ALLOCATOR>::assign(size_type numElements, const VALUE& value)
2791{
2792 NodePtr dst_p = this->headNode();
2793 const const_iterator dstEnd = this->cend();
2794 const NodePtr dstEnd_p = dstEnd.d_node_p;
2795
2796 for (; 0 < numElements && dstEnd_p != dst_p;
2797 --numElements, dst_p = dst_p->d_next_p) {
2798 dst_p->d_value = value;
2799 }
2800
2801 erase(const_iterator(dst_p), dstEnd);
2802
2803 for (; 0 < numElements; --numElements) {
2804 insert(dstEnd, value);
2805 }
2806}
2807
2808#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2809template <class VALUE, class ALLOCATOR>
2810inline
2811void list<VALUE, ALLOCATOR>::assign(std::initializer_list<VALUE> values)
2812{
2813 assign(values.begin(), values.end());
2814}
2815#endif
2816
2817 // *** iterators ***
2818
2819template <class VALUE, class ALLOCATOR>
2820inline
2821typename list<VALUE, ALLOCATOR>::iterator list<VALUE, ALLOCATOR>::begin()
2823{
2824 return iterator(headNode());
2825}
2826
2827template <class VALUE, class ALLOCATOR>
2828inline
2834
2835template <class VALUE, class ALLOCATOR>
2836inline
2842
2843template <class VALUE, class ALLOCATOR>
2844inline
2850
2851 // *** modify size ***
2852
2853template <class VALUE, class ALLOCATOR>
2854inline
2856{
2857 const NodePtr e = d_sentinel;
2858 for (NodePtr p = d_sentinel->d_next_p; e != p; ) {
2859 NodePtr condemned = p;
2860 p = p->d_next_p;
2861 deleteNode(condemned);
2862 }
2863
2864 linkNodes(d_sentinel, d_sentinel);
2865 sizeRef() = 0;
2866}
2867
2868template <class VALUE, class ALLOCATOR>
2870{
2871 if (newSize > sizeRef()) {
2872 const_iterator ce = cend();
2873 do {
2874 emplace(ce);
2875 } while (newSize > sizeRef());
2876 }
2877 else {
2878 NodePtr e = d_sentinel;
2879 NodePtr p = e->d_prev_p;
2880 for (size_type d = sizeRef() - newSize; d > 0; --d) {
2881 NodePtr condemned = p;
2882 p = p->d_prev_p;
2883 deleteNode(condemned);
2884 }
2885 linkNodes(p, e);
2886 sizeRef() = newSize;
2887 }
2888}
2889
2890template <class VALUE, class ALLOCATOR>
2891void list<VALUE, ALLOCATOR>::resize(size_type newSize, const VALUE& value)
2892{
2893 if (newSize > sizeRef()) {
2894 const_iterator ce = cend();
2895 do {
2896 emplace(ce, value);
2897 } while (newSize > sizeRef());
2898 }
2899 else {
2900 NodePtr e = d_sentinel;
2901 NodePtr p = e->d_prev_p;
2902 for (size_type d = sizeRef() - newSize; d > 0; --d) {
2903 NodePtr condemned = p;
2904 p = p->d_prev_p;
2905 deleteNode(condemned);
2906 }
2907 linkNodes(p, e);
2908 sizeRef() = newSize;
2909 }
2910}
2911
2912 // element access:
2913
2914template <class VALUE, class ALLOCATOR>
2915inline
2918{
2919 BSLS_ASSERT_SAFE(sizeRef() > 0);
2920
2921 return d_sentinel->d_prev_p->d_value;
2922}
2923
2924template <class VALUE, class ALLOCATOR>
2925inline
2928{
2929 BSLS_ASSERT_SAFE(sizeRef() > 0);
2930
2931 return headNode()->d_value;
2932}
2933
2934 // *** end erase ***
2935
2936template <class VALUE, class ALLOCATOR>
2937inline
2939{
2940 BSLS_ASSERT_SAFE(sizeRef() > 0);
2941
2942 erase(--cend());
2943}
2944
2945template <class VALUE, class ALLOCATOR>
2946inline
2948{
2949 BSLS_ASSERT_SAFE(sizeRef() > 0);
2950
2951 erase(cbegin());
2952}
2953
2954 // *** random access erase ***
2955
2956template <class VALUE, class ALLOCATOR>
2959{
2960 BSLS_ASSERT(position.d_node_p != d_sentinel);
2961
2962 NodePtr condemned = position.d_node_p;
2963 iterator ret(condemned->d_next_p);
2964
2965 linkNodes(condemned->d_prev_p, condemned->d_next_p);
2966 deleteNode(condemned);
2967 --sizeRef();
2968 return ret;
2969}
2970
2971template <class VALUE, class ALLOCATOR>
2974{
2975 NodePtr p = dstBegin.d_node_p;
2976 const NodePtr e = dstEnd. d_node_p;
2977
2978 linkNodes(p->d_prev_p, e);
2979
2980 size_type numDeleted = 0;
2981 for (; e != p; ++numDeleted) {
2982 NodePtr condemned = p;
2983 p = p->d_next_p;
2984 deleteNode(condemned);
2985 }
2986
2987 sizeRef() -= numDeleted;
2988
2989 return iterator(e);
2990}
2991
2992 // *** end inserts ***
2993
2994#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2995template <class VALUE, class ALLOCATOR>
2996template <class... ARGS>
2997inline
3000{
3001 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
3002 return back();
3003}
3004#endif
3005
3006#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3007template <class VALUE, class ALLOCATOR>
3008template <class... ARGS>
3009inline
3012{
3013 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
3014 return front();
3015}
3016#endif
3017
3018template <class VALUE, class ALLOCATOR>
3019inline
3021{
3022 emplace(cend(), value);
3023}
3024
3025template <class VALUE, class ALLOCATOR>
3026inline
3028 BloombergLP::bslmf::MovableRef<VALUE> value)
3029{
3030 emplace(cend(), MoveUtil::move(value));
3031}
3032
3033template <class VALUE, class ALLOCATOR>
3034inline
3036{
3037 emplace(cbegin(), value);
3038}
3039
3040template <class VALUE, class ALLOCATOR>
3041inline
3043 BloombergLP::bslmf::MovableRef<VALUE> value)
3044{
3045 emplace(cbegin(), MoveUtil::move(value));
3046}
3047
3048 // *** random access inserts ***
3049
3050#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3051template <class VALUE, class ALLOCATOR>
3052template <class... ARGS>
3055{
3056 NodePtr p = allocateNode();
3057 NodeProctor proctor(this, p);
3058 AllocTraits::construct(allocatorImp(),
3059 BloombergLP::bsls::Util::addressOf(p->d_value),
3060 BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
3061 proctor.release();
3062 return insertNode(position, p);
3063}
3064#endif
3065
3066template <class VALUE, class ALLOCATOR>
3068list<VALUE, ALLOCATOR>::insert(const_iterator dstPosition, const VALUE& value)
3069{
3070 return emplace(dstPosition, value);
3071}
3072
3073template <class VALUE, class ALLOCATOR>
3076 const_iterator dstPosition,
3077 BloombergLP::bslmf::MovableRef<VALUE> value)
3078{
3079 return emplace(dstPosition, MoveUtil::move(value));
3080}
3081
3082template <class VALUE, class ALLOCATOR>
3085 size_type numElements,
3086 const VALUE& value)
3087{
3088 if (0 == numElements) {
3089 return dstPosition.unconst(); // RETURN
3090 }
3091
3092 // Remember the position of the first node inserted before 'dstPosition'.
3093
3094 iterator ret = emplace(dstPosition, value);
3095
3096 // And put the rest of the nodes after it.
3097
3098 for (--numElements; numElements > 0; --numElements) {
3099 emplace(dstPosition, value);
3100 }
3101
3102 return ret;
3103}
3104
3105#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3106template <class VALUE, class ALLOCATOR>
3108list<VALUE, ALLOCATOR>::insert(const_iterator dstPosition,
3109 std::initializer_list<VALUE> values)
3110{
3111 return insert(dstPosition, values.begin(), values.end());
3112}
3113#endif
3114
3115 // *** list operations ***
3116
3117template <class VALUE, class ALLOCATOR>
3118inline
3120{
3121 BSLS_ASSERT_SAFE(this->allocatorImp() == other.allocatorImp());
3122
3123 merge(other, DefaultLessThan());
3124}
3125
3126template <class VALUE, class ALLOCATOR>
3127inline
3128void list<VALUE, ALLOCATOR>::merge(BloombergLP::bslmf::MovableRef<list> other)
3129{
3130 list& lvalue = other;
3131
3132 BSLS_ASSERT_SAFE(this->allocatorImp() == lvalue.allocatorImp());
3133
3134 merge(lvalue, DefaultLessThan());
3135}
3136
3137template <class VALUE, class ALLOCATOR>
3138template <class COMPARE>
3139void list<VALUE, ALLOCATOR>::merge(list& other, COMPARE comparator)
3140{
3141 if (&other == this) {
3142 return; // RETURN
3143 }
3144
3145 BSLS_ASSERT(this->allocatorImp() == other.allocatorImp());
3146
3147 if (other.empty()) {
3148 // This is an important special case to avoid pointing to sentinel.
3149
3150 return; // RETURN
3151 }
3152
3153 // Splice 'other' to the end of '*this', but remember the first node of the
3154 // appended sequence.
3155
3156 NodePtr xfirst = other.d_sentinel->d_next_p;
3157 splice(end(), other);
3158
3159 // Call 'mergeImp' with a pointer to the first node of the original list, a
3160 // pointer to the first node of 'other' (which also ends the original
3161 // list), and a pointer to the sentinel (which now ends 'other').
3162
3163 mergeImp(d_sentinel->d_next_p, xfirst, d_sentinel, comparator);
3164}
3165
3166template <class VALUE, class ALLOCATOR>
3167template <class COMPARE>
3168inline
3170 BloombergLP::bslmf::MovableRef<list> other,
3171 COMPARE comparator)
3172{
3173 list& lvalue = other;
3174
3175 BSLS_ASSERT_SAFE(this->allocatorImp() == lvalue.allocatorImp());
3176
3177 merge(lvalue, comparator);
3178}
3179
3180template <class VALUE, class ALLOCATOR>
3183{
3184 const size_type origSize = this->size();
3185 const const_iterator e = cend();
3186 for (const_iterator i = cbegin(); e != i; ) {
3187 // Standard says to use 'operator==', not 'std::equal_to'.
3188
3189 if (value == *i) {
3190 i = erase(i);
3191 }
3192 else {
3193 ++i;
3194 }
3195 }
3196
3197 return origSize - this->size();
3198}
3199
3200template <class VALUE, class ALLOCATOR>
3201template <class PREDICATE>
3204{
3205 const size_type origSize = this->size();
3206 const iterator e = end();
3207 for (iterator i = begin(); e != i; ) {
3208 if (predicate(*i)) {
3209 i = erase(i);
3210 }
3211 else {
3212 ++i;
3213 }
3214 }
3215
3216 return origSize - this->size();
3217}
3218
3219template <class VALUE, class ALLOCATOR>
3220void list<VALUE, ALLOCATOR>::reverse() BSLS_KEYWORD_NOEXCEPT
3221{
3222 NodePtr sentinel = d_sentinel;
3223 NodePtr p = sentinel;
3224
3225 do {
3226 NodePtr tmp = p->d_next_p;
3227 p->d_next_p = p->d_prev_p;
3228 p->d_prev_p = tmp;
3229 p = tmp;
3230 } while (p != sentinel);
3231}
3232
3233template <class VALUE, class ALLOCATOR>
3234inline
3236{
3237 sort(DefaultLessThan());
3238}
3239
3240template <class VALUE, class ALLOCATOR>
3241template <class COMPARE>
3242void list<VALUE, ALLOCATOR>::sort(COMPARE comparator)
3243{
3244 if (sizeRef() < 2) {
3245 return; // RETURN
3246 }
3247 NodePtr node1 = d_sentinel->d_next_p;
3248 sortImp(&node1, size(), comparator);
3249}
3250
3251template <class VALUE, class ALLOCATOR>
3253{
3254 BSLS_ASSERT(allocatorImp() == src.allocatorImp());
3255 BSLS_ASSERT(&src != this);
3256
3257 if (src.empty()) {
3258 return; // RETURN
3259 }
3260
3261 NodePtr pPos = dstPosition.d_node_p;
3262 NodePtr pFirst = src.headNode();
3263 NodePtr pLast = src.d_sentinel->d_prev_p;
3264 size_type n = src.sizeRef();
3265
3266 // Splice contents out of 'src'.
3267
3268 linkNodes(src.d_sentinel, src.d_sentinel);
3269 src.sizeRef() = 0;
3270
3271 // Splice contents into '*this'.
3272
3273 linkNodes(pPos->d_prev_p, pFirst);
3274 linkNodes(pLast, pPos);
3275 sizeRef() += n;
3276}
3277
3278template <class VALUE, class ALLOCATOR>
3279inline
3281 const_iterator dstPosition,
3282 BloombergLP::bslmf::MovableRef<list> src)
3283{
3284 splice(dstPosition, MoveUtil::access(src));
3285}
3286
3287template <class VALUE, class ALLOCATOR>
3289 list& src,
3290 const_iterator srcNode)
3291{
3292 BSLS_ASSERT(allocatorImp() == src.allocatorImp());
3293
3294 NodePtr pPos = dstPosition.d_node_p;
3295 NodePtr pSrcNode = srcNode.d_node_p;
3296 NodePtr pAfterSrcNode = pSrcNode->d_next_p;
3297
3298 if (pPos == pSrcNode || pPos == pAfterSrcNode) {
3299 return; // RETURN
3300 }
3301
3302 // Splice contents out of 'src'.
3303
3304 linkNodes(pSrcNode->d_prev_p, pAfterSrcNode);
3305 --src.sizeRef();
3306
3307 // Splice contents into '*this'.
3308
3309 linkNodes(pPos->d_prev_p, pSrcNode);
3310 linkNodes(pSrcNode, pPos);
3311 ++sizeRef();
3312}
3313
3314template <class VALUE, class ALLOCATOR>
3315inline
3317 const_iterator dstPosition,
3318 BloombergLP::bslmf::MovableRef<list> src,
3319 const_iterator srcNode)
3320{
3321 splice(dstPosition, MoveUtil::access(src), srcNode);
3322}
3323
3324template <class VALUE, class ALLOCATOR>
3326 list& src,
3327 const_iterator first,
3328 const_iterator last)
3329{
3330 BSLS_ASSERT(allocatorImp() == src.allocatorImp());
3331
3332 size_type n = bsl::distance(first, last);
3333
3334 if (0 == n) {
3335 return; // RETURN
3336 }
3337
3338 NodePtr pPos = dstPosition.d_node_p;
3339 NodePtr pFirst = first.d_node_p;
3340 NodePtr pLast = last.d_node_p;
3341 NodePtr pSrcLast = pLast->d_prev_p;
3342
3343 // Splice contents out of 'src'.
3344
3345 linkNodes(pFirst->d_prev_p, pLast);
3346 src.sizeRef() -= n;
3347
3348 // Splice contents into '*this'.
3349
3350 linkNodes(pPos->d_prev_p, pFirst);
3351 linkNodes(pSrcLast, pPos);
3352 sizeRef() += n;
3353}
3354
3355template <class VALUE, class ALLOCATOR>
3356inline
3358 const_iterator dstPosition,
3359 BloombergLP::bslmf::MovableRef<list> src,
3360 const_iterator first,
3361 const_iterator last)
3362{
3363 splice(dstPosition, MoveUtil::access(src), first, last);
3364}
3365
3366template <class VALUE, class ALLOCATOR>
3368{
3369 if (size() < 2) {
3370 return; // RETURN
3371 }
3372
3373 iterator i = begin();
3374 iterator e = end();
3375 while (i != e) {
3376 reference match = *i++;
3377 while (i != e && *i == match) {
3378 i = erase(i);
3379 }
3380 }
3381}
3382
3383template <class VALUE, class ALLOCATOR>
3384template <class EQ_PREDICATE>
3385void list<VALUE, ALLOCATOR>::unique(EQ_PREDICATE binaryPredicate)
3386{
3387 if (size() < 2) {
3388 return; // RETURN
3389 }
3390
3391 iterator i = begin();
3392 iterator e = end();
3393 while (i != e) {
3394 reference match = *i++;
3395 while (i != e && binaryPredicate(*i, match)) {
3396 i = erase(i);
3397 }
3398 }
3399}
3400
3401 // *** misc ***
3402
3403template <class VALUE, class ALLOCATOR>
3405 BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocTraits::is_always_equal::value)
3406{
3407 // C++11 behavior for member 'swap': undefined for unequal allocators.
3408 // BSLS_ASSERT(allocatorImp() == other.allocatorImp());
3409
3410 typedef typename AllocTraits::propagate_on_container_swap Propagate;
3411
3412 if (Propagate::value) {
3413 using std::swap;
3414 using BloombergLP::bslma::AllocatorUtil;
3415
3416 AllocatorUtil::swap( // Won't throw
3417 &allocatorImp(), &other.allocatorImp(), Propagate());
3418 swap(d_sentinel, other.d_sentinel);
3419 swap(sizeRef(), other.sizeRef());
3420 }
3422 allocatorImp() == other.allocatorImp())) {
3423 quickSwap(&other);
3424 }
3425 else {
3427
3428 // Create copies using the move constructor, then swap both containers
3429 // with them. Note that if no move constructor exists, but a copy
3430 // constructor does, the copy constructor will be used.
3431
3432 // Also note that if either of these copies throws, it could leave the
3433 // two containers in a changed state. They are, however, guaranteed to
3434 // be left in valid state.
3435
3436 list toOtherCopy(MoveUtil::move(*this), other.allocatorImp());
3437 list toThisCopy( MoveUtil::move(other), this->allocatorImp());
3438
3439 toOtherCopy.quickSwap(&other);
3440 toThisCopy .quickSwap(this);
3441 }
3442}
3443
3444// ACCESSORS
3445
3446 // *** iterators ***
3447
3448template <class VALUE, class ALLOCATOR>
3449inline
3450typename list<VALUE, ALLOCATOR>::const_iterator
3452{
3453 return const_iterator(headNode());
3454}
3455
3456template <class VALUE, class ALLOCATOR>
3457inline
3458typename list<VALUE, ALLOCATOR>::const_iterator
3460{
3461 return const_iterator(d_sentinel);
3462}
3463
3464template <class VALUE, class ALLOCATOR>
3465inline
3471
3472template <class VALUE, class ALLOCATOR>
3473inline
3476{
3477 return end();
3478}
3479
3480template <class VALUE, class ALLOCATOR>
3481inline
3487
3488template <class VALUE, class ALLOCATOR>
3489inline
3495
3496template <class VALUE, class ALLOCATOR>
3497inline
3503
3504template <class VALUE, class ALLOCATOR>
3505inline
3511
3512 // *** size ***
3513
3514template <class VALUE, class ALLOCATOR>
3515inline
3517{
3518 return 0 == sizeRef();
3519}
3520
3521template <class VALUE, class ALLOCATOR>
3522inline
3525{
3526 return AllocTraits::max_size(allocatorImp());
3527}
3528
3529template <class VALUE, class ALLOCATOR>
3530inline
3533{
3534 return sizeRef();
3535}
3536
3537 // *** element access ***
3538
3539template <class VALUE, class ALLOCATOR>
3540inline
3543{
3544 BSLS_ASSERT_SAFE(sizeRef() > 0);
3545
3546 return d_sentinel->d_prev_p->d_value;
3547}
3548
3549template <class VALUE, class ALLOCATOR>
3550inline
3553{
3554 BSLS_ASSERT_SAFE(sizeRef() > 0);
3555
3556 return headNode()->d_value;
3557}
3558
3559 // *** misc ***
3560
3561template <class VALUE, class ALLOCATOR>
3562inline
3564{
3565 return allocatorImp();
3566}
3567
3568} // close namespace bsl
3569
3570// FREE OPERATORS
3571template <class VALUE, class ALLOCATOR>
3572inline
3573bool bsl::operator==(const list<VALUE, ALLOCATOR>& lhs,
3574 const list<VALUE, ALLOCATOR>& rhs)
3575{
3576 return BloombergLP::bslalg::RangeCompare::equal(lhs.begin(),
3577 lhs.end(),
3578 lhs.size(),
3579 rhs.begin(),
3580 rhs.end(),
3581 rhs.size());
3582}
3583
3584#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
3585
3586template <class VALUE, class ALLOCATOR>
3587inline
3588bool bsl::operator!=(const list<VALUE, ALLOCATOR>& lhs,
3589 const list<VALUE, ALLOCATOR>& rhs)
3590{
3591 return ! (lhs == rhs);
3592}
3593
3594#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
3595
3596#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
3597
3598template <class VALUE, class ALLOCATOR>
3599inline
3600BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE> bsl::operator<=>(
3601 const list<VALUE, ALLOCATOR>& lhs,
3602 const list<VALUE, ALLOCATOR>& rhs)
3603{
3604 return bsl::lexicographical_compare_three_way(
3605 lhs.begin(),
3606 lhs.end(),
3607 rhs.begin(),
3608 rhs.end(),
3609 BloombergLP::bslalg::SynthThreeWayUtil::compare);
3610}
3611
3612#else
3613
3614template <class VALUE, class ALLOCATOR>
3615inline
3616bool bsl::operator< (const list<VALUE, ALLOCATOR>& lhs,
3617 const list<VALUE, ALLOCATOR>& rhs)
3618{
3619 return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.begin(),
3620 lhs.end(),
3621 lhs.size(),
3622 rhs.begin(),
3623 rhs.end(),
3624 rhs.size());
3625}
3626
3627template <class VALUE, class ALLOCATOR>
3628inline
3629bool bsl::operator> (const list<VALUE, ALLOCATOR>& lhs,
3630 const list<VALUE, ALLOCATOR>& rhs)
3631{
3632 return rhs < lhs;
3633}
3634
3635template <class VALUE, class ALLOCATOR>
3636inline
3637bool bsl::operator<=(const list<VALUE, ALLOCATOR>& lhs,
3638 const list<VALUE, ALLOCATOR>& rhs)
3639{
3640 return !(rhs < lhs);
3641}
3642
3643template <class VALUE, class ALLOCATOR>
3644inline
3645bool bsl::operator>=(const list<VALUE, ALLOCATOR>& lhs,
3646 const list<VALUE, ALLOCATOR>& rhs)
3647{
3648 return !(lhs < rhs);
3649}
3650
3651#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
3652
3653// FREE FUNCTIONS
3654template <class VALUE, class ALLOCATOR, class BDE_OTHER_TYPE>
3656bsl::erase(list<VALUE, ALLOCATOR>& l, const BDE_OTHER_TYPE& value)
3657{
3658 // We could use the erase/remove idiom here like we do in the other
3659 // sequence containers, but this is more efficient, since we just unlink
3660 // and delete nodes from the list.
3661 typename list<VALUE, ALLOCATOR>::size_type oldSize = l.size();
3662 for (typename list<VALUE, ALLOCATOR>::iterator it = l.begin();
3663 it != l.end();)
3664 {
3665 if (value == *it) {
3666 it = l.erase(it);
3667 }
3668 else {
3669 ++it;
3670 }
3671 }
3672 return oldSize - l.size();
3673}
3674
3675template <class VALUE, class ALLOCATOR, class PREDICATE>
3677bsl::erase_if(list<VALUE, ALLOCATOR>& l, PREDICATE predicate)
3678{
3679 return BloombergLP::bslstl::AlgorithmUtil::containerEraseIf(l, predicate);
3680}
3681
3682template <class VALUE, class ALLOCATOR>
3683inline
3684void bsl::swap(list<VALUE, ALLOCATOR>& a, list<VALUE, ALLOCATOR>& b)
3686 a.swap(b)))
3687{
3688 a.swap(b);
3689}
3690
3691// ============================================================================
3692// TYPE TRAITS
3693// ============================================================================
3694
3695// Type traits for STL *sequence* containers:
3696//: o A sequence container defines STL iterators.
3697//: o A sequence container uses 'bslma' allocators if the (template parameter)
3698//: type 'ALLOCATOR' is convertible from 'bslma::Allocator*'.
3699
3700
3701
3702namespace bslalg {
3703
3704template <class VALUE, class ALLOCATOR>
3705struct HasStlIterators<bsl::list<VALUE, ALLOCATOR> >
3707{};
3708
3709} // close namespace bslalg
3710
3711namespace bslma {
3712
3713template <class VALUE, class ALLOCATOR>
3714struct UsesBslmaAllocator<bsl::list<VALUE, ALLOCATOR> >
3715 : bsl::is_convertible<Allocator*, ALLOCATOR>
3716{};
3717
3718} // close namespace bslma
3719
3720namespace bslmf {
3721
3722// A list is bitwise movable if its allocator is bitwise movable.
3723
3724template <class VALUE, class ALLOCATOR>
3725struct IsBitwiseMoveable<bsl::list<VALUE, ALLOCATOR> >
3726 : BloombergLP::bslmf::IsBitwiseMoveable<ALLOCATOR>
3727{};
3728
3729} // close namespace bslmf
3730
3731
3732#endif // End C++11 code
3733
3734#endif
3735
3736// ----------------------------------------------------------------------------
3737// Copyright 2019 Bloomberg Finance L.P.
3738//
3739// Licensed under the Apache License, Version 2.0 (the "License");
3740// you may not use this file except in compliance with the License.
3741// You may obtain a copy of the License at
3742//
3743// http://www.apache.org/licenses/LICENSE-2.0
3744//
3745// Unless required by applicable law or agreed to in writing, software
3746// distributed under the License is distributed on an "AS IS" BASIS,
3747// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3748// See the License for the specific language governing permissions and
3749// limitations under the License.
3750// ----------------------------- END-OF-FILE ----------------------------------
3751
3752/** @} */
3753/** @} */
3754/** @} */
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements contained by this deque.
Definition bslstl_deque.h:2074
Definition bslstl_list.h:915
List_AllocAndSizeWrapper(const NodeAlloc &basicAllocator, size_type size)
Definition bslstl_list.h:2211
size_type & size()
Definition bslstl_list.h:2223
const size_type & size() const
Definition bslstl_list.h:2232
Definition bslstl_list.h:739
List_Iterator & operator--()
Definition bslstl_list.h:2134
friend class list
Definition bslstl_list.h:753
VALUE * pointer
Definition bslstl_list.h:773
List_Iterator & operator++()
Definition bslstl_list.h:2126
friend class List_Iterator
Definition bslstl_list.h:756
reference operator*() const
Definition bslstl_list.h:2162
friend bool operator==(List_Iterator< T1 >, List_Iterator< T2 >)
Definition bslstl_list.h:2178
std::bidirectional_iterator_tag iterator_category
Definition bslstl_list.h:770
VALUE & reference
Definition bslstl_list.h:774
NcType value_type
Definition bslstl_list.h:771
BloombergLP::bsls::Types::IntPtr difference_type
Definition bslstl_list.h:772
pointer operator->() const
Definition bslstl_list.h:2170
Definition bslstl_list.h:974
AllocTraits::pointer NodePtr
Definition bslstl_list.h:990
void release()
Definition bslstl_list.h:2266
~List_NodeProctor()
Definition bslstl_list.h:2256
Definition bslstl_list.h:700
Definition bslma_bslallocator.h:580
Forward declaration required by List_NodeProctor.
Definition bslstl_list.h:1033
void reverse() BSLS_KEYWORD_NOEXCEPT
Reverse the order of the elements in this list.
Definition bslstl_list.h:3220
void resize(size_type newSize)
Definition bslstl_list.h:2869
list(const list &original, const typename type_identity< ALLOCATOR >::type &basicAllocator)
Definition bslstl_list.h:2586
void merge(BloombergLP::bslmf::MovableRef< list > other)
Definition bslstl_list.h:3128
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_list.h:3563
const VALUE & const_reference
Definition bslstl_list.h:1069
list(const list &original)
Definition bslstl_list.h:2572
const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_list.h:3491
void push_back(BloombergLP::bslmf::MovableRef< value_type > value)
Definition bslstl_list.h:3027
VALUE & reference
Definition bslstl_list.h:1068
list(BloombergLP::bslmf::MovableRef< list > original, const typename type_identity< ALLOCATOR >::type &basicAllocator)
Definition bslstl_list.h:2616
iterator insert(const_iterator dstPosition, const value_type &value)
Definition bslstl_list.h:3068
void merge(BloombergLP::bslmf::MovableRef< list > other, COMPARE comparator)
Definition bslstl_list.h:3169
void merge(list &other)
Definition bslstl_list.h:3119
reference back()
Definition bslstl_list.h:2917
const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_list.h:3475
void push_front(BloombergLP::bslmf::MovableRef< value_type > value)
Definition bslstl_list.h:3042
const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_list.h:3483
list()
Definition bslstl_list.h:2496
void sort()
Definition bslstl_list.h:3235
allocator_traits< ALLOCATOR >::size_type size_type
Definition bslstl_list.h:1076
List_Iterator< VALUE > iterator
Definition bslstl_list.h:1070
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_list.h:1082
size_type remove_if(PREDICATE predicate)
void unique()
Definition bslstl_list.h:3367
void swap(list &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocTraits const_iterator begin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_list.h:1829
size_type remove(const value_type &value)
Definition bslstl_list.h:3182
void pop_front()
Definition bslstl_list.h:2947
list(BloombergLP::bslmf::MovableRef< list > original)
Definition bslstl_list.h:2599
size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_list.h:3524
iterator begin() BSLS_KEYWORD_NOEXCEPT
allocator_traits< ALLOCATOR >::pointer pointer
Definition bslstl_list.h:1072
void push_back(const value_type &value)
Definition bslstl_list.h:3020
iterator insert(const_iterator dstPosition, BloombergLP::bslmf::MovableRef< value_type > value)
Definition bslstl_list.h:3075
iterator insert(const_iterator dstPosition, size_type numElements, const value_type &value)
Definition bslstl_list.h:3084
VALUE value_type
Definition bslstl_list.h:1079
void pop_back()
Definition bslstl_list.h:2938
allocator_traits< ALLOCATOR >::difference_type difference_type
Definition bslstl_list.h:1078
List_Iterator< const VALUE > const_iterator
Definition bslstl_list.h:1071
allocator_traits< ALLOCATOR >::const_pointer const_pointer
Definition bslstl_list.h:1074
list & operator=(const list &rhs)
Definition bslstl_list.h:2686
void push_front(const value_type &value)
Definition bslstl_list.h:3035
iterator insert(const_iterator dstPosition, INPUT_ITERATOR first, INPUT_ITERATOR last, typename enable_if< !is_arithmetic< INPUT_ITERATOR >::value &&!is_enum< INPUT_ITERATOR >::value >::type *=0)
Definition bslstl_list.h:1660
iterator emplace(const_iterator position, ARGS &&... arguments)
reference emplace_front(ARGS &&... arguments)
reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_list.h:2846
void splice(const_iterator dstPosition, list &src)
Definition bslstl_list.h:3252
reference emplace_back(ARGS &&... arguments)
~list()
Definition bslstl_list.h:2671
reference front()
Definition bslstl_list.h:2927
ALLOCATOR allocator_type
Definition bslstl_list.h:1080
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this list.
Definition bslstl_list.h:3531
reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_list.h:2838
list &operator=(BloombergLP::bslmf::MovableRef< list > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocTraits void assign(INPUT_ITERATOR first, INPUT_ITERATOR last, typename enable_if< !is_arithmetic< INPUT_ITERATOR >::value &&!is_enum< INPUT_ITERATOR >::value >::type *=0)
Definition bslstl_list.h:1410
iterator erase(const_iterator position)
Definition bslstl_list.h:2958
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_list.h:2829
bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this list has no elements, and false otherwise.
Definition bslstl_list.h:3516
void clear() BSLS_KEYWORD_NOEXCEPT
Remove all the elements from this list.
Definition bslstl_list.h:2855
const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_list.h:3467
bsl::reverse_iterator< iterator > reverse_iterator
Definition bslstl_list.h:1081
void merge(list &other, COMPARE comparator)
Definition bslstl_list.h:3139
void assign(size_type numElements, const value_type &value)
Definition bslstl_list.h:2790
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_NOEXCEPT_OPERATOR(...)
Definition bsls_keyword.h:635
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:634
#define BSLS_PERFORMANCEHINT_PREDICT_LIKELY(expr)
Definition bsls_performancehint.h:451
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
void swap(OptionValue &a, OptionValue &b)
int assign(LHS_TYPE *lhs, const RHS_TYPE &rhs)
Definition bdlb_printmethods.h:283
T::reverse_iterator rend(T &container)
Definition bslstl_iterator.h:1625
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
T::const_iterator cend(const T &container)
Definition bslstl_iterator.h:1611
T::const_reverse_iterator crbegin(const T &container)
Definition bslstl_iterator.h:1597
T::reverse_iterator rbegin(T &container)
Definition bslstl_iterator.h:1567
bool operator>=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator<=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
deque< VALUE_TYPE, ALLOCATOR >::size_type erase(deque< VALUE_TYPE, ALLOCATOR > &deq, const BDE_OTHER_TYPE &value)
Definition bslstl_deque.h:4126
T::iterator begin(T &container)
Definition bslstl_iterator.h:1495
T::const_iterator cbegin(const T &container)
Definition bslstl_iterator.h:1553
BSLS_KEYWORD_CONSTEXPR size_t size(const TYPE(&)[DIMENSION]) BSLS_KEYWORD_NOEXCEPT
Return the dimension of the specified array argument.
Definition bslstl_iterator.h:1331
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
deque< VALUE_TYPE, ALLOCATOR >::size_type erase_if(deque< VALUE_TYPE, ALLOCATOR > &deq, PREDICATE predicate)
Definition bslstl_deque.h:4135
bool operator!=(const memory_resource &a, const memory_resource &b)
BSLS_KEYWORD_CONSTEXPR bool empty(const CONTAINER &container)
Definition bslstl_iterator.h:1279
T::const_reverse_iterator crend(const T &container)
Definition bslstl_iterator.h:1654
Definition bdlc_flathashmap.h:1805
Definition balxml_encoderoptions.h:68
Definition bdlbb_blob.h:576
void swap(TYPE &a, TYPE &b)
Definition bslstl_list.h:893
bool operator()(const VALUE &lhs, const VALUE &rhs) const
Definition bslstl_list.h:2278
Definition bslma_allocatortraits.h:1061
BloombergLP::bslma::AllocatorTraits_ConstPointerType< ALLOCATOR_TYPE >::type const_pointer
Definition bslma_allocatortraits.h:1152
BloombergLP::bslma::AllocatorTraits_SizeType< ALLOCATOR_TYPE >::type size_type
Definition bslma_allocatortraits.h:1165
BloombergLP::bslma::AllocatorTraits_PointerType< ALLOCATOR_TYPE >::type pointer
Definition bslma_allocatortraits.h:1149
BloombergLP::bslma::AllocatorTraits_DifferenceType< ALLOCATOR_TYPE >::type difference_type
Definition bslma_allocatortraits.h:1162
Definition bslmf_enableif.h:525
Definition bslmf_isarithmetic.h:124
Definition bslmf_isconvertible.h:867
Definition bslmf_isenum.h:270
Definition bslmf_issame.h:146
remove_const< typenameremove_volatile< t_TYPE >::type >::type type
Definition bslmf_removecv.h:126
t_TYPE type
Definition bslmf_typeidentity.h:216
Definition bslalg_hasstliterators.h:99
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_isbitwisemoveable.h:718