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