BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_list_cpp03.h
Go to the documentation of this file.
1/// @file bslstl_list_cpp03.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_list_cpp03.h -*-C++-*-
8
9// Automatically generated file. **DO NOT EDIT**
10
11#ifndef INCLUDED_BSLSTL_LIST_CPP03
12#define INCLUDED_BSLSTL_LIST_CPP03
13
14/// @defgroup bslstl_list_cpp03 bslstl_list_cpp03
15/// @brief Provide C++03 implementation for bslstl_list.h
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_list_cpp03
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_list_cpp03-purpose"> Purpose</a>
25/// * <a href="#bslstl_list_cpp03-classes"> Classes </a>
26/// * <a href="#bslstl_list_cpp03-description"> Description </a>
27///
28/// # Purpose {#bslstl_list_cpp03-purpose}
29/// Provide C++03 implementation for bslstl_list.h
30///
31/// # Classes {#bslstl_list_cpp03-classes}
32/// See bslstl_list.h for list of classes
33///
34/// @see bslstl_list
35///
36/// # Description {#bslstl_list_cpp03-description}
37/// This component is the C++03 translation of a C++11 component,
38/// generated by the 'sim_cpp11_features.pl' program. If the original header
39/// contains any specially delimited regions of C++11 code, then this generated
40/// file contains the C++03 equivalent, i.e., with variadic templates expanded
41/// and rvalue-references replaced by 'bslmf::MovableRef' objects. The header
42/// code in this file is designed to be '#include'd into the original header
43/// when compiling with a C++03 compiler. If there are no specially delimited
44/// regions of C++11 code, then this header contains no code and is not
45/// '#include'd in the original header.
46///
47/// Generated on Fri Oct 10 04:51:21 2025
48/// Command line: sim_cpp11_features.pl bslstl_list.h
49/// @}
50/** @} */
51/** @} */
52
53/** @addtogroup bsl
54 * @{
55 */
56/** @addtogroup bslstl
57 * @{
58 */
59/** @addtogroup bslstl_list_cpp03
60 * @{
61 */
62
63#ifdef COMPILING_BSLSTL_LIST_H
64
65namespace bsl {
66
67 // =====================
68 // struct bsl::List_Node
69 // =====================
70
71/// PRIVATE CLASS TEMPLATE. For use only by `bsl::list` implementation.
72/// An instance of `List_Node<T>` is a single node in a doubly-linked list
73/// used to implement `bsl::list<T,A>`, for a given element type `T` and allocator type `A`.
74///
75/// \note Note that an instantiation of this `class` for a
76/// given `bsl::list` is independent of the allocator type.
77///
78/// See @ref bslstl_list_cpp03
79template <class VALUE>
80class List_Node {
81
82 // DATA
83 List_Node *d_prev_p; // pointer to the previous node in the list
84 List_Node *d_next_p; // pointer to the next node in the list
85 VALUE d_value; // list element
86
87 // FRIENDS
88 template <class LIST_VALUE, class LIST_ALLOCATOR>
89 friend class list;
90
91 template <class ITER_VALUE>
92 friend class List_Iterator;
93
94 private:
95 // NOT IMPLEMENTED
96 List_Node(); // = delete;
97 List_Node(const List_Node&); // = delete;
98 ~List_Node(); // = delete;
99 List_Node& operator=(const List_Node&); // = delete;
100
101 // A 'List_Node' is never constructed, copied, destroyed, or assigned to.
102 // The 'd_value' field is constructed directly by 'list::emplace', and
103 // destroyed directly by 'list::erase'.
104};
105
106 // ========================
107 // class bsl::List_Iterator
108 // ========================
109
110#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
111// On Solaris studio12-v4, <algorithm> is compatible only with iterators
112// inheriting from 'std::iterator'.
113
114template <class VALUE>
115class List_Iterator :
116 public std::iterator<std::bidirectional_iterator_tag, VALUE> {
117#else
118template <class VALUE>
119class List_Iterator {
120#endif
121 // Implementation of 'bsl::list::iterator'.
122
123 // PRIVATE TYPES
124 typedef typename remove_cv<VALUE>::type NcType;
125 typedef List_Iterator<NcType> NcIter;
126 typedef List_Node<NcType> Node;
127
128 // DATA
129 Node *d_node_p; // pointer to list node
130
131 // FRIENDS
132 template <class LIST_VALUE, class LIST_ALLOCATOR>
133 friend class list;
134
135 template <class ITER_VALUE> // This 'friend' statement is needed for the
136 friend class List_Iterator; // case where 'VALUE' != 'ITER_VALUE'.
137
138 template <class T1, class T2>
139 friend bool operator==(List_Iterator<T1>, List_Iterator<T2>);
140
141 private:
142 // PRIVATE ACCESSORS
143
144 /// Return an iterator providing modifiable access to the list element
145 /// that this list iterator refers to.
146 NcIter unconst() const;
147
148 public:
149 // PUBLIC TYPES
150 typedef std::bidirectional_iterator_tag iterator_category;
151 typedef NcType value_type;
152 typedef BloombergLP::bsls::Types::IntPtr difference_type;
153 typedef VALUE *pointer;
154 typedef VALUE& reference;
155
156 // CREATORS
157
158 /// Create a singular iterator (i.e., one that cannot be incremented,
159 /// decremented, or dereferenced until assigned a non-singular value).
161
162 /// Create an iterator that references the value pointed to by the
163 /// specified `nodePtr`. If `0 == nodePtr` the iterator will be
164 /// singular.
165 explicit List_Iterator(Node *nodePtr);
166
167 /// Create an iterator that has the same value as the specified `other`
168 /// iterator. If the (template parameter) type `VALUE` is not
169 /// `const`-qualified, then this constructor is the copy constructor;
170 /// otherwise, the copy constructor is implicitly generated.
171 ///
172 /// \note Note that this method is marked "IMPLICIT" in case it is not the copy
173 /// constructor.
174 ///
175 ///
176 /// \note Note that this means that a `List_Iterator<const VALUE>` can be copy
177 /// constructed or assigned to from a `List_Iterator<VALUE>`, but not
178 /// vice-versa.
179 List_Iterator(const NcIter& other); // IMPLICIT
180
181 /// Compiler-generated copy constructor, destructor, and copy-assignment
182 /// operator:
183 List_Iterator(const List_Iterator&); // Maybe defaulted (see above).
184 ~List_Iterator() = default;
185 List_Iterator& operator=(const List_Iterator&) = default;
186
187#if defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS)
188 /// Default compiler-generated destructor.
189 ~List_Iterator() = default;
190
191 /// Default compiler-generated copy-assignment operator.
192 List_Iterator& operator=(const List_Iterator&) = default;
193#endif
194
195 // MANIPULATORS
196
197 /// Advance this iterator to the next element in the list and return its new value.
198 ///
199 /// \pre The behavior is undefined unless this iterator is in the
200 /// range `[begin() .. end())` for some list (i.e., the iterator is not
201 /// singular, is not `end()`, and has not been invalidated).
203
204 /// Regress this iterator to the previous element in the list and return its new value.
205 ///
206 /// \pre The behavior is undefined unless this iterator is in
207 /// the range `(begin() .. end()]` for some list (i.e., the iterator is
208 /// not singular, is not `begin()`, and has not been invalidated).
210
211 /// Advance this iterator to the next element in the list and return its previous value.
212 ///
213 /// \pre The behavior is undefined unless this iterator is
214 /// in the range `[begin() .. end())` for some list (i.e., the iterator
215 /// is not singular, is not `end()`, and has not been invalidated).
217
218 /// Regress this iterator to the previous element in the list and return its previous value.
219 ///
220 /// \pre The behavior is undefined unless this iterator
221 /// is in the range `(begin() .. end()]` for some list (i.e., the
222 /// iterator is not singular, is not `begin()`, and has not been
223 /// invalidated).
225
226 // ACCESSORS
227
228 /// Return a reference providing modifiable access to the element referenced by this iterator.
229 ///
230 /// \pre The behavior is undefined unless this
231 /// iterator is in the range `[begin() .. end())` for some list (i.e.,
232 /// the iterator is not singular, is not `end()`, and has not been
233 /// invalidated).
234 reference operator*() const;
235
236 /// Return a pointer providing modifiable access to the element referenced by this iterator.
237 ///
238 /// \pre The behavior is undefined unless this
239 /// iterator is in the range `[begin() .. end())` for some list (i.e.,
240 /// the iterator is not singular, is not `end()`, and has not been
241 /// invalidated).
242 pointer operator->() const;
243};
244
245// FREE OPERATORS
246
247/// Return `true` if the specified `lhs` and `rhs` iterators have the same
248/// value, and `false` otherwise. Two iterators have the same value if both
249/// refer to the same element of the same list or both are the `end()` iterator of the same list.
250///
251/// \pre The behavior is undefined unless both `lhs` and `rhs` refer to the same list.
252///
253/// \note Note that the different types `T1`
254/// and `T2` are to facilitate comparisons between `const` and non-`const`
255/// iterators and there will be a compilation error if `T1` and `T2` differ
256/// in any way other than `const`-ness.
257template <class T1, class T2>
258bool operator==(List_Iterator<T1> lhs, List_Iterator<T2> rhs);
259
260#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
261/// Return `true` if the specified `lhs` and `rhs` iterators do not have the
262/// same value, and `false` otherwise. Two iterators do not have the same
263/// value unless both refer to the same element of the same list or unless
264/// both are the `end()` iterator of the same list.
265///
266/// \pre The behavior is undefined unless both `lhs` and `rhs` refer to the same list.
267///
268/// \note Note that the different types `T1` and `T2` are to facilitate comparisons between
269/// `const` and non-`const` iterators and there will be a compilation error
270/// if `T1` and `T2` differ in any way other than `const`-ness.
271template <class T1, class T2>
272bool operator!=(List_Iterator<T1> lhs, List_Iterator<T2> rhs);
273#endif
274
275 // ===========================
276 // struct List_DefaultLessThan
277 // ===========================
278
279/// Binary predicate type for comparing two `VALUE` objects using
280/// `operator<`. This operation is usually, but not always, the same as
281/// that provided by `std::less<VALUE>`. The standard requires that certain
282/// functions use `operator<`, which means that divergent specializations of
283/// `std::less` are to be ignored.
284///
285/// See @ref bslstl_list_cpp03
286template <class VALUE>
287struct List_DefaultLessThan {
288
289 // ACCESSORS
290
291 /// Return `true` if the value of the specified `lhs` is less than that
292 /// of the specified `rhs`, and `false` otherwise.
293 bool operator()(const VALUE& lhs, const VALUE& rhs) const;
294};
295
296 // ==============================
297 // class List_AllocAndSizeWrapper
298 // ==============================
299
300/// This struct is a wrapper around the allocator and size data members of a
301/// `list`. It takes advantage of the empty-base optimization (EBO) so that
302/// if the allocator is stateless, it takes up no space.
303///
304/// TBD: This struct should eventually be replaced by the use of a general
305/// EBO-enabled component that provides a `pair`-like interface. (A
306/// properly-optimized `tuple` would do the job.)
307template <class VALUE, class ALLOCATOR>
308class List_AllocAndSizeWrapper : public allocator_traits<ALLOCATOR>::
309 template rebind_traits<List_Node<VALUE> >::allocator_type {
310
311 // PRIVATE TYPES
312 typedef List_Node<VALUE> Node;
313
314 /// Alias for the allocator traits type associated with the `bsl::list`
315 /// container.
316 typedef typename allocator_traits<ALLOCATOR>::template rebind_traits<Node>
317 AllocTraits;
318
319 typedef typename AllocTraits::allocator_type NodeAlloc; // base class
320
321 typedef typename AllocTraits::size_type size_type;
322
323 // DATA
324 size_type d_size; // Number of elements in the list (not including the
325 // sentinel).
326
327 private:
328 // NOT IMPLEMENTED
329 List_AllocAndSizeWrapper(const List_AllocAndSizeWrapper&);
330 List_AllocAndSizeWrapper& operator=(const List_AllocAndSizeWrapper&);
331
332 public:
333 // CREATORS
334
335 /// Create an allocator and size wrapper having the specified
336 /// `basicAllocator` and (initial) `size`.
337 List_AllocAndSizeWrapper(const NodeAlloc& basicAllocator,
338 size_type size);
339
340 // ~List_AllocAndSizeWrapper() = default;
341
342 // MANIPULATORS
343
344 /// Return a reference providing modifiable access to the `size` field of
345 /// this object.
346 size_type& size();
347
348 // ACCESSORS
349
350 /// Return a reference providing non-modifiable access to the `size` field
351 /// of this object.
352 const size_type& size() const;
353};
354
355/// Forward declaration required by `List_NodeProctor`.
356template <class VALUE, class ALLOCATOR>
357class list;
358
359 // ======================
360 // class List_NodeProctor
361 // ======================
362
363/// This class provides a proctor to free a node containing an uninitialized
364/// `VALUE` object in the event that an exception is thrown.
365///
366/// See @ref bslstl_list_cpp03
367template <class VALUE, class ALLOCATOR>
368class List_NodeProctor {
369
370 // PRIVATE TYPES
371 typedef List_Node<VALUE> Node;
372
373 /// Alias for the allocator traits type associated with the `bsl::list`
374 /// container.
375 typedef typename allocator_traits<ALLOCATOR>::template rebind_traits<Node>
376 AllocTraits;
377
378 public:
379 // PUBLIC TYPES
380
381 // In C++11 'NodePtr' would be generalized as follows:
382 // 'typedef pointer_traits<VoidPtr>::template rebind<List_Node> NodePtr;'
383
384 typedef typename AllocTraits::pointer NodePtr;
385
386 private:
387 // DATA
388 list<VALUE, ALLOCATOR> *d_list_p; // list to proctor
389 NodePtr d_node_p; // node to free upon destruction
390
391 private:
392 // NOT IMPLEMENTED
393 List_NodeProctor(const List_NodeProctor&);
394 List_NodeProctor &operator=(const List_NodeProctor&);
395
396 public:
397 // CREATORS
398
399 /// Create a node proctor object that will use the specified list `listPtr` to free the specified `nodePtr`.
400 ///
401 /// \pre The behavior is undefined unless
402 /// `nodePtr` was allocated by the allocator of `*listPtr`.
403 List_NodeProctor(list<VALUE, ALLOCATOR> *listPtr, NodePtr nodePtr);
404
405 /// Destroy this node proctor, and free the node it contains unless the `release` method has been called before.
406 ///
407 /// \note Note that the `d_value` field
408 /// of the node is not destroyed.
409 ~List_NodeProctor();
410
411 // MANIPULATORS
412
413 /// Detach the node contained in this proctor from the proctor. After
414 /// calling this `release` method, the proctor no longer frees any node
415 /// upon its destruction.
416 void release();
417};
418
419 // ===============
420 // class bsl::list
421 // ===============
422
423/// This class template implements a value-semantic container type holding a
424/// sequence of elements of the (template parameter) `VALUE` type.
425///
426/// See @ref bslstl_list_cpp03
427template <class VALUE, class ALLOCATOR = bsl::allocator<VALUE> >
428class list {
429
430 // PRIVATE TYPES
431
432 /// Default comparator.
433 typedef List_DefaultLessThan<VALUE> DefaultLessThan;
434
435 /// Alias for the node type in this list.
436 typedef List_Node<VALUE> Node;
437
438 /// Proctor for guarding a newly allocated node.
439 typedef List_NodeProctor<VALUE, ALLOCATOR> NodeProctor;
440
441 /// Alias for the allocator traits type associated with this container.
442 typedef typename allocator_traits<ALLOCATOR>::template rebind_traits<Node>
443 AllocTraits;
444
445 /// Alias for the utility associated with movable references.
446 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
447
448 /// Alias for the wrapper containing the (usually stateless) allocator and
449 /// number of elements stored in this container.
450 typedef List_AllocAndSizeWrapper<VALUE, ALLOCATOR>
451 AllocAndSizeWrapper;
452
453 /// Base class of `List_AllocAndSizeWrapper` containing the allocator.
454 typedef typename AllocTraits::allocator_type NodeAlloc;
455
456 // In C++11 'NodePtr' would be generalized as follows:
457 // 'typedef pointer_traits<VoidPtr>::template rebind<List_Node> NodePtr;'
458
459 typedef typename AllocTraits::pointer NodePtr;
460
461 public:
462 // PUBLIC TYPES
463 typedef VALUE& reference;
464 typedef const VALUE& const_reference;
465 typedef List_Iterator<VALUE> iterator;
466 typedef List_Iterator<const VALUE> const_iterator;
467 typedef typename allocator_traits<ALLOCATOR>::pointer pointer;
468 typedef typename allocator_traits<ALLOCATOR>::const_pointer
469 const_pointer;
470
471 typedef typename allocator_traits<ALLOCATOR>::size_type size_type;
472 typedef typename allocator_traits<ALLOCATOR>::difference_type
474 typedef VALUE value_type;
475 typedef ALLOCATOR allocator_type;
476 typedef bsl::reverse_iterator<iterator> reverse_iterator;
477 typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;
478
479 private:
480 // DATA
481 NodePtr d_sentinel; // node pointer of sentinel element
482 AllocAndSizeWrapper d_alloc_and_size; // node allocator
483
484 // FRIENDS
485 friend class List_NodeProctor<VALUE, ALLOCATOR>;
486
487 // PRIVATE MANIPULATORS
488
489 /// Return a reference providing modifiable access to the allocator used to
490 /// allocate nodes.
491 NodeAlloc& allocatorImp();
492
493 /// Return a pointer to a node allocated from the container's allocator.
494 /// Before returning, the node's pointers are zeroed, but the constructor
495 /// of the `value_type` is not called.
496 NodePtr allocateNode();
497
498 /// Create the sentinel node of this list. The sentinel node does not hold
499 /// a value. When first created, its forward and backward pointers point
500 /// to itself, creating a circular linked list. This function also sets
501 /// this list's size to 0.
502 void createSentinel();
503
504 /// Destroy the value part of the specified `node` and free the node's
505 /// memory. Do not do any pointer fix-up of the node or its neighbors, and do not update `sizeRef`.
506 ///
507 /// \pre The behavior is undefined unless `node` was
508 /// allocated using the allocator of this list.
509 void deleteNode(NodePtr node);
510
511 /// Erase all elements and deallocate the sentinel node, leaving this list
512 /// in an invalid but destructible state (i.e., with `size == -1`).
513 void destroyAll();
514
515 /// Zero out the pointers and deallocate the node pointed to by the specified `node`.
516 ///
517 /// \pre The behavior is undefined unless `node` was allocated using the allocator of this list.
518 ///
519 /// \note Note that node's
520 /// destructor is not called, and, importantly, the value field of `node`
521 /// is not destroyed.
522 void freeNode(NodePtr node);
523
524 /// Insert the specified `node` prior to the specified `position` in this list.
525 ///
526 /// \pre The behavior is undefined unless `node` was allocated using the
527 /// allocator of this list and `position` is in the range
528 /// `[begin() .. end()]`.
529 iterator insertNode(const_iterator position, NodePtr node);
530
531 /// Modify the forward pointer of the specified `prev` to point to the
532 /// specified `next` and the backward pointer of `next` to point to `prev`.
533 ///
534 /// \pre The behavior is undefined unless `prev` and `next` point to nodes
535 /// created with `allocateNode`.
536 void linkNodes(NodePtr prev, NodePtr next);
537
538 /// Given a specified pair of nodes `node1` and `finish` specifying the
539 /// range `[node1 .. finish)`, with the specified `node2` pointing
540 /// somewhere in the middle of the sequence, merge sequence
541 /// `[node2 .. finish)` into `[node1 .. node2)`, and return a pointer to
542 /// the beginning of the merged sequence, using the specified
543 /// `comparator` to determine order. If an exception is thrown, all
544 /// nodes remain in this list, but their order is unspecified. If any
545 /// nodes in the range `[node1 .. node2)` compare equivalent to any
546 /// nodes in the range `[node2 .. finish)`, the nodes from
547 /// `[node1 .. node2)` will be merged first.
548 ///
549 /// \pre The behavior is undefined unless `[node1 .. node2)` and `[node2 .. finish)` each describe a
550 /// contiguous sequence of nodes.
551 template <class COMPARE>
552 NodePtr mergeImp(NodePtr node1,
553 NodePtr node2,
554 NodePtr finish,
555 COMPARE comparator);
556
557 /// Append the values from the specified `[first, last)` range.
558 template <class t_ITERATOR, class t_SENTINEL>
559 void privateAppendRange(t_ITERATOR first, t_SENTINEL last);
560
561 /// Efficiently exchange the value of this object with that of the
562 /// specified `other` object. This method provides the no-throw exception-safety guarantee.
563 ///
564 /// \pre The behavior is undefined unless this
565 /// object was created with the same allocator as `other`.
566 void quickSwap(list *other);
567
568 /// Return a reference providing modifiable access to the data element
569 /// holding the size of this list.
570 typename AllocTraits::size_type& sizeRef() BSLS_KEYWORD_NOEXCEPT;
571
572 /// Sort the sequence of the specified `size` nodes starting with the
573 /// specified `*nodePtrPtr`, and modify `*nodePtrPtr` to refer to the
574 /// first node of the sorted sequence. Return the pointer to the node
575 /// following the sequence of nodes to be sorted. Use the specified
576 /// `comparator` to compare `VALUE` type objects. If an exception is
577 /// thrown, all nodes remain properly linked, but their order is unspecified.
578 ///
579 /// \pre The behavior is undefined unless `*nodePtrPtr` begins
580 /// a sequence of at least `size` nodes, none of which is the sentinel
581 /// node, and `0 < size`.
582 template <class COMPARE>
583 NodePtr sortImp(NodePtr *nodePtrPtr,
584 size_type size,
585 const COMPARE& comparator);
586
587 // PRIVATE ACCESSORS
588
589 /// Return a reference providing non-modifiable access to the allocator
590 /// used to allocate nodes.
591 const NodeAlloc& allocatorImp() const;
592
593 /// Return a pointer providing modifiable access to the first node in
594 /// this list or the sentinel node if this list is empty.
595 NodePtr headNode() const;
596
597 /// Return a reference providing non-modifiable access to the data
598 /// element holding the size of this list.
599 const typename AllocTraits::size_type& sizeRef() const
601
602 public:
603 // CREATORS
604
605 /// Create an empty list. A default-constructed object of the (template
606 /// parameter) type `ALLOCATOR` is used. If the type `ALLOCATOR` is
607 /// `bsl::allocator`, the currently installed default allocator is used.
608 list();
609
610 /// Create an empty list. Use the specified `basicAllocator` to supply
611 /// memory. If the type `ALLOCATOR` is `bsl::allocator` (the default),
612 /// then `basicAllocator` shall be convertible to `bslma::Allocator *`.
613 explicit list(const ALLOCATOR& basicAllocator);
614
615 /// Create a list of the specified `numElements` size whose every
616 /// element is default-constructed. A default-constructed object of the
617 /// (template parameter) type `ALLOCATOR` is used. If the type
618 /// `ALLOCATOR` is `bsl::allocator`, the currently installed default
619 /// allocator is used. Throw `bsl::length_error` if
620 /// `numElements > max_size()`. This method requires that the (template
621 /// parameter) `VALUE` be `default-insertable` into this list (see
622 /// {Requirements on `VALUE`}).
623 explicit list(size_type numElements);
624
625 /// Create a list of the specified `numElements` size whose every
626 /// element is default-constructed. Use the specified `basicAllocator`
627 /// to supply memory. If the type `ALLOCATOR` is `bsl::allocator` (the
628 /// default), then `basicAllocator` shall be convertible to
629 /// `bslma::Allocator *`. Throw `bsl::length_error` if
630 /// `numElements > max_size()`. This method requires that the (template
631 /// parameter) `VALUE` be `default-insertable` into this list (see
632 /// {Requirements on `VALUE`}).
633 list(size_type numElements,
634 const ALLOCATOR& basicAllocator);
635
636 /// Create a list of the specified `numElements` size whose every
637 /// element has the specified `value`. Optionally specify a
638 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
639 /// supplied, a default-constructed object of the (template parameter)
640 /// type `ALLOCATOR` is used. If the type `ALLOCATOR` is
641 /// `bsl::allocator` (the default), then `basicAllocator`, if supplied,
642 /// shall be convertible to `bslma::Allocator *`. If the type
643 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
644 /// supplied, the currently installed default allocator is used. Throw
645 /// `bsl::length_error` if `numElements > max_size()`. This method
646 /// requires that the (template parameter) `VALUE` be `copy-insertable`
647 /// into this list (see {Requirements on `VALUE`}).
648 list(size_type numElements,
649 const value_type& value,
650 const ALLOCATOR& basicAllocator = ALLOCATOR());
651
652 /// Create a list initially containing copies of the values in the range
653 /// starting at the specified `first` and ending immediately before the
654 /// specified `last` iterators of the (template parameter) type
655 /// `INPUT_ITERATOR`. Optionally specify a `basicAllocator` used to
656 /// supply memory. If `basicAllocator` is not supplied, a
657 /// default-constructed object of the (template parameter) type
658 /// `ALLOCATOR` is used. If the type `ALLOCATOR` is `bsl::allocator`
659 /// (the default), then `basicAllocator`, if supplied, shall be
660 /// convertible to `bslma::Allocator *`. If the type `ALLOCATOR` is
661 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
662 /// installed default allocator is used. Throw `bsl::length_error` if
663 /// the number of elements in `[first .. last)` exceeds the size
664 /// returned by @ref max_size . The (template parameter) type
665 /// `INPUT_ITERATOR` shall meet the requirements of an input iterator
666 /// defined in the C++11 standard [input.iterators] providing access to
667 /// values of a type convertible to `value_type`, and `value_type` must
668 /// be `emplace-constructible` from `*i` into this list, where `i` is a
669 /// dereferenceable iterator in the range `[first .. last)` (see {Requirements on `VALUE`}).
670 ///
671 /// \pre The behavior is undefined unless
672 /// `first` and `last` refer to a sequence of valid values where `first`
673 /// is at a position at or before `last`.
674 template <class INPUT_ITERATOR>
675 list(INPUT_ITERATOR first,
676 INPUT_ITERATOR last,
677 const ALLOCATOR& basicAllocator = ALLOCATOR(),
678 typename enable_if<
679 !is_arithmetic<INPUT_ITERATOR>::value &&
680 !is_enum<INPUT_ITERATOR>::value
681 >::type * = 0)
682 : d_alloc_and_size(basicAllocator, size_type(-1))
683 {
684 // MS Visual Studio 2008 compiler requires that a function using
685 // enable_if be in-place inline.
686
687 // '*this' is in an invalid but destructible state (size == -1).
688 // Create a temporary list, 'tmp' with the specified data. If an
689 // exception is thrown, 'tmp's destructor will clean up. Otherwise,
690 // swap 'tmp' with '*this', leaving 'tmp' in an invalid but
691 // destructible state and leaving '*this' fully constructed.
692
693 list tmp(this->allocatorImp());
694 tmp.insert(tmp.cbegin(), first, last);
695 quickSwap(&tmp);
696 }
697
698 /// Create a list from the elements of the specifed `range`. Optionally
699 /// specify an `basicAllocator` used to supply memory. If `basicAllocator`
700 /// is not specified, a default-constructed object of the (template parameter) type `ALLOCATOR` is used.
701 ///
702 /// \note Note that `range` must meet the
703 /// requirements of an input range and the values from `range` must have a
704 /// type matching or convertible to (template parameter) `VALUE`.
705 template <class t_RANGE>
707 list(from_range_t ,
709 const ALLOCATOR& basicAllocator =
710 ALLOCATOR());
711
712 /// Create a list having the same value as the specified `original`
713 /// object. Use the allocator returned by
714 /// 'bsl::allocator_traits<ALLOCATOR>::
715 /// select_on_container_copy_construction(original.get_allocator())' to
716 /// allocate memory. This method requires that the (template parameter)
717 /// type `VALUE` be `copy-insertable` into this list (see {Requirements
718 /// on `VALUE`}).
719 list(const list& original);
720
721 /// Create a list that has the same value as the specified `original`
722 /// object. Use the specified `basicAllocator` to supply memory. This
723 /// method requires that the (template parameter) `VALUE` be
724 /// `copy-insertable` into this list (see {Requirements on `VALUE`}).
725 ///
726 /// \note Note that a `bslma::Allocator *` can be supplied for
727 /// `basicAllocator` if the (template parameter) type `ALLOCATOR` is
728 /// `bsl::allocator` (the default).
729 list(const list& original,
730 const typename type_identity<ALLOCATOR>::type& basicAllocator);
731
732 /// Create a list having the same value as the specified `original`
733 /// object by moving (in constant time) the contents of `original` to
734 /// the new list. The allocator associated with `original` is
735 /// propagated for use in the newly-created list. `original` is left in
736 /// a valid but unspecified state.
737 list(BloombergLP::bslmf::MovableRef<list> original); // IMPLICIT
738
739 /// Create a list having the same value as the specified `original`
740 /// object that uses the specified `basicAllocator` to supply memory.
741 /// The contents of `original` are moved (in constant time) to the new
742 /// list if `basicAllocator == original.get_allocator()`, and are move-
743 /// inserted (in linear time) using `basicAllocator` otherwise.
744 /// `original` is left in a valid but unspecified state. This method
745 /// requires that the (template parameter) `VALUE` be `move-insertable` into this list (see {Requirements on `VALUE`}).
746 ///
747 /// \note Note that a
748 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
749 /// (template parameter) `ALLOCATOR` is `bsl::allocator` (the default).
750 list(BloombergLP::bslmf::MovableRef<list> original,
751 const typename type_identity<ALLOCATOR>::type& basicAllocator);
752
753#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
754 /// Create a list and append each `value_type` object in the specified
755 /// `values` initializer list. Optionally specify a `basicAllocator`
756 /// used to supply memory. If `basicAllocator` is not supplied, a
757 /// default-constructed object of the (template parameter) type
758 /// `ALLOCATOR` is used. If the type `ALLOCATOR` is `bsl::allocator`
759 /// (the default), then `basicAllocator`, if supplied, shall be
760 /// convertible to `bslma::Allocator *`. If the type `ALLOCATOR` is
761 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
762 /// installed default allocator is used. This method requires that the
763 /// (template parameter) `VALUE` be `copy-insertable` into this list
764 /// (see {Requirements on `VALUE`}).
765 list(std::initializer_list<value_type> values,
766 const ALLOCATOR& basicAllocator = ALLOCATOR());
767 // IMPLICIT
768#endif
769
770 /// Destroy this list by calling the destructor for each element and
771 /// deallocating all allocated storage.
772 ~list();
773
774 // MANIPULATORS
775
776 // *** assignment ***
777
778 /// Assign to this object the value of the specified `rhs` object,
779 /// propagate to this object the allocator of `rhs` if the `ALLOCATOR`
780 /// type has trait @ref propagate_on_container_copy_assignment , and return
781 /// a reference providing modifiable access to this object. If an
782 /// exception is thrown, `*this` is left in a valid but unspecified
783 /// state. This method requires that the (template parameter) type
784 /// `VALUE` be `copy-assignable` and `copy-insertable` into this list.
785 ///
786 /// \note Note that, to the extent possible, existing elements of this list
787 /// are copy-assigned to, to minimize the number of nodes that need to
788 /// be copy-inserted or erased.
789 list& operator=(const list& rhs);
790
791 /// Assign to this object the value of the specified `rhs` object,
792 /// propagate to this object the allocator of `rhs` if the `ALLOCATOR`
793 /// type has trait @ref propagate_on_container_move_assignment , and return
794 /// a reference providing modifiable access to this object. The
795 /// contents of `rhs` are moved (in constant time) to this list if
796 /// `get_allocator() == rhs.get_allocator()` (after accounting for the
797 /// aforementioned trait); otherwise, all elements in this list are
798 /// either destroyed or move-assigned to and each additional element in
799 /// `rhs` is move-inserted into this list. `rhs` is left in a valid but
800 /// unspecified state, and if an exception is thrown, `*this` is left in
801 /// a valid but unspecified state. This method requires that the
802 /// (template parameter) type `VALUE` be `move-assignable` and
803 /// `move-insertable` into this list (see {Requirements on `VALUE`}).
804 list& operator=(BloombergLP::bslmf::MovableRef<list> rhs)
806 AllocTraits::is_always_equal::value);
807
808#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
809 /// Assign to this list, in order, the sequence of values in the
810 /// specified `rhs` initializer list, and return a reference providing
811 /// modifiable access to this list. This method requires that the
812 /// (template parameter) type `VALUE` be `copy-assignable` and `copy-insertable` into this list.
813 ///
814 /// \note Note that, to the extent
815 /// possible, existing elements of this list are copy-assigned to, to
816 /// minimize the number of nodes that need to be copy-inserted or
817 /// erased.
818 list& operator=(std::initializer_list<value_type> rhs);
819#endif
820
821 /// Assign to this list the sequence of values, in order, of the
822 /// elements of the specified range `[first .. last)`. The (template
823 /// parameter) type `INPUT_ITERATOR` shall meet the requirements of an
824 /// input iterator defined in the C++11 standard [24.2.3] providing
825 /// access to values of a type convertible to `value_type`, and
826 /// `value_type` must be `emplace-constructible` from `*i` into this
827 /// list, where `i` is a dereferenceable iterator in the range `[first .. last)`.
828 ///
829 /// \pre The behavior is undefined unless `first` and
830 /// `last` refer to a sequence of valid values where `first` is at a position at or before `last`.
831 ///
832 /// \note Note that, to the extent possible,
833 /// existing elements of this list are copy-assigned to, to minimize the
834 /// number of nodes that need to be copy-inserted or erased. If an
835 /// exception is thrown, `*this` is left in a valid but unspecified
836 /// state.
837 template <class INPUT_ITERATOR>
838 void assign(INPUT_ITERATOR first,
839 INPUT_ITERATOR last,
840 typename enable_if<
843 >::type * = 0)
844 {
845 // MS Visual Studio 2008 compiler requires that a function using
846 // enable_if be in-place inline.
847
848 iterator dstIt = this->begin();
849 const iterator dstEnd = this->end();
850
851 for (; first != last && dstEnd != dstIt; ++first, ++dstIt) {
852 *dstIt = *first;
853 }
854
855 erase(dstIt, dstEnd);
856
857 for (; first != last; ++first) {
858 emplace(dstEnd, *first);
859 }
860 }
861
862 /// Replace the contents of this list with the specified `numElements` copies of the specified `value`.
863 ///
864 /// \note Note that, to the extent possible,
865 /// existing elements of this list are copy-assigned to, to minimize the
866 /// number of nodes that need to be copy-inserted or erased.
867 void assign(size_type numElements, const value_type& value);
868
869#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
870 /// Assign to this list, in order, the sequence of values in the
871 /// specified `values` initializer list. This method requires that the
872 /// (template parameter) type `VALUE` be `copy-assignable` and `copy-insertable` into this list.
873 ///
874 /// \note Note that, to the extent
875 /// possible, existing elements of this list are copy-assigned to, to
876 /// minimize the number of nodes that need to be copy-inserted or
877 /// erased.
878 void assign(std::initializer_list<value_type> values);
879#endif
880
881 /// Assign to this object the elements of the specified `range`.
882 ///
883 /// \note Note that `range` must meet the requirements of an input range and the values
884 /// from `range` must have a type matching or convertible to (template
885 /// parameter) `VALUE`.
886 template <class t_RANGE>
888 void assign_range(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range);
889
890 // *** iterators ***
891
892 /// Return an iterator providing modifiable access to the first element
893 /// in this list, and the past-the-end iterator if this list is empty.
894 iterator begin() BSLS_KEYWORD_NOEXCEPT;
895
896 /// Return the past-the-end (forward) iterator providing modifiable
897 /// access to this list.
898 iterator end() BSLS_KEYWORD_NOEXCEPT;
899
900 /// Return a reverse iterator providing modifiable access to the last
901 /// element in this list, and the past-the-end reverse iterator if this
902 /// list is empty.
903 reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT;
904
905 /// Return the past-the-end reverse iterator providing modifiable access
906 /// to this list.
907 reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT;
908
909 // *** modify size ***
910
911 /// Remove all the elements from this list.
912 void clear() BSLS_KEYWORD_NOEXCEPT;
913
914 /// Change the size of this list to the specified `newSize`. Erase
915 /// `size() - newSize` elements at the back if `newSize < size()`.
916 /// Append `newSize - size()` elements at the back having the optionally
917 /// specified `value` if `newSize > size()`; if `value` is not
918 /// specified, default-constructed objects of the (template parameter)
919 /// `VALUE` are emplaced. This method has no effect if
920 /// `newSize == size()`. Throw `bsl::length_error` if
921 /// `newSize > max_size()`.
922 void resize(size_type newSize);
923 void resize(size_type newSize, const value_type& value);
924
925 // *** element access ***
926
927 /// Return a reference providing modifiable access to the last element of this list.
928 ///
929 /// \pre The behavior is undefined unless this list contains
930 /// at least one element.
931 reference back();
932
933 /// Return a reference providing modifiable access to the first element of this list.
934 ///
935 /// \pre The behavior is undefined unless this list contains
936 /// at least one element.
937 reference front();
938
939 // *** end erase ***
940
941 /// Remove and destroy the last element of this list.
942 ///
943 /// \pre The behavior is undefined unless this list contains at least one element.
944 void pop_back();
945
946 /// Remove and destroy the first element of this list.
947 ///
948 /// \pre The behavior is undefined unless this list contains at least one element.
949 void pop_front();
950
951 // *** random access erase ***
952
953 /// Remove from this list the element at the specified `position`, and
954 /// return an iterator providing modifiable access to the element
955 /// immediately following the removed element, or to the position
956 /// returned by the `end` method if the removed element was the last in the sequence.
957 ///
958 /// \pre The behavior is undefined unless `position` refers to
959 /// an element in this list.
960 iterator erase(const_iterator position);
961
962 /// Remove from this list the elements starting at the specified
963 /// `dstBegin` position up to, but not including, the specified `dstEnd`
964 /// position, and return a non-`const` iterator equivalent to `dstEnd`.
965 ///
966 /// \pre The behavior is undefined unless `dstBegin` is an iterator in the
967 /// range `[begin() .. end()]` and `dstEnd` is an iterator in the range
968 /// `[dstBegin .. end()]` (both endpoints included).
969 ///
970 /// \note Note that `dstBegin` may be equal to `dstEnd`, in which case the list is not
971 /// modified.
972 iterator erase(const_iterator dstBegin, const_iterator dstEnd);
973
974 // *** end inserts ***
975
976 /// Append to the end of this object the elements of the specified `range`.
977 ///
978 /// \note Note that `range` must meet the requirements of an input range and the
979 /// values from `range` must have a type matching or convertible to
980 /// (template parameter) `VALUE`.
981 template <class t_RANGE>
983 void append_range(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range);
984
985#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
986// {{{ BEGIN GENERATED CODE
987// Command line: sim_cpp11_features.pl bslstl_list.h
988#ifndef BSLSTL_LIST_VARIADIC_LIMIT
989#define BSLSTL_LIST_VARIADIC_LIMIT 10
990#endif
991#ifndef BSLSTL_LIST_VARIADIC_LIMIT_A
992#define BSLSTL_LIST_VARIADIC_LIMIT_A BSLSTL_LIST_VARIADIC_LIMIT
993#endif
994#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 0
995 reference emplace_back(
996 );
997#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 0
998
999#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 1
1000 template <class ARGS_01>
1001 reference emplace_back(
1002 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01);
1003#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 1
1004
1005#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 2
1006 template <class ARGS_01,
1007 class ARGS_02>
1008 reference emplace_back(
1009 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1010 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02);
1011#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 2
1012
1013#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 3
1014 template <class ARGS_01,
1015 class ARGS_02,
1016 class ARGS_03>
1017 reference emplace_back(
1018 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1019 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1020 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03);
1021#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 3
1022
1023#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 4
1024 template <class ARGS_01,
1025 class ARGS_02,
1026 class ARGS_03,
1027 class ARGS_04>
1028 reference emplace_back(
1029 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1030 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1031 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1032 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04);
1033#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 4
1034
1035#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 5
1036 template <class ARGS_01,
1037 class ARGS_02,
1038 class ARGS_03,
1039 class ARGS_04,
1040 class ARGS_05>
1041 reference emplace_back(
1042 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1043 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1044 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1045 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1046 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05);
1047#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 5
1048
1049#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 6
1050 template <class ARGS_01,
1051 class ARGS_02,
1052 class ARGS_03,
1053 class ARGS_04,
1054 class ARGS_05,
1055 class ARGS_06>
1056 reference emplace_back(
1057 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1058 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1059 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1060 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1061 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1062 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06);
1063#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 6
1064
1065#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 7
1066 template <class ARGS_01,
1067 class ARGS_02,
1068 class ARGS_03,
1069 class ARGS_04,
1070 class ARGS_05,
1071 class ARGS_06,
1072 class ARGS_07>
1073 reference emplace_back(
1074 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1075 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1076 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1077 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1078 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1079 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1080 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07);
1081#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 7
1082
1083#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 8
1084 template <class ARGS_01,
1085 class ARGS_02,
1086 class ARGS_03,
1087 class ARGS_04,
1088 class ARGS_05,
1089 class ARGS_06,
1090 class ARGS_07,
1091 class ARGS_08>
1092 reference emplace_back(
1093 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1094 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1095 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1096 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1097 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1098 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1099 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
1100 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08);
1101#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 8
1102
1103#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 9
1104 template <class ARGS_01,
1105 class ARGS_02,
1106 class ARGS_03,
1107 class ARGS_04,
1108 class ARGS_05,
1109 class ARGS_06,
1110 class ARGS_07,
1111 class ARGS_08,
1112 class ARGS_09>
1113 reference emplace_back(
1114 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1115 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1116 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1117 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1118 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1119 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1120 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
1121 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
1122 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09);
1123#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 9
1124
1125#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 10
1126 template <class ARGS_01,
1127 class ARGS_02,
1128 class ARGS_03,
1129 class ARGS_04,
1130 class ARGS_05,
1131 class ARGS_06,
1132 class ARGS_07,
1133 class ARGS_08,
1134 class ARGS_09,
1135 class ARGS_10>
1136 reference emplace_back(
1137 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1138 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1139 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1140 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1141 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1142 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1143 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
1144 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
1145 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
1146 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10);
1147#endif // BSLSTL_LIST_VARIADIC_LIMIT_A >= 10
1148
1149#else
1150// The generated code below is a workaround for the absence of perfect
1151// forwarding in some compilers.
1152 template <class... ARGS>
1153 reference emplace_back(
1154 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments);
1155// }}} END GENERATED CODE
1156#endif
1157
1158#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
1159// {{{ BEGIN GENERATED CODE
1160// Command line: sim_cpp11_features.pl bslstl_list.h
1161#ifndef BSLSTL_LIST_VARIADIC_LIMIT
1162#define BSLSTL_LIST_VARIADIC_LIMIT 10
1163#endif
1164#ifndef BSLSTL_LIST_VARIADIC_LIMIT_B
1165#define BSLSTL_LIST_VARIADIC_LIMIT_B BSLSTL_LIST_VARIADIC_LIMIT
1166#endif
1167#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 0
1168 reference emplace_front(
1169 );
1170#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 0
1171
1172#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 1
1173 template <class ARGS_01>
1174 reference emplace_front(
1175 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01);
1176#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 1
1177
1178#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 2
1179 template <class ARGS_01,
1180 class ARGS_02>
1181 reference emplace_front(
1182 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1183 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02);
1184#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 2
1185
1186#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 3
1187 template <class ARGS_01,
1188 class ARGS_02,
1189 class ARGS_03>
1190 reference emplace_front(
1191 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1192 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1193 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03);
1194#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 3
1195
1196#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 4
1197 template <class ARGS_01,
1198 class ARGS_02,
1199 class ARGS_03,
1200 class ARGS_04>
1201 reference emplace_front(
1202 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1203 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1204 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1205 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04);
1206#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 4
1207
1208#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 5
1209 template <class ARGS_01,
1210 class ARGS_02,
1211 class ARGS_03,
1212 class ARGS_04,
1213 class ARGS_05>
1214 reference emplace_front(
1215 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1216 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1217 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1218 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1219 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05);
1220#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 5
1221
1222#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 6
1223 template <class ARGS_01,
1224 class ARGS_02,
1225 class ARGS_03,
1226 class ARGS_04,
1227 class ARGS_05,
1228 class ARGS_06>
1229 reference emplace_front(
1230 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1231 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1232 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1233 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1234 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1235 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06);
1236#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 6
1237
1238#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 7
1239 template <class ARGS_01,
1240 class ARGS_02,
1241 class ARGS_03,
1242 class ARGS_04,
1243 class ARGS_05,
1244 class ARGS_06,
1245 class ARGS_07>
1246 reference emplace_front(
1247 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1248 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1249 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1250 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1251 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1252 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1253 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07);
1254#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 7
1255
1256#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 8
1257 template <class ARGS_01,
1258 class ARGS_02,
1259 class ARGS_03,
1260 class ARGS_04,
1261 class ARGS_05,
1262 class ARGS_06,
1263 class ARGS_07,
1264 class ARGS_08>
1265 reference emplace_front(
1266 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1267 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1268 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1269 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1270 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1271 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1272 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
1273 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08);
1274#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 8
1275
1276#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 9
1277 template <class ARGS_01,
1278 class ARGS_02,
1279 class ARGS_03,
1280 class ARGS_04,
1281 class ARGS_05,
1282 class ARGS_06,
1283 class ARGS_07,
1284 class ARGS_08,
1285 class ARGS_09>
1286 reference emplace_front(
1287 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1288 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1289 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1290 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1291 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1292 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1293 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
1294 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
1295 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09);
1296#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 9
1297
1298#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 10
1299 template <class ARGS_01,
1300 class ARGS_02,
1301 class ARGS_03,
1302 class ARGS_04,
1303 class ARGS_05,
1304 class ARGS_06,
1305 class ARGS_07,
1306 class ARGS_08,
1307 class ARGS_09,
1308 class ARGS_10>
1309 reference emplace_front(
1310 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1311 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1312 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1313 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1314 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1315 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1316 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
1317 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
1318 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
1319 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10);
1320#endif // BSLSTL_LIST_VARIADIC_LIMIT_B >= 10
1321
1322#else
1323// The generated code below is a workaround for the absence of perfect
1324// forwarding in some compilers.
1325 template <class... ARGS>
1326 reference emplace_front(
1327 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments);
1328// }}} END GENERATED CODE
1329#endif
1330
1331 /// Prepend to the front of this object the elements of the specified `range`.
1332 ///
1333 /// \note Note that `range` must meet the requirements of an input
1334 /// range and the values from `range` must have a type matching or
1335 /// convertible to (template parameter) `VALUE`.
1336 template <class t_RANGE>
1338 void prepend_range(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range);
1339
1340 /// Append to the back of this list a copy of the specified `value`.
1341 /// This method offers full guarantee of rollback in case an exception
1342 /// is thrown. This method requires that the (template parameter)
1343 /// `VALUE` be `copy-constructible` (see {Requirements on `VALUE`}).
1344 void push_back(const value_type& value);
1345
1346 /// Append to the back of this list the specified move-insertable
1347 /// `value`. `value` is left in a valid but unspecified state. If an
1348 /// exception is thrown (other than by the move constructor of a
1349 /// non-copy-insertable `value_type`), this method has no effect. This
1350 /// method requires that the (template parameter) `VALUE` be
1351 /// `move-insertable` into this list (see {Requirements on `VALUE`}).
1352 void push_back(BloombergLP::bslmf::MovableRef<value_type> value);
1353
1354 /// Prepend to the front of this list a copy of the specified `value`.
1355 /// This method offers full guarantee of rollback in case an exception
1356 /// is thrown. This method requires that the (template parameter)
1357 /// `VALUE` be `copy-constructible` (see {Requirements on `VALUE`}).
1358 void push_front(const value_type& value);
1359
1360 /// Prepend to the front of this list the specified move-insertable
1361 /// `value`. `value` is left in a valid but unspecified state. If an
1362 /// exception is thrown (other than by the move constructor of a
1363 /// non-copy-insertable `value_type`), this method has no effect. This
1364 /// method requires that the (template parameter) `VALUE` be
1365 /// `move-insertable` into this list (see {Requirements on `VALUE`}).
1366 void push_front(BloombergLP::bslmf::MovableRef<value_type> value);
1367
1368 // *** random access inserts ***
1369
1370#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
1371// {{{ BEGIN GENERATED CODE
1372// Command line: sim_cpp11_features.pl bslstl_list.h
1373#ifndef BSLSTL_LIST_VARIADIC_LIMIT
1374#define BSLSTL_LIST_VARIADIC_LIMIT 10
1375#endif
1376#ifndef BSLSTL_LIST_VARIADIC_LIMIT_C
1377#define BSLSTL_LIST_VARIADIC_LIMIT_C BSLSTL_LIST_VARIADIC_LIMIT
1378#endif
1379#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 0
1380 iterator emplace(const_iterator position);
1381#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 0
1382
1383#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 1
1384 template <class ARGS_01>
1385 iterator emplace(const_iterator position,
1386 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01);
1387#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 1
1388
1389#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 2
1390 template <class ARGS_01,
1391 class ARGS_02>
1392 iterator emplace(const_iterator position,
1393 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1394 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02);
1395#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 2
1396
1397#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 3
1398 template <class ARGS_01,
1399 class ARGS_02,
1400 class ARGS_03>
1401 iterator emplace(const_iterator position,
1402 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1403 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1404 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03);
1405#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 3
1406
1407#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 4
1408 template <class ARGS_01,
1409 class ARGS_02,
1410 class ARGS_03,
1411 class ARGS_04>
1412 iterator emplace(const_iterator position,
1413 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1414 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1415 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1416 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04);
1417#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 4
1418
1419#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 5
1420 template <class ARGS_01,
1421 class ARGS_02,
1422 class ARGS_03,
1423 class ARGS_04,
1424 class ARGS_05>
1425 iterator emplace(const_iterator position,
1426 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1427 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1428 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1429 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1430 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05);
1431#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 5
1432
1433#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 6
1434 template <class ARGS_01,
1435 class ARGS_02,
1436 class ARGS_03,
1437 class ARGS_04,
1438 class ARGS_05,
1439 class ARGS_06>
1440 iterator emplace(const_iterator position,
1441 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1442 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1443 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1444 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1445 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1446 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06);
1447#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 6
1448
1449#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 7
1450 template <class ARGS_01,
1451 class ARGS_02,
1452 class ARGS_03,
1453 class ARGS_04,
1454 class ARGS_05,
1455 class ARGS_06,
1456 class ARGS_07>
1457 iterator emplace(const_iterator position,
1458 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1459 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1460 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1461 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1462 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1463 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1464 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07);
1465#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 7
1466
1467#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 8
1468 template <class ARGS_01,
1469 class ARGS_02,
1470 class ARGS_03,
1471 class ARGS_04,
1472 class ARGS_05,
1473 class ARGS_06,
1474 class ARGS_07,
1475 class ARGS_08>
1476 iterator emplace(const_iterator position,
1477 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1478 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1479 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1480 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1481 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1482 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1483 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
1484 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08);
1485#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 8
1486
1487#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 9
1488 template <class ARGS_01,
1489 class ARGS_02,
1490 class ARGS_03,
1491 class ARGS_04,
1492 class ARGS_05,
1493 class ARGS_06,
1494 class ARGS_07,
1495 class ARGS_08,
1496 class ARGS_09>
1497 iterator emplace(const_iterator position,
1498 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1499 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1500 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1501 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1502 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1503 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1504 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
1505 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
1506 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09);
1507#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 9
1508
1509#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 10
1510 template <class ARGS_01,
1511 class ARGS_02,
1512 class ARGS_03,
1513 class ARGS_04,
1514 class ARGS_05,
1515 class ARGS_06,
1516 class ARGS_07,
1517 class ARGS_08,
1518 class ARGS_09,
1519 class ARGS_10>
1520 iterator emplace(const_iterator position,
1521 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
1522 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
1523 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
1524 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
1525 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
1526 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
1527 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
1528 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
1529 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
1530 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10);
1531#endif // BSLSTL_LIST_VARIADIC_LIMIT_C >= 10
1532
1533#else
1534// The generated code below is a workaround for the absence of perfect
1535// forwarding in some compilers.
1536 template <class... ARGS>
1537 iterator emplace(const_iterator position,
1538 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments);
1539// }}} END GENERATED CODE
1540#endif
1541
1542 /// Insert at the specified `dstPosition` in this list a copy of the
1543 /// specified `value`, and return an iterator providing modifiable
1544 /// access to the newly inserted element. This method offers full
1545 /// guarantee of rollback in case an exception is thrown other than by
1546 /// the `VALUE` copy constructor or assignment operator. This method
1547 /// requires that the (template parameter) `VALUE` be `copy-insertable`
1548 /// into this list (see {Requirements on `VALUE`}).
1549 ///
1550 /// \pre The behavior is undefined unless `dstPosition` is an iterator in the range
1551 /// `[cbegin() .. cend()] (both endpoints included)`.
1552 iterator insert(const_iterator dstPosition, const value_type& value);
1553
1554 /// Insert at the specified `dstPosition` in this list the specified
1555 /// move-insertable `value`, and return an iterator providing modifiable
1556 /// access to the newly inserted element. `value` is left in a valid
1557 /// but unspecified state. If an exception is thrown (other than by the
1558 /// copy constructor, move constructor, assignment operator, or move
1559 /// assignment operator of `value_type`), this method has no effect.
1560 /// This method requires that the (template parameter) `VALUE` be
1561 /// `move-insertable` into this list (see {Requirements on `VALUE`}).
1562 ///
1563 /// \pre The behavior is undefined unless `dstPosition` is an iterator in the
1564 /// range `[cbegin() .. cend()]` (both endpoints included).
1565 iterator insert(const_iterator dstPosition,
1566 BloombergLP::bslmf::MovableRef<value_type> value);
1567
1568 /// Insert at the specified `dstPosition` in this list the specified
1569 /// `numElements` copies of the specified `value`, and return an
1570 /// iterator providing modifiable access to the first element in the
1571 /// newly inserted sequence of elements. This method requires that the
1572 /// (template parameter) `VALUE` be `copy-insertable` into this list (see {Requirements on `VALUE`}).
1573 ///
1574 /// \pre The behavior is undefined unless
1575 /// `dstPosition` is an iterator in the range `[cbegin() .. cend()]`
1576 /// (both endpoints included).
1577 iterator insert(const_iterator dstPosition,
1578 size_type numElements,
1579 const value_type& value);
1580
1581 /// Insert at the specified `dstPosition` in this list the values in the
1582 /// range starting at the specified `first` and ending immediately
1583 /// before the specified `last` iterators of the (template parameter)
1584 /// type `INPUT_ITERATOR`, and return an iterator providing modifiable
1585 /// access to the first element in the newly inserted sequence of
1586 /// elements. The (template parameter) type `INPUT_ITERATOR` shall meet
1587 /// the requirements of an input iterator defined in the C++11 standard
1588 /// [input.iterators] providing access to values of a type convertible
1589 /// to `value_type`, and `value_type` must be `emplace-constructible`
1590 /// from `*i` into this list, where `i` is a dereferenceable iterator in
1591 /// the range `[first .. last)` (see {Requirements on `VALUE`}).
1592 ///
1593 /// \pre The behavior is undefined unless `dstPosition` is an iterator in the
1594 /// range `[cbegin() .. cend()]` (both endpoints included), and `first`
1595 /// and `last` refer to a sequence of valid values where `first` is at a
1596 /// position at or before `last`.
1597 template <class INPUT_ITERATOR>
1598 iterator insert(const_iterator dstPosition,
1599 INPUT_ITERATOR first,
1600 INPUT_ITERATOR last,
1601 typename enable_if<
1604 >::type * = 0)
1605 {
1606 // MS Visual Studio 2008 compiler requires that a function using
1607 // enable_if be in place inline.
1608
1609 if (first == last) {
1610 return dstPosition.unconst(); // RETURN
1611 }
1612
1613 // The return value should indicate the first node inserted. We can't
1614 // assume 'INPUT_ITERATOR' has a post-increment available.
1615
1616 iterator ret = insert(dstPosition, *first);
1617 for (++first; first != last; ++first) {
1618 insert(dstPosition, *first);
1619 }
1620
1621 return ret;
1622 }
1623
1624#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1625 /// Insert at the specified `dstPosition` in this list the value of each
1626 /// `value_type` object in the specified `values` initializer list, and
1627 /// return an iterator providing modifiable access to the first element
1628 /// in the newly inserted sequence of elements. This method requires
1629 /// that the (template parameter) `VALUE` be `copy-insertable` into this
1630 /// list (see {Requirements on `VALUE`}).
1631 ///
1632 /// \pre The behavior is undefined unless `dstPosition` is an iterator in the range
1633 /// `[cbegin() .. cend()]` (both endpoints included).
1634 iterator insert(const_iterator dstPosition,
1635 std::initializer_list<value_type> values);
1636#endif
1637
1638 /// Insert at the specified `position` in this object the elements of the specified `range`.
1639 ///
1640 /// \note Note that `range` must meet the requirements of an
1641 /// input range and the values from `range` must have a type matching or
1642 /// convertible to (template parameter) `VALUE`.
1643 template <class t_RANGE>
1645 iterator insert_range(const_iterator position,
1646 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range);
1647
1648 // *** list operations ***
1649
1650 /// Merge the specified sorted `other` list into this sorted list. This
1651 /// method has no effect if `other` is this list; otherwise, `other` is left empty.
1652 ///
1653 /// \pre The behavior is undefined unless both `other` and this
1654 /// list are sorted in non-decreasing order according to the ordering
1655 /// provided by `operator<`, and unless both `other` and this list use
1656 /// the same allocator. `operator<` must define a strict weak ordering
1657 /// per `value_type` (see {Comparators and Strict Weak Ordering}).
1658 void merge(list& other);
1659 void merge(BloombergLP::bslmf::MovableRef<list> other);
1660
1661 /// Merge the specified sorted `other` list into this sorted list, using
1662 /// the specified binary `comparator` predicate to order elements. This
1663 /// method has no effect if `other` is this list; otherwise, `other` is left empty.
1664 ///
1665 /// \pre The behavior is undefined unless both `other` and this
1666 /// list are sorted in non-decreasing order according to the ordering
1667 /// provided by `comparator`, and unless both `other` and this list use
1668 /// the same allocator.
1669 template <class COMPARE>
1670 void merge(list& other, COMPARE comparator);
1671 template <class COMPARE>
1672 void merge(BloombergLP::bslmf::MovableRef<list> other, COMPARE comparator);
1673
1674 /// Erase all the elements having the specified `value` from this list
1675 /// and return the number of erased elements.
1676 size_type remove(const value_type& value);
1677
1678 /// Erase all the elements in this list for which the specified unary
1679 /// `predicate` returns `true` and return the number of erased elements.
1680 template <class PREDICATE>
1681 size_type remove_if(PREDICATE predicate);
1682
1683 /// Reverse the order of the elements in this list.
1684 void reverse() BSLS_KEYWORD_NOEXCEPT;
1685
1686 /// Sort this list in non-decreasing order according to the order provided
1687 /// by `operator<`. `operator<` must provide a strict weak ordering over
1688 /// `value_type` (see @ref bslstl_list_cpp03-comparators-and-strict-weak-ordering ). The sort is
1689 /// stable, meaning that if `!(a < b) && !(b < a)`, then the ordering of
1690 /// elements `a` and `b` in the sequence is preserved.
1691 void sort();
1692
1693 /// Sort this list in non-decreasing order according to the order provided
1694 /// by the specified `comparator` predicate. `comparator` must define a
1695 /// strict weak ordering over `value_type` (see
1696 /// @ref bslstl_list_cpp03-comparators-and-strict-weak-ordering ). The sort is stable,
1697 /// meaning that if `!comparator(a, b) && !comparator(b, a)`, then the
1698 /// ordering of elements `a` and `b` in the sequence is preserved.
1699 template <class COMPARE>
1700 void sort(COMPARE comparator);
1701
1702 /// Remove all elements of the specified `src` list and insert them, in
1703 /// the same order, in this list at the specified `dstPosition`.
1704 ///
1705 /// \pre The behavior is undefined unless `src` is not this list, this list and
1706 /// `src` use the same allocator, and `dstPosition` is in the range
1707 /// `[begin() .. end()]` (note both endpoints included).
1708 void splice(const_iterator dstPosition,
1709 list& src);
1710 void splice(const_iterator dstPosition,
1711 BloombergLP::bslmf::MovableRef<list> src);
1712
1713 /// Remove the single element at the specified `srcNode` from the
1714 /// specified `src` list, and insert it at the specified `dstPosition` in this list.
1715 ///
1716 /// \pre The behavior is undefined unless `srcNode` refers to
1717 /// a valid element in `src`, this list and `src` use the same
1718 /// allocator, and `dstPosition` is in the range `[begin() .. end()]` (note both endpoints included).
1719 ///
1720 /// \note Note that `src` and `*this` may be
1721 /// the same list, in which case the element is moved to a (possibly)
1722 /// new position in the list.
1723 void splice(const_iterator dstPosition,
1724 list& src,
1725 const_iterator srcNode);
1726 void splice(const_iterator dstPosition,
1727 BloombergLP::bslmf::MovableRef<list> src,
1728 const_iterator srcNode);
1729
1730 /// Remove the elements in the specified range `[first .. last)` from
1731 /// the specified `src` list, and insert them, in the same order, at the
1732 /// specified `dstPosition` in this list.
1733 ///
1734 /// \pre The behavior is undefined unless `[first .. last)` represents a range of valid elements in
1735 /// `src`, `dstPosition` is not in the range `[first .. last)`, this
1736 /// list and `src` use the same allocator, and `dstPosition` is in the
1737 /// range `[begin() .. end()]` (note both endpoints included).
1738 ///
1739 /// \note Note that `src` and `*this` may be the same list, in which case an entire
1740 /// sequence of nodes is moved to a (possibly) new position in this
1741 /// list.
1742 void splice(const_iterator dstPosition,
1743 list& src,
1744 const_iterator first,
1745 const_iterator last);
1746 void splice(const_iterator dstPosition,
1747 BloombergLP::bslmf::MovableRef<list> src,
1748 const_iterator first,
1749 const_iterator last);
1750
1751 /// Erase from this list all but the first element of every consecutive
1752 /// group of elements that have the same value.
1753 void unique();
1754
1755 /// Erase from this list all but the first element of every consecutive
1756 /// group of elements for which the specified `binaryPredicate` returns
1757 /// `true` for any two consecutive elements in the group.
1758 template <class EQ_PREDICATE>
1759 void unique(EQ_PREDICATE binaryPredicate);
1760
1761 // *** misc ***
1762
1763 /// Exchange the value of this object with that of the specified `other`
1764 /// object; also exchange the allocator of this object with that of `other`
1765 /// if the (template parameter) type `ALLOCATOR` has the
1766 /// @ref propagate_on_container_swap trait, and do not modify either allocator
1767 /// otherwise. This method provides the no-throw exception-safety
1768 /// guarantee. This operation has `O[1]` complexity if either this object
1769 /// was created with the same allocator as `other` or `ALLOCATOR` has the
1770 /// @ref propagate_on_container_swap trait; otherwise, it has `O[n + m]`
1771 /// complexity, where `n` and `m` are the number of elements in this object and `other`, respectively.
1772 ///
1773 /// \note Note that this method`s support for
1774 /// swapping objects created with different allocators when `ALLOCATOR`
1775 /// does not have the @ref propagate_on_container_swap trait is a departure
1776 /// from the C++ Standard.
1777 void swap(list& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(
1778 AllocTraits::is_always_equal::value);
1779
1780 // ACCESSORS
1781
1782 // *** iterators ***
1783
1784 const_iterator begin() const BSLS_KEYWORD_NOEXCEPT;
1785
1786 /// Return an iterator providing non-modifiable access to the first
1787 /// `value_type` object in the ordered sequence of `value_type` objects
1788 /// maintained by this list, or the `end` iterator if this list is empty.
1789 const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT;
1790
1791 const_iterator end() const BSLS_KEYWORD_NOEXCEPT;
1792
1793 /// Return the past-the-end (forward) iterator providing non-modifiable
1794 /// access to this list.
1795 const_iterator cend() const BSLS_KEYWORD_NOEXCEPT;
1796
1797 const_reverse_iterator rbegin() const BSLS_KEYWORD_NOEXCEPT;
1798
1799 /// Return a reverse iterator providing non-modifiable access to the last
1800 /// element in this list, and the past-the-end reverse iterator if this
1801 /// list is empty.
1802 const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT;
1803
1804 const_reverse_iterator rend() const BSLS_KEYWORD_NOEXCEPT;
1805
1806 /// Return the past-the-end reverse iterator providing non-modifiable
1807 /// access to this list.
1808 const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT;
1809
1810 // *** size ***
1811
1812 /// Return `true` if this list has no elements, and `false` otherwise.
1813 bool empty() const BSLS_KEYWORD_NOEXCEPT;
1814
1815 /// Return an upper bound on the largest number of elements that this list could possibly hold.
1816 ///
1817 /// \note Note that the return value of this function does
1818 /// not guarantee that this list can successfully grow that large, or even
1819 /// close to that large without running out of resources.
1820 size_type max_size() const BSLS_KEYWORD_NOEXCEPT;
1821
1822 /// Return the number of elements in this list.
1823 size_type size() const BSLS_KEYWORD_NOEXCEPT;
1824
1825 // *** element access ***
1826
1827 /// Return a reference providing non-modifiable access to the last element of this list.
1828 ///
1829 /// \pre The behavior is undefined unless this list contains at
1830 /// least one element.
1831 const_reference back() const;
1832
1833 /// Return a reference providing non-modifiable access to the first element of this list.
1834 ///
1835 /// \pre The behavior is undefined unless this list contains at
1836 /// least one element.
1837 const_reference front() const;
1838
1839 // *** misc ***
1840
1841 /// Return a copy of the allocator used for memory allocation by this list.
1842 allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT;
1843};
1844
1845#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1846// CLASS TEMPLATE DEDUCTION GUIDES
1847
1848/// Deduce the template parameter `VALUE` from the corresponding parameter
1849/// supplied to the constructor of `list`. This deduction guide does not
1850/// participate unless the supplied allocator is convertible to
1851/// `bsl::allocator<VALUE>`.
1852template <
1853 class SIZE_TYPE,
1854 class VALUE,
1855 class ALLOC,
1856 class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
1857 class = bsl::enable_if_t<
1858 bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>,
1859 class = bsl::enable_if_t<
1860 bsl::is_convertible_v<
1861 SIZE_TYPE,
1863 >
1864list(SIZE_TYPE, VALUE, ALLOC *) -> list<VALUE>;
1865
1866/// Deduce the template parameter `VALUE` from the `value_type` of the
1867/// iterators supplied to the constructor of `list`.
1868template <
1869 class INPUT_ITERATOR,
1870 class VALUE = typename
1871 BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>
1872 >
1873list(INPUT_ITERATOR, INPUT_ITERATOR) -> list<VALUE>;
1874
1875/// Deduce the template parameter `VALUE` from the `value_type` of the
1876/// iterators supplied to the constructor of `list`. Deduce the template
1877/// parameter `ALLOCATOR` from the allocator supplied to the constructor of
1878/// `list`. This deduction guide does not participate unless the supplied
1879/// allocator meets the requirements of a standard allocator.
1880template<
1881 class INPUT_ITERATOR,
1882 class ALLOCATOR,
1883 class VALUE = typename
1884 BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1885 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>>
1886list(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR) -> list<VALUE, ALLOCATOR>;
1887
1888/// Deduce the template parameter `VALUE` from the value_type of the
1889/// iterators supplied to the constructor of `list`. This deduction guide
1890/// does not participate unless the specified `ALLOC` is convertible to
1891/// `bsl::allocator<CHAR_TYPE>`.
1892template<
1893 class INPUT_ITERATOR,
1894 class ALLOC,
1895 class VALUE = typename
1896 BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1897 class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
1898 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1899 >
1900list(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
1901-> list<VALUE>;
1902
1903/// Deduce the template parameter `VALUE` from the value_type of the
1904/// intializer_list supplied to the constructor of `list`. This deduction
1905/// guide does not participate unless the specified `ALLOC` is convertible
1906/// to `bsl::allocator<CHAR_TYPE>`.
1907template<
1908 class VALUE,
1909 class ALLOC,
1910 class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
1911 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1912 >
1913list(std::initializer_list<VALUE>, ALLOC *)
1914-> list<VALUE>;
1915
1916#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
1917 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
1918/// Deduce the template parameters `VALUE_TYPE` and `ALLOCATOR` from the
1919/// parameters supplied to the constructor of `list`.
1920template <ranges::input_range t_RANGE,
1921 class t_ALLOCATOR =
1922 allocator<ranges::range_value_t<t_RANGE>>>
1923list(from_range_t, t_RANGE&&, t_ALLOCATOR = t_ALLOCATOR())
1924-> list<ranges::range_value_t<t_RANGE>, t_ALLOCATOR>;
1925#endif
1926#endif
1927
1928// FREE OPERATORS
1929
1930/// Return `true` if the specified `lhs` and `rhs` objects have the same
1931/// value, and `false` otherwise. Two `list` objects `lhs` and `rhs` have
1932/// the same value if they have the same number of elements, and each
1933/// element in the ordered sequence of elements of `lhs` has the same value
1934/// as the corresponding element in the ordered sequence of elements of
1935/// `rhs`. This method requires that the (template parameter) type `VALUE`
1936/// be `equality-comparable` (see {Requirements on `VALUE`}).
1937template <class VALUE, class ALLOCATOR>
1938bool operator==(const list<VALUE, ALLOCATOR>& lhs,
1939 const list<VALUE, ALLOCATOR>& rhs);
1940
1941#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1942
1943/// Return `true` if the specified `lhs` and `rhs` objects do not have the
1944/// same value, and `false` otherwise. Two `list` objects `lhs` and `rhs`
1945/// do not have the same value if they do not have the same number of
1946/// elements, or some element in the ordered sequence of elements of `lhs`
1947/// does not have the same value as the corresponding element in the ordered
1948/// sequence of elements of `rhs`. This method requires that the
1949/// (template parameter) type `VALUE` be `equality-comparable` (see
1950/// {Requirements on `VALUE`}).
1951template <class VALUE, class ALLOCATOR>
1952bool operator!=(const list<VALUE, ALLOCATOR>& lhs,
1953 const list<VALUE, ALLOCATOR>& rhs);
1954
1955#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1956
1957#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1958
1959/// Perform a lexicographic three-way comparison of the specified `lhs` and
1960/// the specified `rhs` lists by using the comparison operators of `VALUE`
1961/// on each element; return the result of that comparison.
1962template <class VALUE, class ALLOCATOR>
1963BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE> operator<=>(
1964 const list<VALUE, ALLOCATOR>& lhs,
1965 const list<VALUE, ALLOCATOR>& rhs);
1966
1967#else
1968
1969/// Return `true` if the value of the specified `lhs` list is lexicographically
1970/// less than that of the specified `rhs` list, and `false` otherwise. Given
1971/// iterators `i` and `j` over the respective sequences `[lhs.begin() ..
1972/// lhs.end())` and `[rhs.begin() .. rhs.end())`, the value of list `lhs` is
1973/// lexicographically less than that of list `rhs` if `true == *i < *j` for the
1974/// first pair of corresponding iterator positions where `*i < *j` and `*j <
1975/// *i` are not both `false`. If no such corresponding iterator position
1976/// exists, the value of `lhs` is lexicographically less than that of `rhs` if
1977/// `lhs.size() < rhs.size()`. This method requires that `operator<`, inducing
1978/// a total order, be defined for `value_type`.
1979template <class VALUE, class ALLOCATOR>
1980bool operator< (const list<VALUE, ALLOCATOR>& lhs,
1981 const list<VALUE, ALLOCATOR>& rhs);
1982
1983/// Return `true` if the value of the specified `lhs` list is lexicographically
1984/// greater than that of the specified `rhs` list, and `false` otherwise. The
1985/// value of list `lhs` is lexicographically greater than that of list `rhs` if
1986/// `rhs` is lexicographically less than `lhs` (see `operator<`). This method
1987/// requires that `operator<`, inducing a total order, be defined for `value_type`.
1988///
1989/// \note Note that this operator returns `rhs < lhs`.
1990template <class VALUE, class ALLOCATOR>
1991bool operator> (const list<VALUE, ALLOCATOR>& lhs,
1992 const list<VALUE, ALLOCATOR>& rhs);
1993
1994/// Return `true` if the value of the specified `lhs` list is lexicographically
1995/// less than or equal to that of the specified `rhs` list, and `false`
1996/// otherwise. The value of list `lhs` is lexicographically less than or equal
1997/// to that of list `rhs` if `rhs` is not lexicographically less than `lhs`
1998/// (see `operator<`). This method requires that `operator<`, inducing a total order, be defined for `value_type`.
1999///
2000/// \note Note that this operator returns `!(rhs
2001/// < lhs)`.
2002template <class VALUE, class ALLOCATOR>
2003bool operator<=(const list<VALUE, ALLOCATOR>& lhs,
2004 const list<VALUE, ALLOCATOR>& rhs);
2005
2006/// Return `true` if the value of the specified `lhs` list is lexicographically
2007/// greater than or equal to that of the specified `rhs` list, and `false`
2008/// otherwise. The value of list `lhs` is lexicographically greater than or
2009/// equal to that of list `rhs` if `lhs` is not lexicographically less than
2010/// `rhs` (see `operator<`). This method requires that `operator<`, inducing a total order, be defined for `value_type`.
2011///
2012/// \note Note that this operator returns
2013/// `!(lhs < rhs)`.
2014template <class VALUE, class ALLOCATOR>
2015bool operator>=(const list<VALUE, ALLOCATOR>& lhs,
2016 const list<VALUE, ALLOCATOR>& rhs);
2017
2018#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2019
2020// FREE FUNCTIONS
2021
2022/// Erase all the elements in the specified list `l` that compare equal to
2023/// the specified `value`. Return the number of elements erased.
2024template <class VALUE, class ALLOCATOR, class BDE_OTHER_TYPE>
2025typename list<VALUE, ALLOCATOR>::size_type
2026erase(list<VALUE, ALLOCATOR>& l, const BDE_OTHER_TYPE& value);
2027
2028/// Erase all the elements in the specified list `l` that satisfy the
2029/// specified predicate `predicate`. Return the number of elements erased.
2030template <class VALUE, class ALLOCATOR, class PREDICATE>
2031typename list<VALUE, ALLOCATOR>::size_type
2032erase_if(list<VALUE, ALLOCATOR>& l, PREDICATE predicate);
2033
2034/// Exchange the value of the specified `a` object with that of the specified
2035/// `b` object; also exchange the allocator of `a` with that of `b` if the
2036/// (template parameter) type `ALLOCATOR` has the @ref propagate_on_container_swap
2037/// trait, and do not modify either allocator otherwise. This function
2038/// provides the no-throw exception-safety guarantee. This operation has
2039/// `O[1]` complexity if either `a` was created with the same allocator as `b`
2040/// or `ALLOCATOR` has the @ref propagate_on_container_swap trait; otherwise, it
2041/// has `O[n + m]` complexity, where `n` and `m` are the number of elements in `a` and `b`, respectively.
2042///
2043/// \note Note that this function`s support for swapping
2044/// objects created with different allocators when `ALLOCATOR` does not have
2045/// the @ref propagate_on_container_swap trait is a departure from the C++
2046/// Standard.
2047template <class VALUE, class ALLOCATOR>
2048void swap(list<VALUE, ALLOCATOR>& a, list<VALUE, ALLOCATOR>& b)
2050 a.swap(b)));
2051
2052// ============================================================================
2053// INLINE AND TEMPLATE FUNCTION DEFINITIONS
2054// ============================================================================
2055
2056 // ------------------------
2057 // class bsl::List_Iterator
2058 // ------------------------
2059
2060// PRIVATE ACCESSORS
2061template <class VALUE>
2062inline
2063typename List_Iterator<VALUE>::NcIter List_Iterator<VALUE>::unconst() const
2064{
2065 return NcIter(d_node_p);
2066}
2067
2068// CREATORS
2069template <class VALUE>
2070inline
2072: d_node_p()
2073{
2074}
2075
2076template <class VALUE>
2077inline
2078List_Iterator<VALUE>::List_Iterator(Node *nodePtr)
2079: d_node_p(nodePtr)
2080{
2081}
2082
2083template <class VALUE>
2084inline
2085List_Iterator<VALUE>::List_Iterator(const NcIter& other)
2086: d_node_p(other.d_node_p)
2087{
2088}
2089
2090// MANIPULATORS
2091template <class VALUE>
2092inline
2093List_Iterator<VALUE>& List_Iterator<VALUE>::operator++()
2094{
2095 this->d_node_p = this->d_node_p->d_next_p;
2096 return *this;
2097}
2098
2099template <class VALUE>
2100inline
2101List_Iterator<VALUE>& List_Iterator<VALUE>::operator--()
2102{
2103 this->d_node_p = this->d_node_p->d_prev_p;
2104 return *this;
2105}
2106
2107template <class VALUE>
2108inline
2109List_Iterator<VALUE> List_Iterator<VALUE>::operator++(int)
2110{
2111 List_Iterator temp = *this;
2112 this->operator++();
2113 return temp;
2114}
2115
2116template <class VALUE>
2117inline
2118List_Iterator<VALUE> List_Iterator<VALUE>::operator--(int)
2119{
2120 List_Iterator temp = *this;
2121 this->operator--();
2122 return temp;
2123}
2124
2125// ACCESSORS
2126template <class VALUE>
2127inline
2129 List_Iterator<VALUE>::operator*() const
2130{
2131 return this->d_node_p->d_value;
2132}
2133
2134template <class VALUE>
2135inline
2137 List_Iterator<VALUE>::operator->() const
2138{
2139 return BloombergLP::bsls::Util::addressOf(this->d_node_p->d_value);
2140}
2141
2142// FREE OPERATORS
2143template <class T1, class T2>
2144inline
2146{
2147 // Make sure that this comparison will only compile if 'T1' and 'T2' match
2148 // except for a possible difference in 'const'-ness.
2149
2151 typename bsl::remove_cv<T2>::type>::value));
2152
2153 return lhs.d_node_p == rhs.d_node_p;
2154}
2155
2156#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2157template <class T1, class T2>
2158inline
2160{
2161 // Make sure that this comparison will only compile if 'T1' and 'T2' match
2162 // except for a possible difference in 'const'-ness.
2163
2165 typename bsl::remove_cv<T2>::type>::value));
2166
2167 return ! (lhs == rhs);
2168}
2169#endif
2170
2171 // ------------------------------
2172 // class List_AllocAndSizeWrapper
2173 // ------------------------------
2174
2175// CREATOR
2176template <class VALUE, class ALLOCATOR>
2177inline
2178List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::List_AllocAndSizeWrapper(
2179 const NodeAlloc& basicAllocator,
2180 size_type size)
2181: NodeAlloc(basicAllocator)
2182, d_size(size)
2183{
2184}
2185
2186// MANIPULATORS
2187template <class VALUE, class ALLOCATOR>
2188inline
2189typename List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::size_type&
2190List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::size()
2191{
2192 return d_size;
2193}
2194
2195// ACCESSORS
2196template <class VALUE, class ALLOCATOR>
2197inline
2198const typename List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::size_type&
2199List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::size() const
2200{
2201 return d_size;
2202}
2203
2204 // ----------------------
2205 // class List_NodeProctor
2206 // ----------------------
2207
2208// CREATORS
2209template <class VALUE, class ALLOCATOR>
2210inline
2211List_NodeProctor<VALUE, ALLOCATOR>::List_NodeProctor(
2212 list<VALUE, ALLOCATOR> *listPtr,
2213 NodePtr nodePtr)
2214: d_list_p(listPtr)
2215, d_node_p(nodePtr)
2216{
2217 BSLS_ASSERT_SAFE(listPtr);
2218 BSLS_ASSERT_SAFE(nodePtr);
2219}
2220
2221template <class VALUE, class ALLOCATOR>
2222inline
2223List_NodeProctor<VALUE, ALLOCATOR>::~List_NodeProctor()
2224{
2225 if (d_node_p) {
2226 d_list_p->freeNode(d_node_p);
2227 }
2228}
2229
2230// MANIPULATORS
2231template <class VALUE, class ALLOCATOR>
2232inline
2233void List_NodeProctor<VALUE, ALLOCATOR>::release()
2234{
2235 d_node_p = 0;
2236}
2237
2238 // --------------------------
2239 // class List_DefaultLessThan
2240 // --------------------------
2241
2242// ACCESSORS
2243template <class VALUE>
2244inline
2245bool List_DefaultLessThan<VALUE>::operator()(
2246 const VALUE& lhs, const VALUE& rhs) const
2247{
2248 return lhs < rhs;
2249}
2250
2251 // ---------------
2252 // class bsl::list
2253 // ---------------
2254
2255// PRIVATE MANIPULATORS
2256template <class VALUE, class ALLOCATOR>
2257inline
2258typename list<VALUE, ALLOCATOR>::NodeAlloc&
2259 list<VALUE, ALLOCATOR>::allocatorImp()
2260{
2261 return d_alloc_and_size; // implicit cast to base class
2262}
2263
2264template <class VALUE, class ALLOCATOR>
2265inline
2266typename list<VALUE, ALLOCATOR>::NodePtr list<VALUE, ALLOCATOR>::allocateNode()
2267{
2268 NodePtr ret = AllocTraits::allocate(allocatorImp(), 1);
2269 ret->d_prev_p = 0;
2270 ret->d_next_p = 0;
2271 return ret;
2272}
2273
2274template <class VALUE, class ALLOCATOR>
2275inline
2276void list<VALUE, ALLOCATOR>::createSentinel()
2277{
2278 BSLS_ASSERT_SAFE(size_type(-1) == sizeRef() || 0 == sizeRef());
2279
2280 d_sentinel = allocateNode();
2281 linkNodes(d_sentinel, d_sentinel); // circular
2282 sizeRef() = 0;
2283}
2284
2285template <class VALUE, class ALLOCATOR>
2286inline
2287void list<VALUE, ALLOCATOR>::deleteNode(NodePtr node)
2288{
2289 BSLS_ASSERT_SAFE(node);
2290
2291 AllocTraits::destroy(allocatorImp(),
2292 BloombergLP::bsls::Util::addressOf(node->d_value));
2293 AllocTraits::deallocate(allocatorImp(), node, 1);
2294}
2295
2296template <class VALUE, class ALLOCATOR>
2297inline
2298void list<VALUE, ALLOCATOR>::destroyAll()
2299{
2300 clear();
2301 freeNode(d_sentinel);
2302 sizeRef() = size_type(-1);
2303}
2304
2305template <class VALUE, class ALLOCATOR>
2306inline
2307void list<VALUE, ALLOCATOR>::freeNode(NodePtr node)
2308{
2309 AllocTraits::deallocate(allocatorImp(), node, 1);
2310}
2311
2312template <class VALUE, class ALLOCATOR>
2313inline
2314typename list<VALUE, ALLOCATOR>::iterator
2315list<VALUE, ALLOCATOR>::insertNode(const_iterator position, NodePtr node)
2316{
2317 NodePtr next = position.d_node_p;
2318 NodePtr prev = next->d_prev_p;
2319 linkNodes(prev, node);
2320 linkNodes(node, next);
2321 ++sizeRef();
2322 return iterator(node);
2323}
2324
2325template <class VALUE, class ALLOCATOR>
2326inline
2327void list<VALUE, ALLOCATOR>::linkNodes(NodePtr prev, NodePtr next)
2328{
2329 prev->d_next_p = next;
2330 next->d_prev_p = prev;
2331}
2332
2333template <class VALUE, class ALLOCATOR>
2334template <class COMPARE>
2335typename list<VALUE, ALLOCATOR>::NodePtr
2336list<VALUE, ALLOCATOR>::mergeImp(NodePtr node1,
2337 NodePtr node2,
2338 NodePtr finish,
2339 COMPARE comparator)
2340{
2341 NodePtr pre = node1->d_prev_p;
2342
2343 // The only possible throwing operation is the comparator. Exception
2344 // neutrality is achieved by ensuring that this list is in a valid state,
2345 // with no disconnected nodes, before the comparator is called.
2346
2347 // Having the two sublists be contiguous parts of the same list has the
2348 // following advantages:
2349 // 1. When we reach the end of a sublist, there is no "finalization" step
2350 // where the end of the remaining sublist must be spliced onto the
2351 // merged list.
2352 // 2. No cleanup needed if an exception is thrown; the size and validity of
2353 // the resulting list needs no adjustment.
2354
2355 while (node1 != node2 && node2 != finish) {
2356 // Loop invariants:
2357 // - The open range (pre, node1) is the current merged result
2358 // - The half-open range [node1, node2) is the 1st unmerged sequence
2359 // - The half-open range [node2, finish) is the 2nd unmerged sequence
2360
2361 if (comparator(node2->d_value, node1->d_value)) {
2362 // 'node2' should come before 'node1'.
2363
2364 // Find the end of the sequence of elements that belong before
2365 // node1 so that we can splice them all at once.
2366
2367 NodePtr lastMove = node2;
2368 NodePtr next2 = node2->d_next_p;
2369 while (next2 != finish && comparator(next2->d_value,
2370 node1->d_value)) {
2371 lastMove = next2;
2372 next2 = lastMove->d_next_p;
2373 }
2374
2375 linkNodes(node2->d_prev_p, next2);
2376 linkNodes(node1->d_prev_p, node2);
2377 linkNodes(lastMove, node1);
2378
2379 // Advance to next node in the 2nd unmerged sequence.
2380
2381 node2 = next2;
2382 }
2383 else {
2384 // Advance to next node in the 1st unmerged sequence.
2385
2386 node1 = node1->d_next_p;
2387 }
2388 }
2389
2390 return pre->d_next_p;
2391}
2392
2393template <class VALUE, class ALLOCATOR>
2394template <class t_ITERATOR, class t_SENTINEL>
2395inline
2396void list<VALUE, ALLOCATOR>::privateAppendRange(t_ITERATOR first,
2397 t_SENTINEL last)
2398{
2399 for (; first != last; ++first) {
2400 emplace_back(*first);
2401 }
2402}
2403
2404template <class VALUE, class ALLOCATOR>
2405inline
2406void list<VALUE, ALLOCATOR>::quickSwap(list *other)
2407{
2408 BSLS_ASSERT_SAFE(allocatorImp() == other->allocatorImp());
2409
2410 using std::swap;
2411
2412 swap(d_sentinel, other->d_sentinel);
2413 swap(sizeRef(), other->sizeRef());
2414}
2415
2416template <class VALUE, class ALLOCATOR>
2417inline
2418typename list<VALUE, ALLOCATOR>::AllocTraits::size_type&
2419list<VALUE, ALLOCATOR>::sizeRef() BSLS_KEYWORD_NOEXCEPT
2420{
2421 return d_alloc_and_size.size();
2422}
2423
2424template <class VALUE, class ALLOCATOR>
2425template <class COMPARE>
2426typename list<VALUE, ALLOCATOR>::NodePtr
2427list<VALUE, ALLOCATOR>::sortImp(NodePtr *nodePtrPtr,
2428 size_type size,
2429 const COMPARE& comparator)
2430{
2431 BSLS_ASSERT(size > 0);
2432
2433 NodePtr node1 = *nodePtrPtr;
2434 if (size < 2) {
2435 return node1->d_next_p; // RETURN
2436 }
2437
2438 size_type half = size / 2;
2439
2440 NodePtr node2 = sortImp(&node1, half, comparator);
2441 NodePtr next = sortImp(&node2, size - half, comparator);
2442
2443 *nodePtrPtr = mergeImp(node1, node2, next, comparator);
2444 return next;
2445}
2446
2447// PRIVATE ACCESSORS
2448template <class VALUE, class ALLOCATOR>
2449inline
2450const typename list<VALUE, ALLOCATOR>::NodeAlloc&
2451 list<VALUE, ALLOCATOR>::allocatorImp() const
2452{
2453 return d_alloc_and_size; // implicit cast to base class
2454}
2455
2456template <class VALUE, class ALLOCATOR>
2457inline
2458typename list<VALUE, ALLOCATOR>::NodePtr list<VALUE, ALLOCATOR>::headNode()
2459 const
2460{
2461 return d_sentinel->d_next_p;
2462}
2463
2464template <class VALUE, class ALLOCATOR>
2465inline
2466const typename list<VALUE, ALLOCATOR>::AllocTraits::size_type&
2467list<VALUE, ALLOCATOR>::sizeRef() const BSLS_KEYWORD_NOEXCEPT
2468{
2469 return d_alloc_and_size.size();
2470}
2471
2472// CREATORS
2473template <class VALUE, class ALLOCATOR>
2474list<VALUE, ALLOCATOR>::list()
2475: d_sentinel()
2476, d_alloc_and_size(ALLOCATOR(), 0)
2477{
2478 BSLMF_ASSERT((bsl::is_same<size_type,
2479 typename AllocTraits::size_type>::value));
2480 BSLMF_ASSERT((bsl::is_same<difference_type,
2481 typename AllocTraits::difference_type>::value));
2482 createSentinel();
2483}
2484
2485template <class VALUE, class ALLOCATOR>
2486list<VALUE, ALLOCATOR>::list(const ALLOCATOR& basicAllocator)
2487: d_sentinel()
2488, d_alloc_and_size(basicAllocator, 0)
2489{
2490 createSentinel();
2491}
2492
2493template <class VALUE, class ALLOCATOR>
2494list<VALUE, ALLOCATOR>::list(size_type numElements)
2495: d_sentinel()
2496, d_alloc_and_size(ALLOCATOR(), size_type(-1))
2497{
2498 // '*this' is in an invalid but destructible state (size == -1).
2499
2500 list tmp(this->allocatorImp());
2501
2502 // Default-construct (value-initialize) 'n' elements into 'tmp'. 'tmp's
2503 // destructor will clean up if an exception is thrown.
2504
2505 iterator pos = tmp.end();
2506 for (size_type i = 0; i < numElements; ++i) {
2507 tmp.emplace(pos);
2508 }
2509
2510 quickSwap(&tmp); // Leave 'tmp' in an invalid but destructible state.
2511}
2512
2513template <class VALUE, class ALLOCATOR>
2514list<VALUE, ALLOCATOR>::list(size_type numElements,
2515 const ALLOCATOR& basicAllocator)
2516: d_sentinel()
2517, d_alloc_and_size(basicAllocator, size_type(-1))
2518{
2519 // '*this' is in an invalid but destructible state (size == -1).
2520
2521 list tmp(this->allocatorImp());
2522
2523 // Default-construct (value-initialize) 'n' elements into 'tmp'. 'tmp's
2524 // destructor will clean up if an exception is thrown.
2525
2526 const_iterator pos = tmp.cend();
2527 for (size_type i = 0; i < numElements; ++i) {
2528 tmp.emplace(pos);
2529 }
2530
2531 quickSwap(&tmp); // Leave 'tmp' in an invalid but destructible state.
2532}
2533
2534template <class VALUE, class ALLOCATOR>
2535list<VALUE, ALLOCATOR>::list(size_type numElements,
2536 const VALUE& value,
2537 const ALLOCATOR& basicAllocator)
2538: d_sentinel()
2539, d_alloc_and_size(basicAllocator, size_type(-1))
2540{
2541 // '*this' is in an invalid but destructible state (size == -1).
2542
2543 list tmp(this->allocatorImp());
2544 tmp.insert(tmp.cbegin(), numElements, value); // 'tmp's destructor will
2545 // clean up on throw.
2546 quickSwap(&tmp); // Leave 'tmp' in an invalid but destructible state.
2547}
2548
2549template <class VALUE, class ALLOCATOR>
2550template <class t_RANGE>
2552list<VALUE, ALLOCATOR>::list(
2553 from_range_t ,
2554 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
2555 const ALLOCATOR& basicAllocator)
2556: d_sentinel()
2557, d_alloc_and_size(basicAllocator, size_type(-1))
2558{
2559 list tmp(this->allocatorImp());
2560 tmp.append_range(BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range));
2561 quickSwap(&tmp);
2562}
2563
2564template <class VALUE, class ALLOCATOR>
2565list<VALUE, ALLOCATOR>::list(const list& original)
2566: d_sentinel()
2567, d_alloc_and_size(
2568 AllocTraits::select_on_container_copy_construction(original.allocatorImp()),
2569 size_type(-1))
2570{
2571 list tmp(this->allocatorImp());
2572
2573 tmp.insert(tmp.cbegin(), original.begin(), original.end());
2574
2575 quickSwap(&tmp); // Leave 'tmp' in an invalid but destructible state.
2576}
2577
2578template <class VALUE, class ALLOCATOR>
2579list<VALUE, ALLOCATOR>::list(const list& original,
2580 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2581: d_sentinel()
2582, d_alloc_and_size(basicAllocator, size_type(-1))
2583{
2584 list tmp(this->allocatorImp());
2585
2586 tmp.insert(tmp.cbegin(), original.begin(), original.end());
2587
2588 quickSwap(&tmp); // Leave 'tmp' in an invalid but destructible state.
2589}
2590
2591template <class VALUE, class ALLOCATOR>
2592list<VALUE, ALLOCATOR>::list(BloombergLP::bslmf::MovableRef<list> original)
2593: d_sentinel()
2594, d_alloc_and_size(MoveUtil::access(original).allocatorImp(), 0)
2595{
2596 // Allocator should be copied, not moved, to ensure identical allocators
2597 // between this and 'original', otherwise 'swap' is undefined.
2598
2599 // An rvalue must be left in a valid state after a move.
2600
2601 createSentinel();
2602
2603 // '*this' is now in a valid state.
2604
2605 quickSwap(&MoveUtil::access(original));
2606}
2607
2608template <class VALUE, class ALLOCATOR>
2609list<VALUE, ALLOCATOR>::list(
2610 BloombergLP::bslmf::MovableRef<list> original,
2611 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2612: d_sentinel()
2613, d_alloc_and_size(basicAllocator, size_type(-1))
2614{
2615 // '*this' is in an invalid but destructible state (size == -1).
2616
2617 list& lvalue = original;
2618 if (this->allocatorImp() == lvalue.allocatorImp()) {
2619 // An rvalue must be left in a valid state after a move.
2620
2621 createSentinel(); // '*this' is now in a valid state.
2622 quickSwap(&lvalue);
2623 }
2624 else {
2625 // different allocators, must copy
2626
2627 list tmp(this->allocatorImp());
2628
2629 // Avoid relying on VALUE's copy c'tor unless no move c'tor is
2630 // available.
2631
2632 NodePtr endPtr = lvalue.d_sentinel;
2633 for (NodePtr p = lvalue.headNode(); endPtr != p; p = p->d_next_p) {
2634 tmp.emplace_back(MoveUtil::move(p->d_value));
2635 }
2636
2637 // Leave 'tmp' with all elements in a moved-from (but destructible)
2638 // state.
2639 quickSwap(&tmp);
2640 }
2641}
2642
2643#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2644template <class VALUE, class ALLOCATOR>
2645inline
2646list<VALUE, ALLOCATOR>::list(std::initializer_list<VALUE> values,
2647 const ALLOCATOR& basicAllocator)
2648: d_alloc_and_size(basicAllocator, size_type(-1))
2649{
2650 // '*this' is in an invalid but destructible state (size == -1). Create a
2651 // temporary list, 'tmp', with the specified data. If an exception is
2652 // thrown, 'tmp's destructor will clean up. Otherwise, swap 'tmp' with
2653 // '*this', leaving 'tmp' in an invalid but destructible state and leaving
2654 // '*this' fully constructed.
2655
2656 list tmp(this->allocatorImp());
2657 tmp.insert(tmp.cbegin(), values.begin(), values.end());
2658
2659 quickSwap(&tmp);
2660}
2661#endif
2662
2663template <class VALUE, class ALLOCATOR>
2664list<VALUE, ALLOCATOR>::~list()
2665{
2666 // A size of -1 means a special incompletely-initialized state with no
2667 // sentinel, which requires no destruction.
2668
2669 if (sizeRef() != size_type(-1)) {
2670 destroyAll();
2671 }
2672}
2673
2674// MANIPULATORS
2675
2676 // *** assignment ***
2677
2678template <class VALUE, class ALLOCATOR>
2679list<VALUE, ALLOCATOR>& list<VALUE, ALLOCATOR>::operator=(const list& rhs)
2680{
2681 typedef typename
2682 AllocTraits::propagate_on_container_copy_assignment Propagate;
2683
2684 if (this != &rhs) {
2685 if (Propagate::value && allocatorImp() != rhs.allocatorImp()) {
2686 // Fully destroy old list before assigning allocator, then reset to
2687 // the empty list state.
2688 destroyAll();
2689 BloombergLP::bslma::AllocatorUtil::assign(&allocatorImp(),
2690 rhs.allocatorImp(),
2691 Propagate());
2692 createSentinel();
2693 }
2694 assign(rhs.begin(), rhs.end()); // Copy elements
2695 }
2696
2697 return *this;
2698}
2699
2700template <class VALUE, class ALLOCATOR>
2701list<VALUE, ALLOCATOR>& list<VALUE, ALLOCATOR>::operator=(
2702 BloombergLP::bslmf::MovableRef<list> rhs)
2703 BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocTraits::is_always_equal::value)
2704{
2705 typedef typename
2706 AllocTraits::propagate_on_container_move_assignment Propagate;
2707
2708 list& lvalue = rhs;
2709
2710 if (this == &lvalue) {
2711 return *this; // RETURN
2712 }
2713
2714 if (this->allocatorImp() == lvalue.allocatorImp()) {
2715 // Equal allocators, just swap contents, will never throw.
2716
2717 quickSwap(&lvalue);
2718 }
2719 else if (Propagate::value) {
2720 // An rvalue must be left in a valid state after a move. Both '*this'
2721 // and 'rhs' must be left in valid states after a throw.
2722
2723 // Note: tearing everything down, then changing the allocator, then
2724 // doing 'quickSwap(&lvalue)' has a problem in that it could leave
2725 // 'rhs' in an invalid state, since if 'this->createSentinel()' were
2726 // called after the tearing down to render '*this' to a valid value,
2727 // 'createSentinel' might throw, leaving '*this' in an invalid state.
2728
2729 // Swap everything, including the allocator (here we are relying on the
2730 // C++11 standard, which requires that the allocator type not throw on
2731 // copy or assign).
2732
2733 list other(MoveUtil::move(lvalue));
2734
2735 using std::swap;
2736 using BloombergLP::bslma::AllocatorUtil;
2737
2738 AllocatorUtil::swap( // won't throw
2739 &allocatorImp(), &other.allocatorImp(), Propagate());
2740 swap(d_sentinel, other.d_sentinel); // swap of pointer type
2741 swap(sizeRef(), other.sizeRef()); // swap of fundamental type
2742 }
2743 else {
2744 // Unequal allocators and the allocator of the destination is to remain
2745 // unchanged. Copy using 'move', which will use copy functions where
2746 // 'value_type' doesn't support moving. Note that if this throws part
2747 // way through, both '*this' and 'rhs' may be left changed.
2748
2749 NodePtr dstPtr = this->headNode();
2750 const const_iterator dstEnd = this->cend();
2751 const NodePtr dstEndPtr = dstEnd.d_node_p;
2752
2753 NodePtr srcPtr = lvalue.headNode();
2754 const NodePtr srcEndPtr = lvalue.d_sentinel;
2755
2756 for (; srcEndPtr != srcPtr && dstEndPtr != dstPtr;
2757 srcPtr = srcPtr->d_next_p, dstPtr = dstPtr->d_next_p) {
2758 dstPtr->d_value = MoveUtil::move(srcPtr->d_value);
2759 }
2760
2761 erase(const_iterator(dstPtr), dstEnd);
2762
2763 for (; srcEndPtr != srcPtr; srcPtr = srcPtr->d_next_p) {
2764 emplace(dstEnd, MoveUtil::move(srcPtr->d_value));
2765 }
2766 }
2767
2768 return *this;
2769}
2770
2771#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2772template <class VALUE, class ALLOCATOR>
2773inline
2774list<VALUE, ALLOCATOR>& list<VALUE, ALLOCATOR>::operator=(
2775 std::initializer_list<VALUE> rhs)
2776{
2777 assign(rhs.begin(), rhs.end());
2778 return *this;
2779}
2780#endif
2781
2782template <class VALUE, class ALLOCATOR>
2783void list<VALUE, ALLOCATOR>::assign(size_type numElements, const VALUE& value)
2784{
2785 NodePtr dst_p = this->headNode();
2786 const const_iterator dstEnd = this->cend();
2787 const NodePtr dstEnd_p = dstEnd.d_node_p;
2788
2789 for (; 0 < numElements && dstEnd_p != dst_p;
2790 --numElements, dst_p = dst_p->d_next_p) {
2791 dst_p->d_value = value;
2792 }
2793
2794 erase(const_iterator(dst_p), dstEnd);
2795
2796 for (; 0 < numElements; --numElements) {
2797 insert(dstEnd, value);
2798 }
2799}
2800
2801#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2802template <class VALUE, class ALLOCATOR>
2803inline
2804void list<VALUE, ALLOCATOR>::assign(std::initializer_list<VALUE> values)
2805{
2806 assign(values.begin(), values.end());
2807}
2808#endif
2809
2810template <class VALUE, class ALLOCATOR>
2811template <class t_RANGE>
2813void list<VALUE, ALLOCATOR>::assign_range(
2814 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
2815{
2816 clear();
2817 append_range(BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range));
2818}
2819
2820 // *** iterators ***
2821
2822template <class VALUE, class ALLOCATOR>
2823inline
2824typename list<VALUE, ALLOCATOR>::iterator list<VALUE, ALLOCATOR>::begin()
2826{
2827 return iterator(headNode());
2828}
2829
2830template <class VALUE, class ALLOCATOR>
2831inline
2832typename list<VALUE, ALLOCATOR>::iterator list<VALUE, ALLOCATOR>::end()
2834{
2835 return iterator(d_sentinel);
2836}
2837
2838template <class VALUE, class ALLOCATOR>
2839inline
2840typename list<VALUE, ALLOCATOR>::reverse_iterator
2841list<VALUE, ALLOCATOR>::rbegin() BSLS_KEYWORD_NOEXCEPT
2842{
2843 return reverse_iterator(end());
2844}
2845
2846template <class VALUE, class ALLOCATOR>
2847inline
2848typename list<VALUE, ALLOCATOR>::reverse_iterator
2849list<VALUE, ALLOCATOR>::rend() BSLS_KEYWORD_NOEXCEPT
2850{
2851 return reverse_iterator(begin());
2852}
2853
2854 // *** modify size ***
2855
2856template <class VALUE, class ALLOCATOR>
2857inline
2858void list<VALUE, ALLOCATOR>::clear() BSLS_KEYWORD_NOEXCEPT
2859{
2860 const NodePtr e = d_sentinel;
2861 for (NodePtr p = d_sentinel->d_next_p; e != p; ) {
2862 NodePtr condemned = p;
2863 p = p->d_next_p;
2864 deleteNode(condemned);
2865 }
2866
2867 linkNodes(d_sentinel, d_sentinel);
2868 sizeRef() = 0;
2869}
2870
2871template <class VALUE, class ALLOCATOR>
2872void list<VALUE, ALLOCATOR>::resize(size_type newSize)
2873{
2874 if (newSize > sizeRef()) {
2875 const_iterator ce = cend();
2876 do {
2877 emplace(ce);
2878 } while (newSize > sizeRef());
2879 }
2880 else {
2881 NodePtr e = d_sentinel;
2882 NodePtr p = e->d_prev_p;
2883 for (size_type d = sizeRef() - newSize; d > 0; --d) {
2884 NodePtr condemned = p;
2885 p = p->d_prev_p;
2886 deleteNode(condemned);
2887 }
2888 linkNodes(p, e);
2889 sizeRef() = newSize;
2890 }
2891}
2892
2893template <class VALUE, class ALLOCATOR>
2894void list<VALUE, ALLOCATOR>::resize(size_type newSize, const VALUE& value)
2895{
2896 if (newSize > sizeRef()) {
2897 const_iterator ce = cend();
2898 do {
2899 emplace(ce, value);
2900 } while (newSize > sizeRef());
2901 }
2902 else {
2903 NodePtr e = d_sentinel;
2904 NodePtr p = e->d_prev_p;
2905 for (size_type d = sizeRef() - newSize; d > 0; --d) {
2906 NodePtr condemned = p;
2907 p = p->d_prev_p;
2908 deleteNode(condemned);
2909 }
2910 linkNodes(p, e);
2911 sizeRef() = newSize;
2912 }
2913}
2914
2915 // element access:
2916
2917template <class VALUE, class ALLOCATOR>
2918inline
2919typename list<VALUE, ALLOCATOR>::reference
2920list<VALUE, ALLOCATOR>::back()
2921{
2922 BSLS_ASSERT_SAFE(sizeRef() > 0);
2923
2924 return d_sentinel->d_prev_p->d_value;
2925}
2926
2927template <class VALUE, class ALLOCATOR>
2928inline
2929typename list<VALUE, ALLOCATOR>::reference
2930list<VALUE, ALLOCATOR>::front()
2931{
2932 BSLS_ASSERT_SAFE(sizeRef() > 0);
2933
2934 return headNode()->d_value;
2935}
2936
2937 // *** end erase ***
2938
2939template <class VALUE, class ALLOCATOR>
2940inline
2941void list<VALUE, ALLOCATOR>::pop_back()
2942{
2943 BSLS_ASSERT_SAFE(sizeRef() > 0);
2944
2945 erase(--cend());
2946}
2947
2948template <class VALUE, class ALLOCATOR>
2949inline
2950void list<VALUE, ALLOCATOR>::pop_front()
2951{
2952 BSLS_ASSERT_SAFE(sizeRef() > 0);
2953
2954 erase(cbegin());
2955}
2956
2957 // *** random access erase ***
2958
2959template <class VALUE, class ALLOCATOR>
2960typename list<VALUE, ALLOCATOR>::iterator
2961list<VALUE, ALLOCATOR>::erase(const_iterator position)
2962{
2963 BSLS_ASSERT(position.d_node_p != d_sentinel);
2964
2965 NodePtr condemned = position.d_node_p;
2966 iterator ret(condemned->d_next_p);
2967
2968 linkNodes(condemned->d_prev_p, condemned->d_next_p);
2969 deleteNode(condemned);
2970 --sizeRef();
2971 return ret;
2972}
2973
2974template <class VALUE, class ALLOCATOR>
2975typename list<VALUE, ALLOCATOR>::iterator
2976list<VALUE, ALLOCATOR>::erase(const_iterator dstBegin, const_iterator dstEnd)
2977{
2978 NodePtr p = dstBegin.d_node_p;
2979 const NodePtr e = dstEnd. d_node_p;
2980
2981 linkNodes(p->d_prev_p, e);
2982
2983 size_type numDeleted = 0;
2984 for (; e != p; ++numDeleted) {
2985 NodePtr condemned = p;
2986 p = p->d_next_p;
2987 deleteNode(condemned);
2988 }
2989
2990 sizeRef() -= numDeleted;
2991
2992 return iterator(e);
2993}
2994
2995 // *** end inserts ***
2996
2997
2998template <class VALUE, class ALLOCATOR>
2999template <class t_RANGE>
3001void list<VALUE, ALLOCATOR>::append_range(
3002 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
3003{
3004 privateAppendRange(ranges::begin(range), ranges::end(range));
3005}
3006
3007#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
3008// {{{ BEGIN GENERATED CODE
3009// Command line: sim_cpp11_features.pl bslstl_list.h
3010#ifndef BSLSTL_LIST_VARIADIC_LIMIT
3011#define BSLSTL_LIST_VARIADIC_LIMIT 10
3012#endif
3013#ifndef BSLSTL_LIST_VARIADIC_LIMIT_D
3014#define BSLSTL_LIST_VARIADIC_LIMIT_D BSLSTL_LIST_VARIADIC_LIMIT
3015#endif
3016#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 0
3017template <class VALUE, class ALLOCATOR>
3018inline
3019typename list<VALUE, ALLOCATOR>::reference
3020list<VALUE, ALLOCATOR>::emplace_back(
3021 )
3022{
3023 emplace(cend());
3024 return back();
3025}
3026#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 0
3027
3028#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 1
3029template <class VALUE, class ALLOCATOR>
3030template <class ARGS_01>
3031inline
3032typename list<VALUE, ALLOCATOR>::reference
3033list<VALUE, ALLOCATOR>::emplace_back(
3034 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01)
3035{
3036 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01));
3037 return back();
3038}
3039#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 1
3040
3041#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 2
3042template <class VALUE, class ALLOCATOR>
3043template <class ARGS_01,
3044 class ARGS_02>
3045inline
3046typename list<VALUE, ALLOCATOR>::reference
3047list<VALUE, ALLOCATOR>::emplace_back(
3048 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3049 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02)
3050{
3051 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3052 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02));
3053 return back();
3054}
3055#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 2
3056
3057#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 3
3058template <class VALUE, class ALLOCATOR>
3059template <class ARGS_01,
3060 class ARGS_02,
3061 class ARGS_03>
3062inline
3063typename list<VALUE, ALLOCATOR>::reference
3064list<VALUE, ALLOCATOR>::emplace_back(
3065 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3066 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3067 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03)
3068{
3069 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3070 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3071 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03));
3072 return back();
3073}
3074#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 3
3075
3076#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 4
3077template <class VALUE, class ALLOCATOR>
3078template <class ARGS_01,
3079 class ARGS_02,
3080 class ARGS_03,
3081 class ARGS_04>
3082inline
3083typename list<VALUE, ALLOCATOR>::reference
3084list<VALUE, ALLOCATOR>::emplace_back(
3085 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3086 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3087 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3088 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04)
3089{
3090 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3091 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3092 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3093 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04));
3094 return back();
3095}
3096#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 4
3097
3098#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 5
3099template <class VALUE, class ALLOCATOR>
3100template <class ARGS_01,
3101 class ARGS_02,
3102 class ARGS_03,
3103 class ARGS_04,
3104 class ARGS_05>
3105inline
3106typename list<VALUE, ALLOCATOR>::reference
3107list<VALUE, ALLOCATOR>::emplace_back(
3108 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3109 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3110 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3111 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3112 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05)
3113{
3114 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3115 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3116 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3117 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3118 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05));
3119 return back();
3120}
3121#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 5
3122
3123#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 6
3124template <class VALUE, class ALLOCATOR>
3125template <class ARGS_01,
3126 class ARGS_02,
3127 class ARGS_03,
3128 class ARGS_04,
3129 class ARGS_05,
3130 class ARGS_06>
3131inline
3132typename list<VALUE, ALLOCATOR>::reference
3133list<VALUE, ALLOCATOR>::emplace_back(
3134 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3135 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3136 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3137 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3138 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3139 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06)
3140{
3141 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3142 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3143 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3144 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3145 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3146 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06));
3147 return back();
3148}
3149#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 6
3150
3151#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 7
3152template <class VALUE, class ALLOCATOR>
3153template <class ARGS_01,
3154 class ARGS_02,
3155 class ARGS_03,
3156 class ARGS_04,
3157 class ARGS_05,
3158 class ARGS_06,
3159 class ARGS_07>
3160inline
3161typename list<VALUE, ALLOCATOR>::reference
3162list<VALUE, ALLOCATOR>::emplace_back(
3163 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3164 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3165 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3166 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3167 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3168 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3169 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07)
3170{
3171 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3172 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3173 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3174 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3175 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3176 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3177 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07));
3178 return back();
3179}
3180#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 7
3181
3182#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 8
3183template <class VALUE, class ALLOCATOR>
3184template <class ARGS_01,
3185 class ARGS_02,
3186 class ARGS_03,
3187 class ARGS_04,
3188 class ARGS_05,
3189 class ARGS_06,
3190 class ARGS_07,
3191 class ARGS_08>
3192inline
3193typename list<VALUE, ALLOCATOR>::reference
3194list<VALUE, ALLOCATOR>::emplace_back(
3195 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3196 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3197 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3198 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3199 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3200 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3201 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
3202 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08)
3203{
3204 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3205 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3206 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3207 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3208 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3209 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3210 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
3211 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08));
3212 return back();
3213}
3214#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 8
3215
3216#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 9
3217template <class VALUE, class ALLOCATOR>
3218template <class ARGS_01,
3219 class ARGS_02,
3220 class ARGS_03,
3221 class ARGS_04,
3222 class ARGS_05,
3223 class ARGS_06,
3224 class ARGS_07,
3225 class ARGS_08,
3226 class ARGS_09>
3227inline
3228typename list<VALUE, ALLOCATOR>::reference
3229list<VALUE, ALLOCATOR>::emplace_back(
3230 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3231 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3232 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3233 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3234 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3235 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3236 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
3237 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
3238 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09)
3239{
3240 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3241 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3242 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3243 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3244 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3245 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3246 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
3247 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
3248 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09));
3249 return back();
3250}
3251#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 9
3252
3253#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 10
3254template <class VALUE, class ALLOCATOR>
3255template <class ARGS_01,
3256 class ARGS_02,
3257 class ARGS_03,
3258 class ARGS_04,
3259 class ARGS_05,
3260 class ARGS_06,
3261 class ARGS_07,
3262 class ARGS_08,
3263 class ARGS_09,
3264 class ARGS_10>
3265inline
3266typename list<VALUE, ALLOCATOR>::reference
3267list<VALUE, ALLOCATOR>::emplace_back(
3268 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3269 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3270 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3271 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3272 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3273 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3274 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
3275 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
3276 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
3277 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10)
3278{
3279 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3280 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3281 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3282 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3283 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3284 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3285 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
3286 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
3287 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09),
3288 BSLS_COMPILERFEATURES_FORWARD(ARGS_10, arguments_10));
3289 return back();
3290}
3291#endif // BSLSTL_LIST_VARIADIC_LIMIT_D >= 10
3292
3293#else
3294// The generated code below is a workaround for the absence of perfect
3295// forwarding in some compilers.
3296template <class VALUE, class ALLOCATOR>
3297template <class... ARGS>
3298inline
3299typename list<VALUE, ALLOCATOR>::reference
3300list<VALUE, ALLOCATOR>::emplace_back(
3301 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments)
3302{
3303 emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
3304 return back();
3305}
3306// }}} END GENERATED CODE
3307#endif
3308
3309#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
3310// {{{ BEGIN GENERATED CODE
3311// Command line: sim_cpp11_features.pl bslstl_list.h
3312#ifndef BSLSTL_LIST_VARIADIC_LIMIT
3313#define BSLSTL_LIST_VARIADIC_LIMIT 10
3314#endif
3315#ifndef BSLSTL_LIST_VARIADIC_LIMIT_E
3316#define BSLSTL_LIST_VARIADIC_LIMIT_E BSLSTL_LIST_VARIADIC_LIMIT
3317#endif
3318#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 0
3319template <class VALUE, class ALLOCATOR>
3320inline
3321typename list<VALUE, ALLOCATOR>::reference
3322list<VALUE, ALLOCATOR>::emplace_front(
3323 )
3324{
3325 emplace(cbegin());
3326 return front();
3327}
3328#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 0
3329
3330#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 1
3331template <class VALUE, class ALLOCATOR>
3332template <class ARGS_01>
3333inline
3334typename list<VALUE, ALLOCATOR>::reference
3335list<VALUE, ALLOCATOR>::emplace_front(
3336 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01)
3337{
3338 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01));
3339 return front();
3340}
3341#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 1
3342
3343#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 2
3344template <class VALUE, class ALLOCATOR>
3345template <class ARGS_01,
3346 class ARGS_02>
3347inline
3348typename list<VALUE, ALLOCATOR>::reference
3349list<VALUE, ALLOCATOR>::emplace_front(
3350 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3351 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02)
3352{
3353 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3354 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02));
3355 return front();
3356}
3357#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 2
3358
3359#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 3
3360template <class VALUE, class ALLOCATOR>
3361template <class ARGS_01,
3362 class ARGS_02,
3363 class ARGS_03>
3364inline
3365typename list<VALUE, ALLOCATOR>::reference
3366list<VALUE, ALLOCATOR>::emplace_front(
3367 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3368 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3369 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03)
3370{
3371 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3372 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3373 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03));
3374 return front();
3375}
3376#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 3
3377
3378#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 4
3379template <class VALUE, class ALLOCATOR>
3380template <class ARGS_01,
3381 class ARGS_02,
3382 class ARGS_03,
3383 class ARGS_04>
3384inline
3385typename list<VALUE, ALLOCATOR>::reference
3386list<VALUE, ALLOCATOR>::emplace_front(
3387 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3388 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3389 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3390 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04)
3391{
3392 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3393 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3394 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3395 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04));
3396 return front();
3397}
3398#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 4
3399
3400#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 5
3401template <class VALUE, class ALLOCATOR>
3402template <class ARGS_01,
3403 class ARGS_02,
3404 class ARGS_03,
3405 class ARGS_04,
3406 class ARGS_05>
3407inline
3408typename list<VALUE, ALLOCATOR>::reference
3409list<VALUE, ALLOCATOR>::emplace_front(
3410 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3411 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3412 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3413 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3414 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05)
3415{
3416 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3417 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3418 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3419 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3420 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05));
3421 return front();
3422}
3423#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 5
3424
3425#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 6
3426template <class VALUE, class ALLOCATOR>
3427template <class ARGS_01,
3428 class ARGS_02,
3429 class ARGS_03,
3430 class ARGS_04,
3431 class ARGS_05,
3432 class ARGS_06>
3433inline
3434typename list<VALUE, ALLOCATOR>::reference
3435list<VALUE, ALLOCATOR>::emplace_front(
3436 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3437 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3438 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3439 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3440 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3441 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06)
3442{
3443 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3444 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3445 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3446 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3447 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3448 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06));
3449 return front();
3450}
3451#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 6
3452
3453#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 7
3454template <class VALUE, class ALLOCATOR>
3455template <class ARGS_01,
3456 class ARGS_02,
3457 class ARGS_03,
3458 class ARGS_04,
3459 class ARGS_05,
3460 class ARGS_06,
3461 class ARGS_07>
3462inline
3463typename list<VALUE, ALLOCATOR>::reference
3464list<VALUE, ALLOCATOR>::emplace_front(
3465 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3466 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3467 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3468 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3469 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3470 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3471 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07)
3472{
3473 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3474 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3475 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3476 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3477 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3478 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3479 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07));
3480 return front();
3481}
3482#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 7
3483
3484#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 8
3485template <class VALUE, class ALLOCATOR>
3486template <class ARGS_01,
3487 class ARGS_02,
3488 class ARGS_03,
3489 class ARGS_04,
3490 class ARGS_05,
3491 class ARGS_06,
3492 class ARGS_07,
3493 class ARGS_08>
3494inline
3495typename list<VALUE, ALLOCATOR>::reference
3496list<VALUE, ALLOCATOR>::emplace_front(
3497 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3498 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3499 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3500 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3501 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3502 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3503 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
3504 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08)
3505{
3506 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3507 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3508 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3509 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3510 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3511 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3512 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
3513 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08));
3514 return front();
3515}
3516#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 8
3517
3518#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 9
3519template <class VALUE, class ALLOCATOR>
3520template <class ARGS_01,
3521 class ARGS_02,
3522 class ARGS_03,
3523 class ARGS_04,
3524 class ARGS_05,
3525 class ARGS_06,
3526 class ARGS_07,
3527 class ARGS_08,
3528 class ARGS_09>
3529inline
3530typename list<VALUE, ALLOCATOR>::reference
3531list<VALUE, ALLOCATOR>::emplace_front(
3532 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3533 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3534 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3535 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3536 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3537 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3538 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
3539 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
3540 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09)
3541{
3542 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3543 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3544 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3545 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3546 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3547 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3548 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
3549 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
3550 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09));
3551 return front();
3552}
3553#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 9
3554
3555#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 10
3556template <class VALUE, class ALLOCATOR>
3557template <class ARGS_01,
3558 class ARGS_02,
3559 class ARGS_03,
3560 class ARGS_04,
3561 class ARGS_05,
3562 class ARGS_06,
3563 class ARGS_07,
3564 class ARGS_08,
3565 class ARGS_09,
3566 class ARGS_10>
3567inline
3568typename list<VALUE, ALLOCATOR>::reference
3569list<VALUE, ALLOCATOR>::emplace_front(
3570 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3571 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3572 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3573 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3574 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3575 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3576 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
3577 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
3578 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
3579 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10)
3580{
3581 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3582 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3583 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3584 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3585 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3586 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3587 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
3588 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
3589 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09),
3590 BSLS_COMPILERFEATURES_FORWARD(ARGS_10, arguments_10));
3591 return front();
3592}
3593#endif // BSLSTL_LIST_VARIADIC_LIMIT_E >= 10
3594
3595#else
3596// The generated code below is a workaround for the absence of perfect
3597// forwarding in some compilers.
3598template <class VALUE, class ALLOCATOR>
3599template <class... ARGS>
3600inline
3601typename list<VALUE, ALLOCATOR>::reference
3602list<VALUE, ALLOCATOR>::emplace_front(
3603 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments)
3604{
3605 emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
3606 return front();
3607}
3608// }}} END GENERATED CODE
3609#endif
3610
3611template <class VALUE, class ALLOCATOR>
3612template <class t_RANGE>
3614void list<VALUE, ALLOCATOR>::prepend_range(
3615 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
3616{
3617 insert_range(begin(), BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range));
3618}
3619
3620template <class VALUE, class ALLOCATOR>
3621inline
3622void list<VALUE, ALLOCATOR>::push_back(const VALUE& value)
3623{
3624 emplace(cend(), value);
3625}
3626
3627template <class VALUE, class ALLOCATOR>
3628inline
3629void list<VALUE, ALLOCATOR>::push_back(
3630 BloombergLP::bslmf::MovableRef<VALUE> value)
3631{
3632 emplace(cend(), MoveUtil::move(value));
3633}
3634
3635template <class VALUE, class ALLOCATOR>
3636inline
3637void list<VALUE, ALLOCATOR>::push_front(const VALUE& value)
3638{
3639 emplace(cbegin(), value);
3640}
3641
3642template <class VALUE, class ALLOCATOR>
3643inline
3644void list<VALUE, ALLOCATOR>::push_front(
3645 BloombergLP::bslmf::MovableRef<VALUE> value)
3646{
3647 emplace(cbegin(), MoveUtil::move(value));
3648}
3649
3650 // *** random access inserts ***
3651
3652#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
3653// {{{ BEGIN GENERATED CODE
3654// Command line: sim_cpp11_features.pl bslstl_list.h
3655#ifndef BSLSTL_LIST_VARIADIC_LIMIT
3656#define BSLSTL_LIST_VARIADIC_LIMIT 10
3657#endif
3658#ifndef BSLSTL_LIST_VARIADIC_LIMIT_F
3659#define BSLSTL_LIST_VARIADIC_LIMIT_F BSLSTL_LIST_VARIADIC_LIMIT
3660#endif
3661#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 0
3662template <class VALUE, class ALLOCATOR>
3663typename list<VALUE, ALLOCATOR>::iterator
3664list<VALUE, ALLOCATOR>::emplace(const_iterator position)
3665{
3666 NodePtr p = allocateNode();
3667 NodeProctor proctor(this, p);
3668 AllocTraits::construct(allocatorImp(),
3669 BloombergLP::bsls::Util::addressOf(p->d_value));
3670 proctor.release();
3671 return insertNode(position, p);
3672}
3673#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 0
3674
3675#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 1
3676template <class VALUE, class ALLOCATOR>
3677template <class ARGS_01>
3678typename list<VALUE, ALLOCATOR>::iterator
3679list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3680 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01)
3681{
3682 NodePtr p = allocateNode();
3683 NodeProctor proctor(this, p);
3684 AllocTraits::construct(allocatorImp(),
3685 BloombergLP::bsls::Util::addressOf(p->d_value),
3686 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01));
3687 proctor.release();
3688 return insertNode(position, p);
3689}
3690#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 1
3691
3692#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 2
3693template <class VALUE, class ALLOCATOR>
3694template <class ARGS_01,
3695 class ARGS_02>
3696typename list<VALUE, ALLOCATOR>::iterator
3697list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3698 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3699 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02)
3700{
3701 NodePtr p = allocateNode();
3702 NodeProctor proctor(this, p);
3703 AllocTraits::construct(allocatorImp(),
3704 BloombergLP::bsls::Util::addressOf(p->d_value),
3705 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3706 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02));
3707 proctor.release();
3708 return insertNode(position, p);
3709}
3710#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 2
3711
3712#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 3
3713template <class VALUE, class ALLOCATOR>
3714template <class ARGS_01,
3715 class ARGS_02,
3716 class ARGS_03>
3717typename list<VALUE, ALLOCATOR>::iterator
3718list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3719 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3720 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3721 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03)
3722{
3723 NodePtr p = allocateNode();
3724 NodeProctor proctor(this, p);
3725 AllocTraits::construct(allocatorImp(),
3726 BloombergLP::bsls::Util::addressOf(p->d_value),
3727 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3728 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3729 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03));
3730 proctor.release();
3731 return insertNode(position, p);
3732}
3733#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 3
3734
3735#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 4
3736template <class VALUE, class ALLOCATOR>
3737template <class ARGS_01,
3738 class ARGS_02,
3739 class ARGS_03,
3740 class ARGS_04>
3741typename list<VALUE, ALLOCATOR>::iterator
3742list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3743 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3744 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3745 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3746 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04)
3747{
3748 NodePtr p = allocateNode();
3749 NodeProctor proctor(this, p);
3750 AllocTraits::construct(allocatorImp(),
3751 BloombergLP::bsls::Util::addressOf(p->d_value),
3752 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3753 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3754 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3755 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04));
3756 proctor.release();
3757 return insertNode(position, p);
3758}
3759#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 4
3760
3761#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 5
3762template <class VALUE, class ALLOCATOR>
3763template <class ARGS_01,
3764 class ARGS_02,
3765 class ARGS_03,
3766 class ARGS_04,
3767 class ARGS_05>
3768typename list<VALUE, ALLOCATOR>::iterator
3769list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3770 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3771 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3772 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3773 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3774 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05)
3775{
3776 NodePtr p = allocateNode();
3777 NodeProctor proctor(this, p);
3778 AllocTraits::construct(allocatorImp(),
3779 BloombergLP::bsls::Util::addressOf(p->d_value),
3780 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3781 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3782 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3783 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3784 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05));
3785 proctor.release();
3786 return insertNode(position, p);
3787}
3788#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 5
3789
3790#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 6
3791template <class VALUE, class ALLOCATOR>
3792template <class ARGS_01,
3793 class ARGS_02,
3794 class ARGS_03,
3795 class ARGS_04,
3796 class ARGS_05,
3797 class ARGS_06>
3798typename list<VALUE, ALLOCATOR>::iterator
3799list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3800 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3801 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3802 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3803 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3804 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3805 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06)
3806{
3807 NodePtr p = allocateNode();
3808 NodeProctor proctor(this, p);
3809 AllocTraits::construct(allocatorImp(),
3810 BloombergLP::bsls::Util::addressOf(p->d_value),
3811 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3812 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3813 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3814 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3815 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3816 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06));
3817 proctor.release();
3818 return insertNode(position, p);
3819}
3820#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 6
3821
3822#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 7
3823template <class VALUE, class ALLOCATOR>
3824template <class ARGS_01,
3825 class ARGS_02,
3826 class ARGS_03,
3827 class ARGS_04,
3828 class ARGS_05,
3829 class ARGS_06,
3830 class ARGS_07>
3831typename list<VALUE, ALLOCATOR>::iterator
3832list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3833 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3834 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3835 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3836 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3837 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3838 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3839 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07)
3840{
3841 NodePtr p = allocateNode();
3842 NodeProctor proctor(this, p);
3843 AllocTraits::construct(allocatorImp(),
3844 BloombergLP::bsls::Util::addressOf(p->d_value),
3845 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3846 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3847 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3848 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3849 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3850 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3851 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07));
3852 proctor.release();
3853 return insertNode(position, p);
3854}
3855#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 7
3856
3857#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 8
3858template <class VALUE, class ALLOCATOR>
3859template <class ARGS_01,
3860 class ARGS_02,
3861 class ARGS_03,
3862 class ARGS_04,
3863 class ARGS_05,
3864 class ARGS_06,
3865 class ARGS_07,
3866 class ARGS_08>
3867typename list<VALUE, ALLOCATOR>::iterator
3868list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3869 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3870 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3871 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3872 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3873 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3874 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3875 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
3876 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08)
3877{
3878 NodePtr p = allocateNode();
3879 NodeProctor proctor(this, p);
3880 AllocTraits::construct(allocatorImp(),
3881 BloombergLP::bsls::Util::addressOf(p->d_value),
3882 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3883 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3884 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3885 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3886 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3887 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3888 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
3889 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08));
3890 proctor.release();
3891 return insertNode(position, p);
3892}
3893#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 8
3894
3895#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 9
3896template <class VALUE, class ALLOCATOR>
3897template <class ARGS_01,
3898 class ARGS_02,
3899 class ARGS_03,
3900 class ARGS_04,
3901 class ARGS_05,
3902 class ARGS_06,
3903 class ARGS_07,
3904 class ARGS_08,
3905 class ARGS_09>
3906typename list<VALUE, ALLOCATOR>::iterator
3907list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3908 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3909 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3910 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3911 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3912 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3913 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3914 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
3915 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
3916 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09)
3917{
3918 NodePtr p = allocateNode();
3919 NodeProctor proctor(this, p);
3920 AllocTraits::construct(allocatorImp(),
3921 BloombergLP::bsls::Util::addressOf(p->d_value),
3922 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3923 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3924 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3925 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3926 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3927 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3928 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
3929 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
3930 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09));
3931 proctor.release();
3932 return insertNode(position, p);
3933}
3934#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 9
3935
3936#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 10
3937template <class VALUE, class ALLOCATOR>
3938template <class ARGS_01,
3939 class ARGS_02,
3940 class ARGS_03,
3941 class ARGS_04,
3942 class ARGS_05,
3943 class ARGS_06,
3944 class ARGS_07,
3945 class ARGS_08,
3946 class ARGS_09,
3947 class ARGS_10>
3948typename list<VALUE, ALLOCATOR>::iterator
3949list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3950 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
3951 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
3952 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
3953 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
3954 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
3955 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
3956 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
3957 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
3958 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
3959 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10)
3960{
3961 NodePtr p = allocateNode();
3962 NodeProctor proctor(this, p);
3963 AllocTraits::construct(allocatorImp(),
3964 BloombergLP::bsls::Util::addressOf(p->d_value),
3965 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
3966 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
3967 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
3968 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
3969 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
3970 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
3971 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
3972 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
3973 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09),
3974 BSLS_COMPILERFEATURES_FORWARD(ARGS_10, arguments_10));
3975 proctor.release();
3976 return insertNode(position, p);
3977}
3978#endif // BSLSTL_LIST_VARIADIC_LIMIT_F >= 10
3979
3980#else
3981// The generated code below is a workaround for the absence of perfect
3982// forwarding in some compilers.
3983template <class VALUE, class ALLOCATOR>
3984template <class... ARGS>
3985typename list<VALUE, ALLOCATOR>::iterator
3986list<VALUE, ALLOCATOR>::emplace(const_iterator position,
3987 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments)
3988{
3989 NodePtr p = allocateNode();
3990 NodeProctor proctor(this, p);
3991 AllocTraits::construct(allocatorImp(),
3992 BloombergLP::bsls::Util::addressOf(p->d_value),
3993 BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
3994 proctor.release();
3995 return insertNode(position, p);
3996}
3997// }}} END GENERATED CODE
3998#endif
3999
4000template <class VALUE, class ALLOCATOR>
4001typename list<VALUE, ALLOCATOR>::iterator
4002list<VALUE, ALLOCATOR>::insert(const_iterator dstPosition, const VALUE& value)
4003{
4004 return emplace(dstPosition, value);
4005}
4006
4007template <class VALUE, class ALLOCATOR>
4008typename list<VALUE, ALLOCATOR>::iterator
4009list<VALUE, ALLOCATOR>::insert(
4010 const_iterator dstPosition,
4011 BloombergLP::bslmf::MovableRef<VALUE> value)
4012{
4013 return emplace(dstPosition, MoveUtil::move(value));
4014}
4015
4016template <class VALUE, class ALLOCATOR>
4017typename list<VALUE, ALLOCATOR>::iterator
4018list<VALUE, ALLOCATOR>::insert(const_iterator dstPosition,
4019 size_type numElements,
4020 const VALUE& value)
4021{
4022 if (0 == numElements) {
4023 return dstPosition.unconst(); // RETURN
4024 }
4025
4026 // Remember the position of the first node inserted before 'dstPosition'.
4027
4028 iterator ret = emplace(dstPosition, value);
4029
4030 // And put the rest of the nodes after it.
4031
4032 for (--numElements; numElements > 0; --numElements) {
4033 emplace(dstPosition, value);
4034 }
4035
4036 return ret;
4037}
4038
4039#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4040template <class VALUE, class ALLOCATOR>
4041typename list<VALUE, ALLOCATOR>::iterator
4042list<VALUE, ALLOCATOR>::insert(const_iterator dstPosition,
4043 std::initializer_list<VALUE> values)
4044{
4045 return insert(dstPosition, values.begin(), values.end());
4046}
4047#endif
4048
4049template <class VALUE, class ALLOCATOR>
4050template <class t_RANGE>
4052typename list<VALUE, ALLOCATOR>::iterator
4053list<VALUE, ALLOCATOR>::insert_range(
4054 const_iterator position,
4055 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
4056{
4057 list tmp(from_range,
4058 BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range),
4059 get_allocator());
4060 iterator it = !tmp.empty() ? tmp.begin() : position.unconst();
4061 splice(position, tmp);
4062 return it;
4063}
4064
4065 // *** list operations ***
4066
4067template <class VALUE, class ALLOCATOR>
4068inline
4069void list<VALUE, ALLOCATOR>::merge(list& other)
4070{
4071 BSLS_ASSERT_SAFE(this->allocatorImp() == other.allocatorImp());
4072
4073 merge(other, DefaultLessThan());
4074}
4075
4076template <class VALUE, class ALLOCATOR>
4077inline
4078void list<VALUE, ALLOCATOR>::merge(BloombergLP::bslmf::MovableRef<list> other)
4079{
4080 list& lvalue = other;
4081
4082 BSLS_ASSERT_SAFE(this->allocatorImp() == lvalue.allocatorImp());
4083
4084 merge(lvalue, DefaultLessThan());
4085}
4086
4087template <class VALUE, class ALLOCATOR>
4088template <class COMPARE>
4089void list<VALUE, ALLOCATOR>::merge(list& other, COMPARE comparator)
4090{
4091 if (&other == this) {
4092 return; // RETURN
4093 }
4094
4095 BSLS_ASSERT(this->allocatorImp() == other.allocatorImp());
4096
4097 if (other.empty()) {
4098 // This is an important special case to avoid pointing to sentinel.
4099
4100 return; // RETURN
4101 }
4102
4103 // Splice 'other' to the end of '*this', but remember the first node of the
4104 // appended sequence.
4105
4106 NodePtr xfirst = other.d_sentinel->d_next_p;
4107 splice(end(), other);
4108
4109 // Call 'mergeImp' with a pointer to the first node of the original list, a
4110 // pointer to the first node of 'other' (which also ends the original
4111 // list), and a pointer to the sentinel (which now ends 'other').
4112
4113 mergeImp(d_sentinel->d_next_p, xfirst, d_sentinel, comparator);
4114}
4115
4116template <class VALUE, class ALLOCATOR>
4117template <class COMPARE>
4118inline
4119void list<VALUE, ALLOCATOR>::merge(
4120 BloombergLP::bslmf::MovableRef<list> other,
4121 COMPARE comparator)
4122{
4123 list& lvalue = other;
4124
4125 BSLS_ASSERT_SAFE(this->allocatorImp() == lvalue.allocatorImp());
4126
4127 merge(lvalue, comparator);
4128}
4129
4130template <class VALUE, class ALLOCATOR>
4131typename list<VALUE, ALLOCATOR>::size_type
4132list<VALUE, ALLOCATOR>::remove(const VALUE& value)
4133{
4134 const size_type origSize = this->size();
4135 const const_iterator e = cend();
4136 for (const_iterator i = cbegin(); e != i; ) {
4137 // Standard says to use 'operator==', not 'std::equal_to'.
4138
4139 if (value == *i) {
4140 i = erase(i);
4141 }
4142 else {
4143 ++i;
4144 }
4145 }
4146
4147 return origSize - this->size();
4148}
4149
4150template <class VALUE, class ALLOCATOR>
4151template <class PREDICATE>
4152typename list<VALUE, ALLOCATOR>::size_type
4153list<VALUE, ALLOCATOR>::remove_if(PREDICATE predicate)
4154{
4155 const size_type origSize = this->size();
4156 const iterator e = end();
4157 for (iterator i = begin(); e != i; ) {
4158 if (predicate(*i)) {
4159 i = erase(i);
4160 }
4161 else {
4162 ++i;
4163 }
4164 }
4165
4166 return origSize - this->size();
4167}
4168
4169template <class VALUE, class ALLOCATOR>
4170void list<VALUE, ALLOCATOR>::reverse() BSLS_KEYWORD_NOEXCEPT
4171{
4172 NodePtr sentinel = d_sentinel;
4173 NodePtr p = sentinel;
4174
4175 do {
4176 NodePtr tmp = p->d_next_p;
4177 p->d_next_p = p->d_prev_p;
4178 p->d_prev_p = tmp;
4179 p = tmp;
4180 } while (p != sentinel);
4181}
4182
4183template <class VALUE, class ALLOCATOR>
4184inline
4185void list<VALUE, ALLOCATOR>::sort()
4186{
4187 sort(DefaultLessThan());
4188}
4189
4190template <class VALUE, class ALLOCATOR>
4191template <class COMPARE>
4192void list<VALUE, ALLOCATOR>::sort(COMPARE comparator)
4193{
4194 if (sizeRef() < 2) {
4195 return; // RETURN
4196 }
4197 NodePtr node1 = d_sentinel->d_next_p;
4198 sortImp(&node1, size(), comparator);
4199}
4200
4201template <class VALUE, class ALLOCATOR>
4202void list<VALUE, ALLOCATOR>::splice(const_iterator dstPosition, list& src)
4203{
4204 BSLS_ASSERT(allocatorImp() == src.allocatorImp());
4205 BSLS_ASSERT(&src != this);
4206
4207 if (src.empty()) {
4208 return; // RETURN
4209 }
4210
4211 NodePtr pPos = dstPosition.d_node_p;
4212 NodePtr pFirst = src.headNode();
4213 NodePtr pLast = src.d_sentinel->d_prev_p;
4214 size_type n = src.sizeRef();
4215
4216 // Splice contents out of 'src'.
4217
4218 linkNodes(src.d_sentinel, src.d_sentinel);
4219 src.sizeRef() = 0;
4220
4221 // Splice contents into '*this'.
4222
4223 linkNodes(pPos->d_prev_p, pFirst);
4224 linkNodes(pLast, pPos);
4225 sizeRef() += n;
4226}
4227
4228template <class VALUE, class ALLOCATOR>
4229inline
4230void list<VALUE, ALLOCATOR>::splice(
4231 const_iterator dstPosition,
4232 BloombergLP::bslmf::MovableRef<list> src)
4233{
4234 splice(dstPosition, MoveUtil::access(src));
4235}
4236
4237template <class VALUE, class ALLOCATOR>
4238void list<VALUE, ALLOCATOR>::splice(const_iterator dstPosition,
4239 list& src,
4240 const_iterator srcNode)
4241{
4242 BSLS_ASSERT(allocatorImp() == src.allocatorImp());
4243
4244 NodePtr pPos = dstPosition.d_node_p;
4245 NodePtr pSrcNode = srcNode.d_node_p;
4246 NodePtr pAfterSrcNode = pSrcNode->d_next_p;
4247
4248 if (pPos == pSrcNode || pPos == pAfterSrcNode) {
4249 return; // RETURN
4250 }
4251
4252 // Splice contents out of 'src'.
4253
4254 linkNodes(pSrcNode->d_prev_p, pAfterSrcNode);
4255 --src.sizeRef();
4256
4257 // Splice contents into '*this'.
4258
4259 linkNodes(pPos->d_prev_p, pSrcNode);
4260 linkNodes(pSrcNode, pPos);
4261 ++sizeRef();
4262}
4263
4264template <class VALUE, class ALLOCATOR>
4265inline
4266void list<VALUE, ALLOCATOR>::splice(
4267 const_iterator dstPosition,
4268 BloombergLP::bslmf::MovableRef<list> src,
4269 const_iterator srcNode)
4270{
4271 splice(dstPosition, MoveUtil::access(src), srcNode);
4272}
4273
4274template <class VALUE, class ALLOCATOR>
4275void list<VALUE, ALLOCATOR>::splice(const_iterator dstPosition,
4276 list& src,
4277 const_iterator first,
4278 const_iterator last)
4279{
4280 BSLS_ASSERT(allocatorImp() == src.allocatorImp());
4281
4282 size_type n = bsl::distance(first, last);
4283
4284 if (0 == n) {
4285 return; // RETURN
4286 }
4287
4288 NodePtr pPos = dstPosition.d_node_p;
4289 NodePtr pFirst = first.d_node_p;
4290 NodePtr pLast = last.d_node_p;
4291 NodePtr pSrcLast = pLast->d_prev_p;
4292
4293 // Splice contents out of 'src'.
4294
4295 linkNodes(pFirst->d_prev_p, pLast);
4296 src.sizeRef() -= n;
4297
4298 // Splice contents into '*this'.
4299
4300 linkNodes(pPos->d_prev_p, pFirst);
4301 linkNodes(pSrcLast, pPos);
4302 sizeRef() += n;
4303}
4304
4305template <class VALUE, class ALLOCATOR>
4306inline
4307void list<VALUE, ALLOCATOR>::splice(
4308 const_iterator dstPosition,
4309 BloombergLP::bslmf::MovableRef<list> src,
4310 const_iterator first,
4311 const_iterator last)
4312{
4313 splice(dstPosition, MoveUtil::access(src), first, last);
4314}
4315
4316template <class VALUE, class ALLOCATOR>
4317void list<VALUE, ALLOCATOR>::unique()
4318{
4319 if (size() < 2) {
4320 return; // RETURN
4321 }
4322
4323 iterator i = begin();
4324 iterator e = end();
4325 while (i != e) {
4326 reference match = *i++;
4327 while (i != e && *i == match) {
4328 i = erase(i);
4329 }
4330 }
4331}
4332
4333template <class VALUE, class ALLOCATOR>
4334template <class EQ_PREDICATE>
4335void list<VALUE, ALLOCATOR>::unique(EQ_PREDICATE binaryPredicate)
4336{
4337 if (size() < 2) {
4338 return; // RETURN
4339 }
4340
4341 iterator i = begin();
4342 iterator e = end();
4343 while (i != e) {
4344 reference match = *i++;
4345 while (i != e && binaryPredicate(*i, match)) {
4346 i = erase(i);
4347 }
4348 }
4349}
4350
4351 // *** misc ***
4352
4353template <class VALUE, class ALLOCATOR>
4354void list<VALUE, ALLOCATOR>::swap(list& other)
4355 BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocTraits::is_always_equal::value)
4356{
4357 // C++11 behavior for member 'swap': undefined for unequal allocators.
4358 // BSLS_ASSERT(allocatorImp() == other.allocatorImp());
4359
4360 typedef typename AllocTraits::propagate_on_container_swap Propagate;
4361
4362 if (Propagate::value) {
4363 using std::swap;
4364 using BloombergLP::bslma::AllocatorUtil;
4365
4366 AllocatorUtil::swap( // Won't throw
4367 &allocatorImp(), &other.allocatorImp(), Propagate());
4368 swap(d_sentinel, other.d_sentinel);
4369 swap(sizeRef(), other.sizeRef());
4370 }
4372 allocatorImp() == other.allocatorImp())) {
4373 quickSwap(&other);
4374 }
4375 else {
4377
4378 // Create copies using the move constructor, then swap both containers
4379 // with them. Note that if no move constructor exists, but a copy
4380 // constructor does, the copy constructor will be used.
4381
4382 // Also note that if either of these copies throws, it could leave the
4383 // two containers in a changed state. They are, however, guaranteed to
4384 // be left in valid state.
4385
4386 list toOtherCopy(MoveUtil::move(*this), other.allocatorImp());
4387 list toThisCopy( MoveUtil::move(other), this->allocatorImp());
4388
4389 toOtherCopy.quickSwap(&other);
4390 toThisCopy .quickSwap(this);
4391 }
4392}
4393
4394// ACCESSORS
4395
4396 // *** iterators ***
4397
4398template <class VALUE, class ALLOCATOR>
4399inline
4400typename list<VALUE, ALLOCATOR>::const_iterator
4401list<VALUE, ALLOCATOR>::begin() const BSLS_KEYWORD_NOEXCEPT
4402{
4403 return const_iterator(headNode());
4404}
4405
4406template <class VALUE, class ALLOCATOR>
4407inline
4408typename list<VALUE, ALLOCATOR>::const_iterator
4409list<VALUE, ALLOCATOR>::end() const BSLS_KEYWORD_NOEXCEPT
4410{
4411 return const_iterator(d_sentinel);
4412}
4413
4414template <class VALUE, class ALLOCATOR>
4415inline
4416typename list<VALUE, ALLOCATOR>::const_iterator
4417list<VALUE, ALLOCATOR>::cbegin() const BSLS_KEYWORD_NOEXCEPT
4418{
4419 return begin();
4420}
4421
4422template <class VALUE, class ALLOCATOR>
4423inline
4424typename list<VALUE, ALLOCATOR>::const_iterator
4425list<VALUE, ALLOCATOR>::cend() const BSLS_KEYWORD_NOEXCEPT
4426{
4427 return end();
4428}
4429
4430template <class VALUE, class ALLOCATOR>
4431inline
4432typename list<VALUE, ALLOCATOR>::const_reverse_iterator
4433list<VALUE, ALLOCATOR>::crbegin() const BSLS_KEYWORD_NOEXCEPT
4434{
4435 return rbegin();
4436}
4437
4438template <class VALUE, class ALLOCATOR>
4439inline
4440typename list<VALUE, ALLOCATOR>::const_reverse_iterator
4441list<VALUE, ALLOCATOR>::crend() const BSLS_KEYWORD_NOEXCEPT
4442{
4443 return rend();
4444}
4445
4446template <class VALUE, class ALLOCATOR>
4447inline
4448typename list<VALUE, ALLOCATOR>::const_reverse_iterator
4449list<VALUE, ALLOCATOR>::rbegin() const BSLS_KEYWORD_NOEXCEPT
4450{
4451 return const_reverse_iterator(end());
4452}
4453
4454template <class VALUE, class ALLOCATOR>
4455inline
4456typename list<VALUE, ALLOCATOR>::const_reverse_iterator
4457list<VALUE, ALLOCATOR>::rend() const BSLS_KEYWORD_NOEXCEPT
4458{
4459 return const_reverse_iterator(begin());
4460}
4461
4462 // *** size ***
4463
4464template <class VALUE, class ALLOCATOR>
4465inline
4466bool list<VALUE, ALLOCATOR>::empty() const BSLS_KEYWORD_NOEXCEPT
4467{
4468 return 0 == sizeRef();
4469}
4470
4471template <class VALUE, class ALLOCATOR>
4472inline
4473typename list<VALUE, ALLOCATOR>::size_type
4474list<VALUE, ALLOCATOR>::max_size() const BSLS_KEYWORD_NOEXCEPT
4475{
4476 return AllocTraits::max_size(allocatorImp());
4477}
4478
4479template <class VALUE, class ALLOCATOR>
4480inline
4481typename list<VALUE, ALLOCATOR>::size_type list<VALUE, ALLOCATOR>::size() const
4483{
4484 return sizeRef();
4485}
4486
4487 // *** element access ***
4488
4489template <class VALUE, class ALLOCATOR>
4490inline
4491typename list<VALUE, ALLOCATOR>::const_reference
4492list<VALUE, ALLOCATOR>::back() const
4493{
4494 BSLS_ASSERT_SAFE(sizeRef() > 0);
4495
4496 return d_sentinel->d_prev_p->d_value;
4497}
4498
4499template <class VALUE, class ALLOCATOR>
4500inline
4501typename list<VALUE, ALLOCATOR>::const_reference
4502list<VALUE, ALLOCATOR>::front() const
4503{
4504 BSLS_ASSERT_SAFE(sizeRef() > 0);
4505
4506 return headNode()->d_value;
4507}
4508
4509 // *** misc ***
4510
4511template <class VALUE, class ALLOCATOR>
4512inline
4513ALLOCATOR list<VALUE, ALLOCATOR>::get_allocator() const BSLS_KEYWORD_NOEXCEPT
4514{
4515 return allocatorImp();
4516}
4517
4518} // close namespace bsl
4519
4520// FREE OPERATORS
4521template <class VALUE, class ALLOCATOR>
4522inline
4523bool bsl::operator==(const list<VALUE, ALLOCATOR>& lhs,
4524 const list<VALUE, ALLOCATOR>& rhs)
4525{
4526 return BloombergLP::bslalg::RangeCompare::equal(lhs.begin(),
4527 lhs.end(),
4528 lhs.size(),
4529 rhs.begin(),
4530 rhs.end(),
4531 rhs.size());
4532}
4533
4534#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
4535
4536template <class VALUE, class ALLOCATOR>
4537inline
4538bool bsl::operator!=(const list<VALUE, ALLOCATOR>& lhs,
4539 const list<VALUE, ALLOCATOR>& rhs)
4540{
4541 return ! (lhs == rhs);
4542}
4543
4544#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
4545
4546#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
4547
4548template <class VALUE, class ALLOCATOR>
4549inline
4550BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE> bsl::operator<=>(
4551 const list<VALUE, ALLOCATOR>& lhs,
4552 const list<VALUE, ALLOCATOR>& rhs)
4553{
4554 return bsl::lexicographical_compare_three_way(
4555 lhs.begin(),
4556 lhs.end(),
4557 rhs.begin(),
4558 rhs.end(),
4559 BloombergLP::bslalg::SynthThreeWayUtil::compare);
4560}
4561
4562#else
4563
4564template <class VALUE, class ALLOCATOR>
4565inline
4566bool bsl::operator< (const list<VALUE, ALLOCATOR>& lhs,
4567 const list<VALUE, ALLOCATOR>& rhs)
4568{
4569 return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.begin(),
4570 lhs.end(),
4571 lhs.size(),
4572 rhs.begin(),
4573 rhs.end(),
4574 rhs.size());
4575}
4576
4577template <class VALUE, class ALLOCATOR>
4578inline
4579bool bsl::operator> (const list<VALUE, ALLOCATOR>& lhs,
4580 const list<VALUE, ALLOCATOR>& rhs)
4581{
4582 return rhs < lhs;
4583}
4584
4585template <class VALUE, class ALLOCATOR>
4586inline
4587bool bsl::operator<=(const list<VALUE, ALLOCATOR>& lhs,
4588 const list<VALUE, ALLOCATOR>& rhs)
4589{
4590 return !(rhs < lhs);
4591}
4592
4593template <class VALUE, class ALLOCATOR>
4594inline
4595bool bsl::operator>=(const list<VALUE, ALLOCATOR>& lhs,
4596 const list<VALUE, ALLOCATOR>& rhs)
4597{
4598 return !(lhs < rhs);
4599}
4600
4601#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
4602
4603// FREE FUNCTIONS
4604template <class VALUE, class ALLOCATOR, class BDE_OTHER_TYPE>
4606bsl::erase(list<VALUE, ALLOCATOR>& l, const BDE_OTHER_TYPE& value)
4607{
4608 // We could use the erase/remove idiom here like we do in the other
4609 // sequence containers, but this is more efficient, since we just unlink
4610 // and delete nodes from the list.
4611 typename list<VALUE, ALLOCATOR>::size_type oldSize = l.size();
4612 for (typename list<VALUE, ALLOCATOR>::iterator it = l.begin();
4613 it != l.end();)
4614 {
4615 if (value == *it) {
4616 it = l.erase(it);
4617 }
4618 else {
4619 ++it;
4620 }
4621 }
4622 return oldSize - l.size();
4623}
4624
4625template <class VALUE, class ALLOCATOR, class PREDICATE>
4627bsl::erase_if(list<VALUE, ALLOCATOR>& l, PREDICATE predicate)
4628{
4629 return BloombergLP::bslstl::AlgorithmUtil::containerEraseIf(l, predicate);
4630}
4631
4632template <class VALUE, class ALLOCATOR>
4633inline
4634void bsl::swap(list<VALUE, ALLOCATOR>& a, list<VALUE, ALLOCATOR>& b)
4636 a.swap(b)))
4637{
4638 a.swap(b);
4639}
4640
4641// ============================================================================
4642// TYPE TRAITS
4643// ============================================================================
4644
4645// Type traits for STL *sequence* containers:
4646//: o A sequence container defines STL iterators.
4647//: o A sequence container uses 'bslma' allocators if the (template parameter)
4648//: type 'ALLOCATOR' is convertible from 'bslma::Allocator*'.
4649
4650
4651
4652namespace bslalg {
4653
4654template <class VALUE, class ALLOCATOR>
4655struct HasStlIterators<bsl::list<VALUE, ALLOCATOR> >
4657{};
4658
4659} // close namespace bslalg
4660
4661namespace bslma {
4662
4663template <class VALUE, class ALLOCATOR>
4664struct UsesBslmaAllocator<bsl::list<VALUE, ALLOCATOR> >
4665 : bsl::is_convertible<Allocator*, ALLOCATOR>
4666{};
4667
4668} // close namespace bslma
4669
4670namespace bslmf {
4671
4672// A list is bitwise movable if its allocator is bitwise movable.
4673
4674template <class VALUE, class ALLOCATOR>
4675struct IsBitwiseMoveable<bsl::list<VALUE, ALLOCATOR> >
4676 : BloombergLP::bslmf::IsBitwiseMoveable<ALLOCATOR>
4677{};
4678
4679} // close namespace bslmf
4680
4681
4682#else // if ! defined(DEFINED_BSLSTL_LIST_H)
4683# error Not valid except when included from bslstl_list.h
4684#endif // ! defined(COMPILING_BSLSTL_LIST_H)
4685
4686#endif // ! defined(INCLUDED_BSLSTL_LIST_CPP03)
4687
4688// ----------------------------------------------------------------------------
4689// Copyright 2019 Bloomberg Finance L.P.
4690//
4691// Licensed under the Apache License, Version 2.0 (the "License");
4692// you may not use this file except in compliance with the License.
4693// You may obtain a copy of the License at
4694//
4695// http://www.apache.org/licenses/LICENSE-2.0
4696//
4697// Unless required by applicable law or agreed to in writing, software
4698// distributed under the License is distributed on an "AS IS" BASIS,
4699// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4700// See the License for the specific language governing permissions and
4701// limitations under the License.
4702// ----------------------------- END-OF-FILE ----------------------------------
4703
4704/** @} */
4705/** @} */
4706/** @} */
Definition bslstl_list.h:769
List_Iterator & operator--()
Definition bslstl_list.h:2282
~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
friend class list
Definition bslstl_list.h:739
friend class List_Iterator
Definition bslstl_list.h:742
Definition bslma_bslallocator.h:588
allocator_traits< ALLOCATOR >::size_type size_type
Definition bslstl_list.h:1121
#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_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
bool operator!=(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
void swap(OptionValue &a, OptionValue &b)
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
int assign(LHS_TYPE *lhs, const RHS_TYPE &rhs)
TransformIterator< FUNCTOR, ITERATOR > operator--(TransformIterator< FUNCTOR, ITERATOR > &iterator, int)
bool operator>=(const Guid &lhs, const Guid &rhs)
FunctionOutputIterator< FUNCTION > & operator++(FunctionOutputIterator< FUNCTION > &iterator)
Do nothing and return specified iterator.
Definition bdlb_functionoutputiterator.h:408
bool operator<=(const Guid &lhs, const Guid &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
bool operator==(const memory_resource &a, const memory_resource &b)
T::const_iterator cbegin(const T &container)
Definition bslstl_iterator.h:1651
ALLOCATOR & lhs
Definition bslstl_string.h:3917
T::iterator end(T &container)
Definition bslstl_iterator.h:1621
deque< VALUE_TYPE, ALLOCATOR >::size_type erase_if(deque< VALUE_TYPE, ALLOCATOR > &deq, PREDICATE predicate)
Definition bslstl_deque.h:4433
bool operator!=(const memory_resource &a, const memory_resource &b)
Definition bdlc_flathashmap.h:2218
Definition baljsn_encoder_testtypes.h:76
Definition bdlbb_blob.h:579
BloombergLP::bslma::AllocatorTraits_SizeType< ALLOCATOR_TYPE >::type size_type
Definition bslma_allocatortraits.h:1196
Definition bslmf_isconvertible.h:875
Definition bslmf_issame.h:146
remove_const< typenameremove_volatile< t_TYPE >::type >::type type
Definition bslmf_removecv.h:128