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