// bslstl_list_cpp03.h                                                -*-C++-*-

// Automatically generated file.  **DO NOT EDIT**

#ifndef INCLUDED_BSLSTL_LIST_CPP03
#define INCLUDED_BSLSTL_LIST_CPP03

//@PURPOSE: Provide C++03 implementation for bslstl_list.h
//
//@CLASSES: See bslstl_list.h for list of classes
//
//@SEE_ALSO: bslstl_list
//
//@DESCRIPTION:  This component is the C++03 translation of a C++11 component,
// generated by the 'sim_cpp11_features.pl' program.  If the original header
// contains any specially delimited regions of C++11 code, then this generated
// file contains the C++03 equivalent, i.e., with variadic templates expanded
// and rvalue-references replaced by 'bslmf::MovableRef' objects.  The header
// code in this file is designed to be '#include'd into the original header
// when compiling with a C++03 compiler.  If there are no specially delimited
// regions of C++11 code, then this header contains no code and is not
// '#include'd in the original header.
//
// Generated on Wed Oct  5 09:43:08 2022
// Command line: sim_cpp11_features.pl bslstl_list.h

#ifdef COMPILING_BSLSTL_LIST_H

namespace bsl {

                        // =====================
                        // struct bsl::List_Node
                        // =====================

template <class VALUE>
class List_Node {
    // PRIVATE CLASS TEMPLATE.  For use only by 'bsl::list' implementation.
    // An instance of 'List_Node<T>' is a single node in a doubly-linked list
    // used to implement 'bsl::list<T,A>', for a given element type 'T' and
    // allocator type 'A'.  Note that an instantiation of this 'class' for a
    // given 'bsl::list' is independent of the allocator type.

    // DATA
    List_Node *d_prev_p;   // pointer to the previous node in the list
    List_Node *d_next_p;   // pointer to the next node in the list
    VALUE      d_value;    // list element

    // FRIENDS
    template <class LIST_VALUE, class LIST_ALLOCATOR>
    friend class list;

    template <class ITER_VALUE>
    friend class List_Iterator;

  private:
    // NOT IMPLEMENTED
    List_Node();                              // = delete;
    List_Node(const List_Node&);              // = delete;
    ~List_Node();                             // = delete;
    List_Node& operator=(const List_Node&);   // = delete;

    // A 'List_Node' is never constructed, copied, destroyed, or assigned to.
    // The 'd_value' field is constructed directly by 'list::emplace', and
    // destroyed directly by 'list::erase'.
};

                        // ========================
                        // class bsl::List_Iterator
                        // ========================

#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
// On Solaris studio12-v4, <algorithm> is compatible only with iterators
// inheriting from 'std::iterator'.

template <class VALUE>
class List_Iterator :
                 public std::iterator<std::bidirectional_iterator_tag, VALUE> {
#else
template <class VALUE>
class List_Iterator {
#endif
    // Implementation of 'bsl::list::iterator'.

    // PRIVATE TYPES
    typedef typename remove_cv<VALUE>::type  NcType;
    typedef List_Iterator<NcType>            NcIter;
    typedef List_Node<NcType>                Node;

    // DATA
    Node *d_node_p;      // pointer to list node

    // FRIENDS
    template <class LIST_VALUE, class LIST_ALLOCATOR>
    friend class list;

    template <class ITER_VALUE>    // This 'friend' statement is needed for the
    friend class List_Iterator;    // case where 'VALUE' != 'ITER_VALUE'.

    template <class T1, class T2>
    friend bool operator==(List_Iterator<T1>, List_Iterator<T2>);

  private:
    // PRIVATE ACCESSORS
    NcIter unconst() const;
        // Return an iterator providing modifiable access to the list element
        // that this list iterator refers to.

  public:
    // PUBLIC TYPES
    typedef std::bidirectional_iterator_tag   iterator_category;
    typedef NcType                            value_type;
    typedef BloombergLP::bsls::Types::IntPtr  difference_type;
    typedef VALUE                            *pointer;
    typedef VALUE&                            reference;

    // CREATORS
    List_Iterator();
        // Create a singular iterator (i.e., one that cannot be incremented,
        // decremented, or dereferenced until assigned a non-singular value).

    explicit List_Iterator(Node *nodePtr);
        // Create an iterator that references the value pointed to by the
        // specified 'nodePtr'.  If '0 == nodePtr' the iterator will be
        // singular.

    List_Iterator(const NcIter& other);                             // IMPLICIT
        // Create an iterator that has the same value as the specified 'other'
        // iterator.  If the (template parameter) type 'VALUE' is not
        // 'const'-qualified, then this constructor is the copy constructor;
        // otherwise, the copy constructor is implicitly generated.  Note that
        // this method is marked "IMPLICIT" in case it is not the copy
        // constructor.
        //
        // Note that this means that a 'List_Iterator<const VALUE>' can be copy
        // constructed or assigned to from a 'List_Iterator<VALUE>', but not
        // vice-versa.

    // Compiler-generated copy constructor, destructor, and copy-assignment
    // operator:
    //: o List_Iterator(const List_Iterator&); // Maybe defaulted (see above).
    //: o ~List_Iterator() = default;
    //: o List_Iterator& operator=(const List_Iterator&) = default;

#if defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS)
    ~List_Iterator() = default;
        // Default compiler-generated destructor.

    List_Iterator& operator=(const List_Iterator&) = default;
        // Default compiler-generated copy-assignment operator.
#endif

    // MANIPULATORS
    List_Iterator& operator++();
        // Advance this iterator to the next element in the list and return its
        // new value.  The behavior is undefined unless this iterator is in the
        // range '[begin() .. end())' for some list (i.e., the iterator is not
        // singular, is not 'end()', and has not been invalidated).

    List_Iterator& operator--();
        // Regress this iterator to the previous element in the list and return
        // its new value.  The behavior is undefined unless this iterator is in
        // the range '(begin() .. end()]' for some list (i.e., the iterator is
        // not singular, is not 'begin()', and has not been invalidated).

    List_Iterator operator++(int);
        // Advance this iterator to the next element in the list and return its
        // previous value.  The behavior is undefined unless this iterator is
        // in the range '[begin() .. end())' for some list (i.e., the iterator
        // is not singular, is not 'end()', and has not been invalidated).

    List_Iterator operator--(int);
        // Regress this iterator to the previous element in the list and return
        // its previous value.  The behavior is undefined unless this iterator
        // is in the range '(begin() .. end()]' for some list (i.e., the
        // iterator is not singular, is not 'begin()', and has not been
        // invalidated).

    // ACCESSORS
    reference operator*() const;
        // Return a reference providing modifiable access to the element
        // referenced by this iterator.  The behavior is undefined unless this
        // iterator is in the range '[begin() .. end())' for some list (i.e.,
        // the iterator is not singular, is not 'end()', and has not been
        // invalidated).

    pointer operator->() const;
        // Return a pointer providing modifiable access to the element
        // referenced by this iterator.  The behavior is undefined unless this
        // iterator is in the range '[begin() .. end())' for some list (i.e.,
        // the iterator is not singular, is not 'end()', and has not been
        // invalidated).
};

// FREE OPERATORS
template <class T1, class T2>
bool operator==(List_Iterator<T1> lhs, List_Iterator<T2> rhs);
    // Return 'true' if the specified 'lhs' and 'rhs' iterators have the same
    // value, and 'false' otherwise.  Two iterators have the same value if both
    // refer to the same element of the same list or both are the 'end()'
    // iterator of the same list.  The behavior is undefined unless both 'lhs'
    // and 'rhs' refer to the same list.  Note that the different types 'T1'
    // and 'T2' are to facilitate comparisons between 'const' and non-'const'
    // iterators and there will be a compilation error if 'T1' and 'T2' differ
    // in any way other than 'const'-ness.

template <class T1, class T2>
bool operator!=(List_Iterator<T1> lhs, List_Iterator<T2> rhs);
    // Return 'true' if the specified 'lhs' and 'rhs' iterators do not have the
    // same value, and 'false' otherwise.  Two iterators do not have the same
    // value unless both refer to the same element of the same list or unless
    // both are the 'end()' iterator of the same list.  The behavior is
    // undefined unless both 'lhs' and 'rhs' refer to the same list.  Note that
    // the different types 'T1' and 'T2' are to facilitate comparisons between
    // 'const' and non-'const' iterators and there will be a compilation error
    // if 'T1' and 'T2' differ in any way other than 'const'-ness.

                         // ===========================
                         // struct List_DefaultLessThan
                         // ===========================

template <class VALUE>
struct List_DefaultLessThan {
    // Binary predicate type for comparing two 'VALUE' objects using
    // 'operator<'.  This operation is usually, but not always, the same as
    // that provided by 'std::less<VALUE>'.  The standard requires that certain
    // functions use 'operator<', which means that divergent specializations of
    // 'std::less' are to be ignored.

    // ACCESSORS
    bool operator()(const VALUE& lhs, const VALUE& rhs) const;
        // Return 'true' if the value of the specified 'lhs' is less than that
        // of the specified 'rhs', and 'false' otherwise.
};

                        // ==============================
                        // class List_AllocAndSizeWrapper
                        // ==============================

template <class VALUE, class ALLOCATOR>
class List_AllocAndSizeWrapper : public allocator_traits<ALLOCATOR>::
                    template rebind_traits<List_Node<VALUE> >::allocator_type {
    // This struct is a wrapper around the allocator and size data members of a
    // 'list'.  It takes advantage of the empty-base optimization (EBO) so that
    // if the allocator is stateless, it takes up no space.
    //
    // TBD: This struct should eventually be replaced by the use of a general
    // EBO-enabled component that provides a 'pair'-like interface.  (A
    // properly-optimized 'tuple' would do the job.)

    // PRIVATE TYPES
    typedef List_Node<VALUE>                      Node;

    typedef typename allocator_traits<ALLOCATOR>::template rebind_traits<Node>
                                                  AllocTraits;
        // Alias for the allocator traits type associated with the 'bsl::list'
        // container.

    typedef typename AllocTraits::allocator_type  NodeAlloc;    // base class

    typedef typename AllocTraits::size_type       size_type;

    // DATA
    size_type d_size;      // Number of elements in the list (not including the
                           // sentinel).

  private:
    // NOT IMPLEMENTED
    List_AllocAndSizeWrapper(const List_AllocAndSizeWrapper&);
    List_AllocAndSizeWrapper& operator=(const List_AllocAndSizeWrapper&);

  public:
    // CREATORS
    List_AllocAndSizeWrapper(const NodeAlloc& basicAllocator,
                             size_type        size);
        // Create an allocator and size wrapper having the specified
        // 'basicAllocator' and (initial) 'size'.

    // ~List_AllocAndSizeWrapper() = default;

    // MANIPULATORS
    size_type& size();
        // Return a reference providing modifiable access to the 'size' field
        // of this object.

    // ACCESSORS
    const size_type& size() const;
        // Return a reference providing non-modifiable access to the 'size'
        // field of this object.
};

template <class VALUE, class ALLOCATOR>
class list;
    // Forward declaration required by 'List_NodeProctor'.

                            // ======================
                            // class List_NodeProctor
                            // ======================

template <class VALUE, class ALLOCATOR>
class List_NodeProctor {
    // This class provides a proctor to free a node containing an uninitialized
    // 'VALUE' object in the event that an exception is thrown.

    // PRIVATE TYPES
    typedef List_Node<VALUE>                      Node;

    typedef typename allocator_traits<ALLOCATOR>::template rebind_traits<Node>
                                                  AllocTraits;
        // Alias for the allocator traits type associated with the 'bsl::list'
        // container.

  public:
    // PUBLIC TYPES

    // In C++11 'NodePtr' would be generalized as follows:
    // 'typedef pointer_traits<VoidPtr>::template rebind<List_Node> NodePtr;'

    typedef typename AllocTraits::pointer         NodePtr;

  private:
    // DATA
    list<VALUE, ALLOCATOR>  *d_list_p;  // list to proctor
    NodePtr                  d_node_p;  // node to free upon destruction

  private:
    // NOT IMPLEMENTED
    List_NodeProctor(const List_NodeProctor&);
    List_NodeProctor &operator=(const List_NodeProctor&);

  public:
    // CREATORS
    List_NodeProctor(list<VALUE, ALLOCATOR> *listPtr, NodePtr nodePtr);
        // Create a node proctor object that will use the specified list
        // 'listPtr' to free the specified 'nodePtr'.  The behavior is
        // undefined unless 'nodePtr' was allocated by the allocator of
        // '*listPtr'.

    ~List_NodeProctor();
        // Destroy this node proctor, and free the node it contains unless the
        // 'release' method has been called before.  Note that the 'd_value'
        // field of the node is not destroyed.

    // MANIPULATORS
    void release();
        // Detach the node contained in this proctor from the proctor.  After
        // calling this 'release' method, the proctor no longer frees any node
        // upon its destruction.
};

                            // ===============
                            // class bsl::list
                            // ===============

template <class VALUE, class ALLOCATOR = bsl::allocator<VALUE> >
class list {
    // This class template implements a value-semantic container type holding a
    // sequence of elements of the (template parameter) 'VALUE' type.

    // PRIVATE TYPES
    typedef List_DefaultLessThan<VALUE>           DefaultLessThan;
        // Default comparator.

    typedef List_Node<VALUE>                      Node;
        // Alias for the node type in this list.

    typedef List_NodeProctor<VALUE, ALLOCATOR>    NodeProctor;
        // Proctor for guarding a newly allocated node.

    typedef typename allocator_traits<ALLOCATOR>::template rebind_traits<Node>
                                                  AllocTraits;
        // Alias for the allocator traits type associated with this container.

    typedef BloombergLP::bslmf::MovableRefUtil    MoveUtil;
        // Alias for the utility associated with movable references.

    typedef List_AllocAndSizeWrapper<VALUE, ALLOCATOR>
                                                  AllocAndSizeWrapper;
        // Alias for the wrapper containing the (usually stateless) allocator
        // and number of elements stored in this container.

    typedef typename AllocTraits::allocator_type  NodeAlloc;
        // Base class of 'List_AllocAndSizeWrapper' containing the allocator.

    // In C++11 'NodePtr' would be generalized as follows:
    // 'typedef pointer_traits<VoidPtr>::template rebind<List_Node> NodePtr;'

    typedef typename AllocTraits::pointer         NodePtr;

  public:
    // PUBLIC TYPES
    typedef VALUE&                                             reference;
    typedef const VALUE&                                       const_reference;
    typedef List_Iterator<VALUE>                               iterator;
    typedef List_Iterator<const VALUE>                         const_iterator;
    typedef typename allocator_traits<ALLOCATOR>::pointer      pointer;
    typedef typename allocator_traits<ALLOCATOR>::const_pointer
                                                               const_pointer;

    typedef typename allocator_traits<ALLOCATOR>::size_type    size_type;
    typedef typename allocator_traits<ALLOCATOR>::difference_type
                                                               difference_type;
    typedef VALUE                                 value_type;
    typedef ALLOCATOR                             allocator_type;
    typedef bsl::reverse_iterator<iterator>       reverse_iterator;
    typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;

  private:
    // DATA
    NodePtr             d_sentinel;        // node pointer of sentinel element
    AllocAndSizeWrapper d_alloc_and_size;  // node allocator

    // FRIENDS
    friend class List_NodeProctor<VALUE, ALLOCATOR>;

    // PRIVATE MANIPULATORS
    NodeAlloc& allocatorImp();
        // Return a reference providing modifiable access to the allocator used
        // to allocate nodes.

    NodePtr allocateNode();
        // Return a pointer to a node allocated from the container's allocator.
        // Before returning, the node's pointers are zeroed, but the
        // constructor of the 'value_type' is not called.

    void createSentinel();
        // Create the sentinel node of this list.  The sentinel node does not
        // hold a value.  When first created, its forward and backward pointers
        // point to itself, creating a circular linked list.  This function
        // also sets this list's size to 0.

    void deleteNode(NodePtr node);
        // Destroy the value part of the specified 'node' and free the node's
        // memory.  Do not do any pointer fix-up of the node or its neighbors,
        // and do not update 'sizeRef'.  The behavior is undefined unless
        // 'node' was allocated using the allocator of this list.

    void destroyAll();
        // Erase all elements and deallocate the sentinel node, leaving this
        // list in an invalid but destructible state (i.e., with 'size == -1').

    void freeNode(NodePtr node);
        // Zero out the pointers and deallocate the node pointed to by the
        // specified 'node'.  The behavior is undefined unless 'node' was
        // allocated using the allocator of this list.  Note that 'node's
        // destructor is not called, and, importantly, the value field of
        // 'node' is not destroyed.

    iterator insertNode(const_iterator position, NodePtr node);
        // Insert the specified 'node' prior to the specified 'position' in
        // this list.  The behavior is undefined unless 'node' was allocated
        // using the allocator of this list and 'position' is in the range
        // '[begin() .. end()]'.

    void linkNodes(NodePtr prev, NodePtr next);
        // Modify the forward pointer of the specified 'prev' to point to the
        // specified 'next' and the backward pointer of 'next' to point to
        // 'prev'.  The behavior is undefined unless 'prev' and 'next' point to
        // nodes created with 'allocateNode'.

    template <class COMPARE>
    NodePtr mergeImp(NodePtr node1,
                     NodePtr node2,
                     NodePtr finish,
                     COMPARE comparator);
        // Given a specified pair of nodes 'node1' and 'finish' specifying the
        // range '[node1 .. finish)', with the specified 'node2' pointing
        // somewhere in the middle of the sequence, merge sequence
        // '[node2 .. finish)' into '[node1 .. node2)', and return a pointer to
        // the beginning of the merged sequence, using the specified
        // 'comparator' to determine order.  If an exception is thrown, all
        // nodes remain in this list, but their order is unspecified.  If any
        // nodes in the range '[node1 .. node2)' compare equivalent to any
        // nodes in the range '[node2 .. finish)', the nodes from
        // '[node1 .. node2)' will be merged first.  The behavior is undefined
        // unless '[node1 .. node2)' and '[node2 .. finish)' each describe a
        // contiguous sequence of nodes.

    void quickSwap(list *other);
        // Efficiently exchange the value of this object with that of the
        // specified 'other' object.  This method provides the no-throw
        // exception-safety guarantee.  The behavior is undefined unless this
        // object was created with the same allocator as 'other'.

    typename AllocTraits::size_type& sizeRef() BSLS_KEYWORD_NOEXCEPT;
        // Return a reference providing modifiable access to the data element
        // holding the size of this list.

    template <class COMPARE>
    NodePtr sortImp(NodePtr        *nodePtrPtr,
                    size_type       size,
                    const COMPARE&  comparator);
        // Sort the sequence of the specified 'size' nodes starting with the
        // specified '*nodePtrPtr', and modify '*nodePtrPtr' to refer to the
        // first node of the sorted sequence.  Return the pointer to the node
        // following the sequence of nodes to be sorted.  Use the specified
        // 'comparator' to compare 'VALUE' type objects.  If an exception is
        // thrown, all nodes remain properly linked, but their order is
        // unspecified.  The behavior is undefined unless '*nodePtrPtr' begins
        // a sequence of at least 'size' nodes, none of which is the sentinel
        // node, and '0 < size'.

    // PRIVATE ACCESSORS
    const NodeAlloc& allocatorImp() const;
        // Return a reference providing non-modifiable access to the allocator
        // used to allocate nodes.

    NodePtr headNode() const;
        // Return a pointer providing modifiable access to the first node in
        // this list or the sentinel node if this list is empty.

    const typename AllocTraits::size_type& sizeRef() const
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Return a reference providing non-modifiable access to the data
        // element holding the size of this list.

  public:
    // CREATORS
    list();
        // Create an empty list.  A default-constructed object of the (template
        // parameter) type 'ALLOCATOR' is used.  If the type 'ALLOCATOR' is
        // 'bsl::allocator', the currently installed default allocator is used.

    explicit list(const ALLOCATOR& basicAllocator);
        // Create an empty list.  Use the specified 'basicAllocator' to supply
        // memory.  If the type 'ALLOCATOR' is 'bsl::allocator' (the default),
        // then 'basicAllocator' shall be convertible to 'bslma::Allocator *'.

    explicit list(size_type numElements);
        // Create a list of the specified 'numElements' size whose every
        // element is default-constructed.  A default-constructed object of the
        // (template parameter) type 'ALLOCATOR' is used.  If the type
        // 'ALLOCATOR' is 'bsl::allocator', the currently installed default
        // allocator is used.  Throw 'bsl::length_error' if
        // 'numElements > max_size()'.  This method requires that the (template
        // parameter) 'VALUE' be 'default-insertable' into this list (see
        // {Requirements on 'VALUE'}).

    list(size_type        numElements,
         const ALLOCATOR& basicAllocator);
        // Create a list of the specified 'numElements' size whose every
        // element is default-constructed.  Use the specified 'basicAllocator'
        // to supply memory.  If the type 'ALLOCATOR' is 'bsl::allocator' (the
        // default), then 'basicAllocator' shall be convertible to
        // 'bslma::Allocator *'.  Throw 'bsl::length_error' if
        // 'numElements > max_size()'.  This method requires that the (template
        // parameter) 'VALUE' be 'default-insertable' into this list (see
        // {Requirements on 'VALUE'}).

    list(size_type         numElements,
         const value_type& value,
         const ALLOCATOR&  basicAllocator = ALLOCATOR());
        // Create a list of the specified 'numElements' size whose every
        // element has the specified 'value'.  Optionally specify a
        // 'basicAllocator' used to supply memory.  If 'basicAllocator' is not
        // supplied, a default-constructed object of the (template parameter)
        // type 'ALLOCATOR' is used.  If the type 'ALLOCATOR' is
        // 'bsl::allocator' (the default), then 'basicAllocator', if supplied,
        // shall be convertible to 'bslma::Allocator *'.  If the type
        // 'ALLOCATOR' is 'bsl::allocator' and 'basicAllocator' is not
        // supplied, the currently installed default allocator is used.  Throw
        // 'bsl::length_error' if 'numElements > max_size()'.  This method
        // requires that the (template parameter) 'VALUE' be 'copy-insertable'
        // into this list (see {Requirements on 'VALUE'}).

    template <class INPUT_ITERATOR>
    list(INPUT_ITERATOR   first,
         INPUT_ITERATOR   last,
         const ALLOCATOR& basicAllocator = ALLOCATOR(),
         typename enable_if<
                 !is_arithmetic<INPUT_ITERATOR>::value &&
                 !is_enum<INPUT_ITERATOR>::value
         >::type * = 0)
        // Create a list initially containing copies of the values in the range
        // starting at the specified 'first' and ending immediately before the
        // specified 'last' iterators of the (template parameter) type
        // 'INPUT_ITERATOR'.  Optionally specify a 'basicAllocator' used to
        // supply memory.  If 'basicAllocator' is not supplied, a
        // default-constructed object of the (template parameter) type
        // 'ALLOCATOR' is used.  If the type 'ALLOCATOR' is 'bsl::allocator'
        // (the default), then 'basicAllocator', if supplied, shall be
        // convertible to 'bslma::Allocator *'.  If the type 'ALLOCATOR' is
        // 'bsl::allocator' and 'basicAllocator' is not supplied, the currently
        // installed default allocator is used.  Throw 'bsl::length_error' if
        // the number of elements in '[first .. last)' exceeds the size
        // returned by 'max_size'.  The (template parameter) type
        // 'INPUT_ITERATOR' shall meet the requirements of an input iterator
        // defined in the C++11 standard [input.iterators] providing access to
        // values of a type convertible to 'value_type', and 'value_type' must
        // be 'emplace-constructible' from '*i' into this list, where 'i' is a
        // dereferenceable iterator in the range '[first .. last)' (see
        // {Requirements on 'VALUE'}).  The behavior is undefined unless
        // 'first' and 'last' refer to a sequence of valid values where 'first'
        // is at a position at or before 'last'.
    : d_alloc_and_size(basicAllocator, size_type(-1))
    {
        // MS Visual Studio 2008 compiler requires that a function using
        // enable_if be in-place inline.

        // '*this' is in an invalid but destructible state (size == -1).
        // Create a temporary list, 'tmp' with the specified data.  If an
        // exception is thrown, 'tmp's destructor will clean up.  Otherwise,
        // swap 'tmp' with '*this', leaving 'tmp' in an invalid but
        // destructible state and leaving '*this' fully constructed.

        list tmp(this->allocatorImp());
        tmp.insert(tmp.cbegin(), first, last);
        quickSwap(&tmp);
    }

    list(const list& original);
        // Create a list having the same value as the specified 'original'
        // object.  Use the allocator returned by
        // 'bsl::allocator_traits<ALLOCATOR>::
        // select_on_container_copy_construction(original.get_allocator())' to
        // allocate memory.  This method requires that the (template parameter)
        // type 'VALUE' be 'copy-insertable' into this list (see {Requirements
        // on 'VALUE'}).

    list(const list&                                    original,
         const typename type_identity<ALLOCATOR>::type& basicAllocator);
        // Create a list that has the same value as the specified 'original'
        // object.  Use the specified 'basicAllocator' to supply memory.  This
        // method requires that the (template parameter) 'VALUE' be
        // 'copy-insertable' into this list (see {Requirements on 'VALUE'}).
        // Note that a 'bslma::Allocator *' can be supplied for
        // 'basicAllocator' if the (template parameter) type 'ALLOCATOR' is
        // 'bsl::allocator' (the default).

    list(BloombergLP::bslmf::MovableRef<list> original);            // IMPLICIT
        // Create a list having the same value as the specified 'original'
        // object by moving (in constant time) the contents of 'original' to
        // the new list.  The allocator associated with 'original' is
        // propagated for use in the newly-created list.  'original' is left in
        // a valid but unspecified state.

    list(BloombergLP::bslmf::MovableRef<list>           original,
         const typename type_identity<ALLOCATOR>::type& basicAllocator);
        // Create a list having the same value as the specified 'original'
        // object that uses the specified 'basicAllocator' to supply memory.
        // The contents of 'original' are moved (in constant time) to the new
        // list if 'basicAllocator == original.get_allocator()', and are move-
        // inserted (in linear time) using 'basicAllocator' otherwise.
        // 'original' is left in a valid but unspecified state.  This method
        // requires that the (template parameter) 'VALUE' be 'move-insertable'
        // into this list (see {Requirements on 'VALUE'}).  Note that a
        // 'bslma::Allocator *' can be supplied for 'basicAllocator' if the
        // (template parameter) 'ALLOCATOR' is 'bsl::allocator' (the default).

#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
    list(std::initializer_list<value_type> values,
         const ALLOCATOR&                  basicAllocator = ALLOCATOR());
                                                                    // IMPLICIT
        // Create a list and append each 'value_type' object in the specified
        // 'values' initializer list.  Optionally specify a 'basicAllocator'
        // used to supply memory.  If 'basicAllocator' is not supplied, a
        // default-constructed object of the (template parameter) type
        // 'ALLOCATOR' is used.  If the type 'ALLOCATOR' is 'bsl::allocator'
        // (the default), then 'basicAllocator', if supplied, shall be
        // convertible to 'bslma::Allocator *'.  If the type 'ALLOCATOR' is
        // 'bsl::allocator' and 'basicAllocator' is not supplied, the currently
        // installed default allocator is used.  This method requires that the
        // (template parameter) 'VALUE' be 'copy-insertable' into this list
        // (see {Requirements on 'VALUE'}).
#endif

    ~list();
        // Destroy this list by calling the destructor for each element and
        // deallocating all allocated storage.

    // MANIPULATORS

                            // *** assignment ***

    list& operator=(const list& rhs);
        // Assign to this object the value of the specified 'rhs' object,
        // propagate to this object the allocator of 'rhs' if the 'ALLOCATOR'
        // type has trait 'propagate_on_container_copy_assignment', and return
        // a reference providing modifiable access to this object.  If an
        // exception is thrown, '*this' is left in a valid but unspecified
        // state.  This method requires that the (template parameter) type
        // 'VALUE' be 'copy-assignable' and 'copy-insertable' into this list.
        // Note that, to the extent possible, existing elements of this list
        // are copy-assigned to, to minimize the number of nodes that need to
        // be copy-inserted or erased.

    list& operator=(BloombergLP::bslmf::MovableRef<list> rhs)
        BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(
                                          AllocTraits::is_always_equal::value);
        // Assign to this object the value of the specified 'rhs' object,
        // propagate to this object the allocator of 'rhs' if the 'ALLOCATOR'
        // type has trait 'propagate_on_container_move_assignment', and return
        // a reference providing modifiable access to this object.  The
        // contents of 'rhs' are moved (in constant time) to this list if
        // 'get_allocator() == rhs.get_allocator()' (after accounting for the
        // aforementioned trait); otherwise, all elements in this list are
        // either destroyed or move-assigned to and each additional element in
        // 'rhs' is move-inserted into this list.  'rhs' is left in a valid but
        // unspecified state, and if an exception is thrown, '*this' is left in
        // a valid but unspecified state.  This method requires that the
        // (template parameter) type 'VALUE' be 'move-assignable' and
        // 'move-insertable' into this list (see {Requirements on 'VALUE'}).

#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
    list& operator=(std::initializer_list<value_type> rhs);
        // Assign to this list, in order, the sequence of values in the
        // specified 'rhs' initializer list, and return a reference providing
        // modifiable access to this list.  This method requires that the
        // (template parameter) type 'VALUE' be 'copy-assignable' and
        // 'copy-insertable' into this list.  Note that, to the extent
        // possible, existing elements of this list are copy-assigned to, to
        // minimize the number of nodes that need to be copy-inserted or
        // erased.
#endif

    template <class INPUT_ITERATOR>
    void assign(INPUT_ITERATOR first,
                INPUT_ITERATOR last,
                typename enable_if<
                    !is_arithmetic<INPUT_ITERATOR>::value &&
                    !is_enum<INPUT_ITERATOR>::value
                >::type * = 0)
        // Assign to this list the sequence of values, in order, of the
        // elements of the specified range '[first .. last)'.  The (template
        // parameter) type 'INPUT_ITERATOR' shall meet the requirements of an
        // input iterator defined in the C++11 standard [24.2.3] providing
        // access to values of a type convertible to 'value_type', and
        // 'value_type' must be 'emplace-constructible' from '*i' into this
        // list, where 'i' is a dereferenceable iterator in the range
        // '[first .. last)'.  The behavior is undefined unless 'first' and
        // 'last' refer to a sequence of valid values where 'first' is at a
        // position at or before 'last'.  Note that, to the extent possible,
        // existing elements of this list are copy-assigned to, to minimize the
        // number of nodes that need to be copy-inserted or erased.  If an
        // exception is thrown, '*this' is left in a valid but unspecified
        // state.
    {
        // MS Visual Studio 2008 compiler requires that a function using
        // enable_if be in-place inline.

        iterator       dstIt  = this->begin();
        const iterator dstEnd = this->end();

        for (; first != last && dstEnd != dstIt; ++first, ++dstIt) {
            *dstIt = *first;
        }

        erase(dstIt, dstEnd);

        for (; first != last; ++first) {
            emplace(dstEnd, *first);
        }
    }

    void assign(size_type numElements, const value_type& value);
        // Replace the contents of this list with the specified 'numElements'
        // copies of the specified 'value'.  Note that, to the extent possible,
        // existing elements of this list are copy-assigned to, to minimize the
        // number of nodes that need to be copy-inserted or erased.

#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
    void assign(std::initializer_list<value_type> values);
        // Assign to this list, in order, the sequence of values in the
        // specified 'values' initializer list.  This method requires that the
        // (template parameter) type 'VALUE' be 'copy-assignable' and
        // 'copy-insertable' into this list.  Note that, to the extent
        // possible, existing elements of this list are copy-assigned to, to
        // minimize the number of nodes that need to be copy-inserted or
        // erased.
#endif

                              // *** iterators ***

    iterator begin() BSLS_KEYWORD_NOEXCEPT;
        // Return an iterator providing modifiable access to the first element
        // in this list, and the past-the-end iterator if this list is empty.

    iterator end() BSLS_KEYWORD_NOEXCEPT;
        // Return the past-the-end (forward) iterator providing modifiable
        // access to this list.

    reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT;
        // Return a reverse iterator providing modifiable access to the last
        // element in this list, and the past-the-end reverse iterator if this
        // list is empty.

    reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT;
        // Return the past-the-end reverse iterator providing modifiable access
        // to this list.

                            // *** modify size ***

    void clear() BSLS_KEYWORD_NOEXCEPT;
        // Remove all the elements from this list.

    void resize(size_type newSize);
    void resize(size_type newSize, const value_type& value);
        // Change the size of this list to the specified 'newSize'.  Erase
        // 'size() - newSize' elements at the back if 'newSize < size()'.
        // Append 'newSize - size()' elements at the back having the optionally
        // specified 'value' if 'newSize > size()'; if 'value' is not
        // specified, default-constructed objects of the (template parameter)
        // 'VALUE' are emplaced.  This method has no effect if
        // 'newSize == size()'.  Throw 'bsl::length_error' if
        // 'newSize > max_size()'.

                           // *** element access ***

    reference back();
        // Return a reference providing modifiable access to the last element
        // of this list.  The behavior is undefined unless this list contains
        // at least one element.

    reference front();
        // Return a reference providing modifiable access to the first element
        // of this list.  The behavior is undefined unless this list contains
        // at least one element.

                                // *** end erase ***

    void pop_back();
        // Remove and destroy the last element of this list.  The behavior is
        // undefined unless this list contains at least one element.

    void pop_front();
        // Remove and destroy the first element of this list.  The behavior is
        // undefined unless this list contains at least one element.

                         // *** random access erase ***

    iterator erase(const_iterator position);
        // Remove from this list the element at the specified 'position', and
        // return an iterator providing modifiable access to the element
        // immediately following the removed element, or to the position
        // returned by the 'end' method if the removed element was the last in
        // the sequence.  The behavior is undefined unless 'position' refers to
        // an element in this list.

    iterator erase(const_iterator dstBegin, const_iterator dstEnd);
        // Remove from this list the elements starting at the specified
        // 'dstBegin' position up to, but not including, the specified 'dstEnd'
        // position, and return a non-'const' iterator equivalent to 'dstEnd'.
        // The behavior is undefined unless 'dstBegin' is an iterator in the
        // range '[begin() .. end()]' and 'dstEnd' is an iterator in the range
        // '[dstBegin .. end()]' (both endpoints included).  Note that
        // 'dstBegin' may be equal to 'dstEnd', in which case the list is not
        // modified.

                            // *** end inserts ***

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_list.h
#ifndef BSLSTL_LIST_VARIADIC_LIMIT
#define BSLSTL_LIST_VARIADIC_LIMIT 10
#endif
#ifndef BSLSTL_LIST_VARIADIC_LIMIT_A
#define BSLSTL_LIST_VARIADIC_LIMIT_A BSLSTL_LIST_VARIADIC_LIMIT
#endif
#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 0
    reference emplace_back(
                         );
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 0

#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 1
    template <class ARGS_01>
    reference emplace_back(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 1

#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 2
    template <class ARGS_01,
              class ARGS_02>
    reference emplace_back(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 2

#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 3
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03>
    reference emplace_back(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 3

#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 4
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04>
    reference emplace_back(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 4

#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 5
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05>
    reference emplace_back(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 5

#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 6
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06>
    reference emplace_back(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 6

#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 7
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07>
    reference emplace_back(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 7

#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 8
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08>
    reference emplace_back(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 8

#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 9
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09>
    reference emplace_back(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 9

#if BSLSTL_LIST_VARIADIC_LIMIT_A >= 10
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09,
              class ARGS_10>
    reference emplace_back(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_A >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
    template <class... ARGS>
    reference emplace_back(
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments);
// }}} END GENERATED CODE
#endif

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_list.h
#ifndef BSLSTL_LIST_VARIADIC_LIMIT
#define BSLSTL_LIST_VARIADIC_LIMIT 10
#endif
#ifndef BSLSTL_LIST_VARIADIC_LIMIT_B
#define BSLSTL_LIST_VARIADIC_LIMIT_B BSLSTL_LIST_VARIADIC_LIMIT
#endif
#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 0
    reference emplace_front(
                         );
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 0

#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 1
    template <class ARGS_01>
    reference emplace_front(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 1

#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 2
    template <class ARGS_01,
              class ARGS_02>
    reference emplace_front(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 2

#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 3
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03>
    reference emplace_front(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 3

#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 4
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04>
    reference emplace_front(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 4

#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 5
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05>
    reference emplace_front(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 5

#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 6
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06>
    reference emplace_front(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 6

#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 7
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07>
    reference emplace_front(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 7

#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 8
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08>
    reference emplace_front(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 8

#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 9
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09>
    reference emplace_front(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 9

#if BSLSTL_LIST_VARIADIC_LIMIT_B >= 10
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09,
              class ARGS_10>
    reference emplace_front(
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_B >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
    template <class... ARGS>
    reference emplace_front(
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments);
// }}} END GENERATED CODE
#endif

    void push_back(const value_type& value);
        // Append to the back of this list a copy of the specified 'value'.
        // This method offers full guarantee of rollback in case an exception
        // is thrown.  This method requires that the (template parameter)
        // 'VALUE' be 'copy-constructible' (see {Requirements on 'VALUE'}).

    void push_back(BloombergLP::bslmf::MovableRef<value_type> value);
        // Append to the back of this list the specified move-insertable
        // 'value'.  'value' is left in a valid but unspecified state.  If an
        // exception is thrown (other than by the move constructor of a
        // non-copy-insertable 'value_type'), this method has no effect.  This
        // method requires that the (template parameter) 'VALUE' be
        // 'move-insertable' into this list (see {Requirements on 'VALUE'}).

    void push_front(const value_type& value);
        // Prepend to the front of this list a copy of the specified 'value'.
        // This method offers full guarantee of rollback in case an exception
        // is thrown.  This method requires that the (template parameter)
        // 'VALUE' be 'copy-constructible' (see {Requirements on 'VALUE'}).

    void push_front(BloombergLP::bslmf::MovableRef<value_type> value);
        // Prepend to the front of this list the specified move-insertable
        // 'value'.  'value' is left in a valid but unspecified state.  If an
        // exception is thrown (other than by the move constructor of a
        // non-copy-insertable 'value_type'), this method has no effect.  This
        // method requires that the (template parameter) 'VALUE' be
        // 'move-insertable' into this list (see {Requirements on 'VALUE'}).

                       // *** random access inserts ***

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_list.h
#ifndef BSLSTL_LIST_VARIADIC_LIMIT
#define BSLSTL_LIST_VARIADIC_LIMIT 10
#endif
#ifndef BSLSTL_LIST_VARIADIC_LIMIT_C
#define BSLSTL_LIST_VARIADIC_LIMIT_C BSLSTL_LIST_VARIADIC_LIMIT
#endif
#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 0
    iterator emplace(const_iterator position);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 0

#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 1
    template <class ARGS_01>
    iterator emplace(const_iterator position,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 1

#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 2
    template <class ARGS_01,
              class ARGS_02>
    iterator emplace(const_iterator position,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 2

#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 3
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03>
    iterator emplace(const_iterator position,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 3

#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 4
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04>
    iterator emplace(const_iterator position,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 4

#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 5
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05>
    iterator emplace(const_iterator position,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 5

#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 6
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06>
    iterator emplace(const_iterator position,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 6

#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 7
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07>
    iterator emplace(const_iterator position,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 7

#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 8
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08>
    iterator emplace(const_iterator position,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 8

#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 9
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09>
    iterator emplace(const_iterator position,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 9

#if BSLSTL_LIST_VARIADIC_LIMIT_C >= 10
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09,
              class ARGS_10>
    iterator emplace(const_iterator position,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10);
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_C >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
    template <class... ARGS>
    iterator emplace(const_iterator position,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments);
// }}} END GENERATED CODE
#endif

    iterator insert(const_iterator dstPosition, const value_type& value);
        // Insert at the specified 'dstPosition' in this list a copy of the
        // specified 'value', and return an iterator providing modifiable
        // access to the newly inserted element.  This method offers full
        // guarantee of rollback in case an exception is thrown other than by
        // the 'VALUE' copy constructor or assignment operator.  This method
        // requires that the (template parameter) 'VALUE' be 'copy-insertable'
        // into this list (see {Requirements on 'VALUE'}).  The behavior is
        // undefined unless 'dstPosition' is an iterator in the range
        // '[cbegin() .. cend()] (both endpoints included)'.

    iterator insert(const_iterator                             dstPosition,
                    BloombergLP::bslmf::MovableRef<value_type> value);
        // Insert at the specified 'dstPosition' in this list the specified
        // move-insertable 'value', and return an iterator providing modifiable
        // access to the newly inserted element.  'value' is left in a valid
        // but unspecified state.  If an exception is thrown (other than by the
        // copy constructor, move constructor, assignment operator, or move
        // assignment operator of 'value_type'), this method has no effect.
        // This method requires that the (template parameter) 'VALUE' be
        // 'move-insertable' into this list (see {Requirements on 'VALUE'}).
        // The behavior is undefined unless 'dstPosition' is an iterator in the
        // range '[cbegin() .. cend()]' (both endpoints included).

    iterator insert(const_iterator    dstPosition,
                    size_type         numElements,
                    const value_type& value);
        // Insert at the specified 'dstPosition' in this list the specified
        // 'numElements' copies of the specified 'value', and return an
        // iterator providing modifiable access to the first element in the
        // newly inserted sequence of elements.  This method requires that the
        // (template parameter) 'VALUE' be 'copy-insertable' into this list
        // (see {Requirements on 'VALUE'}).  The behavior is undefined unless
        // 'dstPosition' is an iterator in the range '[cbegin() .. cend()]'
        // (both endpoints included).

    template <class INPUT_ITERATOR>
    iterator insert(const_iterator dstPosition,
                    INPUT_ITERATOR first,
                    INPUT_ITERATOR last,
                    typename enable_if<
                        !is_arithmetic<INPUT_ITERATOR>::value &&
                        !is_enum<INPUT_ITERATOR>::value
                    >::type * = 0)
        // Insert at the specified 'dstPosition' in this list the values in the
        // range starting at the specified 'first' and ending immediately
        // before the specified 'last' iterators of the (template parameter)
        // type 'INPUT_ITERATOR', and return an iterator providing modifiable
        // access to the first element in the newly inserted sequence of
        // elements.  The (template parameter) type 'INPUT_ITERATOR' shall meet
        // the requirements of an input iterator defined in the C++11 standard
        // [input.iterators] providing access to values of a type convertible
        // to 'value_type', and 'value_type' must be 'emplace-constructible'
        // from '*i' into this list, where 'i' is a dereferenceable iterator in
        // the range '[first .. last)' (see {Requirements on 'VALUE'}).  The
        // behavior is undefined unless 'dstPosition' is an iterator in the
        // range '[cbegin() .. cend()]' (both endpoints included), and 'first'
        // and 'last' refer to a sequence of valid values where 'first' is at a
        // position at or before 'last'.
    {
        // MS Visual Studio 2008 compiler requires that a function using
        // enable_if be in place inline.

        if (first == last) {
            return dstPosition.unconst();                             // RETURN
        }

        // The return value should indicate the first node inserted.  We can't
        // assume 'INPUT_ITERATOR' has a post-increment available.

        iterator ret = insert(dstPosition, *first);
        for (++first; first != last; ++first) {
            insert(dstPosition, *first);
        }

        return ret;
    }

#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
    iterator insert(const_iterator                    dstPosition,
                    std::initializer_list<value_type> values);
        // Insert at the specified 'dstPosition' in this list the value of each
        // 'value_type' object in the specified 'values' initializer list, and
        // return an iterator providing modifiable access to the first element
        // in the newly inserted sequence of elements.  This method requires
        // that the (template parameter) 'VALUE' be 'copy-insertable' into this
        // list (see {Requirements on 'VALUE'}).  The behavior is undefined
        // unless 'dstPosition' is an iterator in the range
        // '[cbegin() .. cend()]' (both endpoints included).
#endif

                          // *** list operations ***

    void merge(list&                                other);
    void merge(BloombergLP::bslmf::MovableRef<list> other);
        // Merge the specified sorted 'other' list into this sorted list.  This
        // method has no effect if 'other' is this list; otherwise, 'other' is
        // left empty.  The behavior is undefined unless both 'other' and this
        // list are sorted in non-decreasing order according to the ordering
        // provided by 'operator<', and unless both 'other' and this list use
        // the same allocator.  'operator<' must define a strict weak ordering
        // per 'value_type' (see {Comparators and Strict Weak Ordering}).

    template <class COMPARE>
    void merge(list& other, COMPARE comparator);
    template <class COMPARE>
    void merge(BloombergLP::bslmf::MovableRef<list> other, COMPARE comparator);
        // Merge the specified sorted 'other' list into this sorted list, using
        // the specified binary 'comparator' predicate to order elements.  This
        // method has no effect if 'other' is this list; otherwise, 'other' is
        // left empty.  The behavior is undefined unless both 'other' and this
        // list are sorted in non-decreasing order according to the ordering
        // provided by 'comparator', and unless both 'other' and this list use
        // the same allocator.

    void remove(const value_type& value);
        // Erase all the elements having the specified 'value' from this list.

    template <class PREDICATE>
    void remove_if(PREDICATE predicate);
        // Remove and destroy all elements in this list for which the specified
        // unary 'predicate' returns 'true'.

    void reverse() BSLS_KEYWORD_NOEXCEPT;
        // Reverse the order of the elements in this list.

    void sort();
        // Sort this list in non-decreasing order according to the order
        // provided by 'operator<'.  'operator<' must provide a strict weak
        // ordering over 'value_type' (see {Comparators and Strict Weak
        // Ordering}).  The sort is stable, meaning that if
        // '!(a < b) && !(b < a)', then the ordering of elements 'a' and 'b' in
        // the sequence is preserved.

    template <class COMPARE>
    void sort(COMPARE comparator);
        // Sort this list in non-decreasing order according to the order
        // provided by the specified 'comparator' predicate.  'comparator' must
        // define a strict weak ordering over 'value_type' (see {Comparators
        // and Strict Weak Ordering}).  The sort is stable, meaning that if
        // '!comparator(a, b) && !comparator(b, a)', then the ordering of
        // elements 'a' and 'b' in the sequence is preserved.

    void splice(const_iterator                       dstPosition,
                list&                                src);
    void splice(const_iterator                       dstPosition,
                BloombergLP::bslmf::MovableRef<list> src);
        // Remove all elements of the specified 'src' list and insert them, in
        // the same order, in this list at the specified 'dstPosition'.  The
        // behavior is undefined unless 'src' is not this list, this list and
        // 'src' use the same allocator, and 'dstPosition' is in the range
        // '[begin() .. end()]' (note both endpoints included).

    void splice(const_iterator                       dstPosition,
                list&                                src,
                const_iterator                       srcNode);
    void splice(const_iterator                       dstPosition,
                BloombergLP::bslmf::MovableRef<list> src,
                const_iterator                       srcNode);
        // Remove the single element at the specified 'srcNode' from the
        // specified 'src' list, and insert it at the specified 'dstPosition'
        // in this list.  The behavior is undefined unless 'srcNode' refers to
        // a valid element in 'src', this list and 'src' use the same
        // allocator, and 'dstPosition' is in the range '[begin() .. end()]'
        // (note both endpoints included).  Note that 'src' and '*this' may be
        // the same list, in which case the element is moved to a (possibly)
        // new position in the list.

    void splice(const_iterator                       dstPosition,
                list&                                src,
                const_iterator                       first,
                const_iterator                       last);
    void splice(const_iterator                       dstPosition,
                BloombergLP::bslmf::MovableRef<list> src,
                const_iterator                       first,
                const_iterator                       last);
        // Remove the elements in the specified range '[first .. last)' from
        // the specified 'src' list, and insert them, in the same order, at the
        // specified 'dstPosition' in this list.  The behavior is undefined
        // unless '[first .. last)' represents a range of valid elements in
        // 'src', 'dstPosition' is not in the range '[first .. last)', this
        // list and 'src' use the same allocator, and 'dstPosition' is in the
        // range '[begin() .. end()]' (note both endpoints included).  Note
        // that 'src' and '*this' may be the same list, in which case an entire
        // sequence of nodes is moved to a (possibly) new position in this
        // list.

    void unique();
        // Erase from this list all but the first element of every consecutive
        // group of elements that have the same value.

    template <class EQ_PREDICATE>
    void unique(EQ_PREDICATE binaryPredicate);
        // Erase from this list all but the first element of every consecutive
        // group of elements for which the specified 'binaryPredicate' returns
        // 'true' for any two consecutive elements in the group.

                              // *** misc ***

    void swap(list& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(
                                          AllocTraits::is_always_equal::value);
        // Exchange the value of this object with that of the specified 'other'
        // object; also exchange the allocator of this object with that of
        // 'other' if the (template parameter) type 'ALLOCATOR' has the
        // 'propagate_on_container_swap' trait, and do not modify either
        // allocator otherwise.  This method provides the no-throw
        // exception-safety guarantee.  This operation has 'O[1]' complexity if
        // either this object was created with the same allocator as 'other' or
        // 'ALLOCATOR' has the 'propagate_on_container_swap' trait; otherwise,
        // it has 'O[n + m]' complexity, where 'n' and 'm' are the number of
        // elements in this object and 'other', respectively.  Note that this
        // method's support for swapping objects created with different
        // allocators when 'ALLOCATOR' does not have the
        // 'propagate_on_container_swap' trait is a departure from the
        // C++ Standard.

    // ACCESSORS

                               // *** iterators ***

    const_iterator begin() const BSLS_KEYWORD_NOEXCEPT;
    const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT;
        // Return an iterator providing non-modifiable access to the first
        // 'value_type' object in the ordered sequence of 'value_type' objects
        // maintained by this list, or the 'end' iterator if this list is
        // empty.

    const_iterator end() const BSLS_KEYWORD_NOEXCEPT;
    const_iterator cend() const BSLS_KEYWORD_NOEXCEPT;
        // Return the past-the-end (forward) iterator providing non-modifiable
        // access to this list.

    const_reverse_iterator rbegin() const BSLS_KEYWORD_NOEXCEPT;
    const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT;
        // Return a reverse iterator providing non-modifiable access to the
        // last element in this list, and the past-the-end reverse iterator if
        // this list is empty.

    const_reverse_iterator rend() const BSLS_KEYWORD_NOEXCEPT;
    const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT;
        // Return the past-the-end reverse iterator providing non-modifiable
        // access to this list.

                                  // *** size ***

    bool empty() const BSLS_KEYWORD_NOEXCEPT;
        // Return 'true' if this list has no elements, and 'false' otherwise.

    size_type max_size() const BSLS_KEYWORD_NOEXCEPT;
        // Return an upper bound on the largest number of elements that this
        // list could possibly hold.  Note that the return value of this
        // function does not guarantee that this list can successfully grow
        // that large, or even close to that large without running out of
        // resources.

    size_type size() const BSLS_KEYWORD_NOEXCEPT;
        // Return the number of elements in this list.

                           // *** element access ***

    const_reference back() const;
        // Return a reference providing non-modifiable access to the last
        // element of this list.  The behavior is undefined unless this list
        // contains at least one element.

    const_reference front() const;
        // Return a reference providing non-modifiable access to the first
        // element of this list.  The behavior is undefined unless this list
        // contains at least one element.

                                // *** misc ***

    allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT;
        // Return a copy of the allocator used for memory allocation by this
        // list.
};

#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
// CLASS TEMPLATE DEDUCTION GUIDES

template <
    class SIZE_TYPE,
    class VALUE,
    class ALLOC,
    class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
    class = bsl::enable_if_t<
                            bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>,
    class = bsl::enable_if_t<
              bsl::is_convertible_v<
                 SIZE_TYPE,
                 typename bsl::allocator_traits<DEFAULT_ALLOCATOR>::size_type>>
    >
list(SIZE_TYPE, VALUE, ALLOC *) -> list<VALUE>;
    // Deduce the template parameter 'VALUE' from the corresponding parameter
    // supplied to the constructor of 'list'.  This deduction guide does not
    // participate unless the supplied allocator is convertible to
    // 'bsl::allocator<VALUE>'.

template <
    class INPUT_ITERATOR,
    class VALUE = typename
                   BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>
    >
list(INPUT_ITERATOR, INPUT_ITERATOR) -> list<VALUE>;
    // Deduce the template parameter 'VALUE' from the 'value_type' of the
    // iterators supplied to the constructor of 'list'.

template<
    class INPUT_ITERATOR,
    class ALLOCATOR,
    class VALUE = typename
                  BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
    class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>>
list(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR) -> list<VALUE, ALLOCATOR>;
    // Deduce the template parameter 'VALUE' from the 'value_type' of the
    // iterators supplied to the constructor of 'list'.  Deduce the template
    // parameter 'ALLOCATOR' from the allocator supplied to the constructor of
    // 'list'.  This deduction guide does not participate unless the supplied
    // allocator meets the requirements of a standard allocator.

template<
    class INPUT_ITERATOR,
    class ALLOC,
    class VALUE = typename
                  BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
    class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
    class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
    >
list(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
-> list<VALUE>;
    // Deduce the template parameter 'VALUE' from the value_type of the
    // iterators supplied to the constructor of 'list'.  This deduction guide
    // does not participate unless the specified 'ALLOC' is convertible to
    // 'bsl::allocator<CHAR_TYPE>'.

template<
    class VALUE,
    class ALLOC,
    class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
    class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
    >
list(std::initializer_list<VALUE>, ALLOC *)
-> list<VALUE>;
    // Deduce the template parameter 'VALUE' from the value_type of the
    // intializer_list supplied to the constructor of 'list'.  This deduction
    // guide does not participate unless the specified 'ALLOC' is convertible
    // to 'bsl::allocator<CHAR_TYPE>'.
#endif

// FREE OPERATORS
template <class VALUE, class ALLOCATOR>
bool operator==(const list<VALUE, ALLOCATOR>& lhs,
                const list<VALUE, ALLOCATOR>& rhs);
    // Return 'true' if the specified 'lhs' and 'rhs' objects have the same
    // value, and 'false' otherwise.  Two 'list' objects 'lhs' and 'rhs' have
    // the same value if they have the same number of elements, and each
    // element in the ordered sequence of elements of 'lhs' has the same value
    // as the corresponding element in the ordered sequence of elements of
    // 'rhs'.  This method requires that the (template parameter) type 'VALUE'
    // be 'equality-comparable' (see {Requirements on 'VALUE'}).

template <class VALUE, class ALLOCATOR>
bool operator!=(const list<VALUE, ALLOCATOR>& lhs,
                const list<VALUE, ALLOCATOR>& rhs);


    // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the
    // same value, and 'false' otherwise.  Two 'list' objects 'lhs' and 'rhs'
    // do not have the same value if they do not have the same number of
    // elements, or some element in the ordered sequence of elements of 'lhs'
    // does not have the same value as the corresponding element in the ordered
    // sequence of elements of 'rhs'.  This method requires that the
    // (template parameter) type 'VALUE' be 'equality-comparable' (see
    // {Requirements on 'VALUE'}).

template <class VALUE, class ALLOCATOR>
bool operator< (const list<VALUE, ALLOCATOR>& lhs,
                const list<VALUE, ALLOCATOR>& rhs);
    // Return 'true' if the value of the specified 'lhs' list is
    // lexicographically less than that of the specified 'rhs' list, and
    // 'false' otherwise.  Given iterators 'i' and 'j' over the respective
    // sequences '[lhs.begin() .. lhs.end())' and '[rhs.begin() .. rhs.end())',
    // the value of list 'lhs' is lexicographically less than that of list
    // 'rhs' if 'true == *i < *j' for the first pair of corresponding iterator
    // positions where '*i < *j' and '*j < *i' are not both 'false'.  If no
    // such corresponding iterator position exists, the value of 'lhs' is
    // lexicographically less than that of 'rhs' if 'lhs.size() < rhs.size()'.
    // This method requires that 'operator<', inducing a total order, be
    // defined for 'value_type'.

template <class VALUE, class ALLOCATOR>
bool operator> (const list<VALUE, ALLOCATOR>& lhs,
                const list<VALUE, ALLOCATOR>& rhs);
    // Return 'true' if the value of the specified 'lhs' list is
    // lexicographically greater than that of the specified 'rhs' list, and
    // 'false' otherwise.  The value of list 'lhs' is lexicographically greater
    // than that of list 'rhs' if 'rhs' is lexicographically less than 'lhs'
    // (see 'operator<').  This method requires that 'operator<', inducing a
    // total order, be defined for 'value_type'.  Note that this operator
    // returns 'rhs < lhs'.

template <class VALUE, class ALLOCATOR>
bool operator<=(const list<VALUE, ALLOCATOR>& lhs,
                const list<VALUE, ALLOCATOR>& rhs);
    // Return 'true' if the value of the specified 'lhs' list is
    // lexicographically less than or equal to that of the specified 'rhs'
    // list, and 'false' otherwise.  The value of list 'lhs' is
    // lexicographically less than or equal to that of list 'rhs' if 'rhs' is
    // not lexicographically less than 'lhs' (see 'operator<').  This method
    // requires that 'operator<', inducing a total order, be defined for
    // 'value_type'.  Note that this operator returns '!(rhs < lhs)'.

template <class VALUE, class ALLOCATOR>
bool operator>=(const list<VALUE, ALLOCATOR>& lhs,
                const list<VALUE, ALLOCATOR>& rhs);
    // Return 'true' if the value of the specified 'lhs' list is
    // lexicographically greater than or equal to that of the specified 'rhs'
    // list, and 'false' otherwise.  The value of list 'lhs' is
    // lexicographically greater than or equal to that of list 'rhs' if 'lhs'
    // is not lexicographically less than 'rhs' (see 'operator<').  This method
    // requires that 'operator<', inducing a total order, be defined for
    // 'value_type'.  Note that this operator returns '!(lhs < rhs)'.

// FREE FUNCTIONS
template <class VALUE, class ALLOCATOR, class BDE_OTHER_TYPE>
typename list<VALUE, ALLOCATOR>::size_type
erase(list<VALUE, ALLOCATOR>& l, const BDE_OTHER_TYPE& value);
    // Erase all the elements in the specified list 'l' that compare equal to
    // the specified 'value'.  Return the number of elements erased.

template <class VALUE, class ALLOCATOR, class PREDICATE>
typename list<VALUE, ALLOCATOR>::size_type
erase_if(list<VALUE, ALLOCATOR>& l, PREDICATE predicate);
    // Erase all the elements in the specified list 'l' that satisfy the
    // specified predicate 'predicate'.  Return the number of elements erased.

template <class VALUE, class ALLOCATOR>
void swap(list<VALUE, ALLOCATOR>& a, list<VALUE, ALLOCATOR>& b)
    BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR(
                                                                   a.swap(b)));
    // Exchange the value of the specified 'a' object with that of the
    // specified 'b' object; also exchange the allocator of 'a' with that of
    // 'b' if the (template parameter) type 'ALLOCATOR' has the
    // 'propagate_on_container_swap' trait, and do not modify either allocator
    // otherwise.  This function provides the no-throw exception-safety
    // guarantee.  This operation has 'O[1]' complexity if either 'a' was
    // created with the same allocator as 'b' or 'ALLOCATOR' has the
    // 'propagate_on_container_swap' trait; otherwise, it has 'O[n + m]'
    // complexity, where 'n' and 'm' are the number of elements in 'a' and 'b',
    // respectively.  Note that this function's support for swapping objects
    // created with different allocators when 'ALLOCATOR' does not have the
    // 'propagate_on_container_swap' trait is a departure from the C++
    // Standard.

// ============================================================================
//                   INLINE AND TEMPLATE FUNCTION DEFINITIONS
// ============================================================================

                           // ------------------------
                           // class bsl::List_Iterator
                           // ------------------------

// PRIVATE ACCESSORS
template <class VALUE>
inline
typename List_Iterator<VALUE>::NcIter List_Iterator<VALUE>::unconst() const
{
    return NcIter(d_node_p);
}

// CREATORS
template <class VALUE>
inline
List_Iterator<VALUE>::List_Iterator()
: d_node_p()
{
}

template <class VALUE>
inline
List_Iterator<VALUE>::List_Iterator(Node *nodePtr)
: d_node_p(nodePtr)
{
}

template <class VALUE>
inline
List_Iterator<VALUE>::List_Iterator(const NcIter& other)
: d_node_p(other.d_node_p)
{
}

// MANIPULATORS
template <class VALUE>
inline
List_Iterator<VALUE>& List_Iterator<VALUE>::operator++()
{
    this->d_node_p = this->d_node_p->d_next_p;
    return *this;
}

template <class VALUE>
inline
List_Iterator<VALUE>& List_Iterator<VALUE>::operator--()
{
    this->d_node_p = this->d_node_p->d_prev_p;
    return *this;
}

template <class VALUE>
inline
List_Iterator<VALUE> List_Iterator<VALUE>::operator++(int)
{
    List_Iterator temp = *this;
    this->operator++();
    return temp;
}

template <class VALUE>
inline
List_Iterator<VALUE> List_Iterator<VALUE>::operator--(int)
{
    List_Iterator temp = *this;
    this->operator--();
    return temp;
}

// ACCESSORS
template <class VALUE>
inline
typename bsl::List_Iterator<VALUE>::reference
                                        List_Iterator<VALUE>::operator*() const
{
    return this->d_node_p->d_value;
}

template <class VALUE>
inline
typename bsl::List_Iterator<VALUE>::pointer
                                       List_Iterator<VALUE>::operator->() const
{
    return BloombergLP::bsls::Util::addressOf(this->d_node_p->d_value);
}

// FREE OPERATORS
template <class T1, class T2>
inline
bool operator==(bsl::List_Iterator<T1> lhs, bsl::List_Iterator<T2> rhs)
{
    // Make sure that this comparison will only compile if 'T1' and 'T2' match
    // except for a possible difference in 'const'-ness.

    BSLMF_ASSERT((bsl::is_same<typename bsl::remove_cv<T1>::type,
                               typename bsl::remove_cv<T2>::type>::value));

    return lhs.d_node_p == rhs.d_node_p;
}

template <class T1, class T2>
inline
bool operator!=(bsl::List_Iterator<T1> lhs, bsl::List_Iterator<T2> rhs)
{
    // Make sure that this comparison will only compile if 'T1' and 'T2' match
    // except for a possible difference in 'const'-ness.

    BSLMF_ASSERT((bsl::is_same<typename bsl::remove_cv<T1>::type,
                               typename bsl::remove_cv<T2>::type>::value));

    return ! (lhs == rhs);
}

                          // ------------------------------
                          // class List_AllocAndSizeWrapper
                          // ------------------------------

// CREATOR
template <class VALUE, class ALLOCATOR>
inline
List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::List_AllocAndSizeWrapper(
                                               const NodeAlloc& basicAllocator,
                                               size_type        size)
: NodeAlloc(basicAllocator)
, d_size(size)
{
}

// MANIPULATORS
template <class VALUE, class ALLOCATOR>
inline
typename List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::size_type&
List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::size()
{
    return d_size;
}

// ACCESSORS
template <class VALUE, class ALLOCATOR>
inline
const typename List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::size_type&
List_AllocAndSizeWrapper<VALUE, ALLOCATOR>::size() const
{
    return d_size;
}

                          // ----------------------
                          // class List_NodeProctor
                          // ----------------------

// CREATORS
template <class VALUE, class ALLOCATOR>
inline
List_NodeProctor<VALUE, ALLOCATOR>::List_NodeProctor(
                                               list<VALUE, ALLOCATOR> *listPtr,
                                               NodePtr                 nodePtr)
: d_list_p(listPtr)
, d_node_p(nodePtr)
{
    BSLS_ASSERT_SAFE(listPtr);
    BSLS_ASSERT_SAFE(nodePtr);
}

template <class VALUE, class ALLOCATOR>
inline
List_NodeProctor<VALUE, ALLOCATOR>::~List_NodeProctor()
{
    if (d_node_p) {
        d_list_p->freeNode(d_node_p);
    }
}

// MANIPULATORS
template <class VALUE, class ALLOCATOR>
inline
void List_NodeProctor<VALUE, ALLOCATOR>::release()
{
    d_node_p = 0;
}

                        // --------------------------
                        // class List_DefaultLessThan
                        // --------------------------

// ACCESSORS
template <class VALUE>
inline
bool List_DefaultLessThan<VALUE>::operator()(
                                      const VALUE& lhs, const VALUE& rhs) const
{
    return lhs < rhs;
}

                                // ---------------
                                // class bsl::list
                                // ---------------

// PRIVATE MANIPULATORS
template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::NodeAlloc&
                                         list<VALUE, ALLOCATOR>::allocatorImp()
{
    return d_alloc_and_size;  // implicit cast to base class
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::NodePtr list<VALUE, ALLOCATOR>::allocateNode()
{
    NodePtr ret = AllocTraits::allocate(allocatorImp(), 1);
    ret->d_prev_p = 0;
    ret->d_next_p = 0;
    return ret;
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::createSentinel()
{
    BSLS_ASSERT_SAFE(size_type(-1) == sizeRef() || 0 == sizeRef());

    d_sentinel = allocateNode();
    linkNodes(d_sentinel, d_sentinel);  // circular
    sizeRef() = 0;
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::deleteNode(NodePtr node)
{
    BSLS_ASSERT_SAFE(node);

    AllocTraits::destroy(allocatorImp(),
                         BloombergLP::bsls::Util::addressOf(node->d_value));
    AllocTraits::deallocate(allocatorImp(), node, 1);
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::destroyAll()
{
    clear();
    freeNode(d_sentinel);
    sizeRef() = size_type(-1);
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::freeNode(NodePtr node)
{
    AllocTraits::deallocate(allocatorImp(), node, 1);
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::insertNode(const_iterator position, NodePtr node)
{
    NodePtr next = position.d_node_p;
    NodePtr prev = next->d_prev_p;
    linkNodes(prev, node);
    linkNodes(node, next);
    ++sizeRef();
    return iterator(node);
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::linkNodes(NodePtr prev, NodePtr next)
{
    prev->d_next_p = next;
    next->d_prev_p = prev;
}

template <class VALUE, class ALLOCATOR>
template <class COMPARE>
typename list<VALUE, ALLOCATOR>::NodePtr
list<VALUE, ALLOCATOR>::mergeImp(NodePtr node1,
                                 NodePtr node2,
                                 NodePtr finish,
                                 COMPARE comparator)
{
    NodePtr pre = node1->d_prev_p;

    // The only possible throwing operation is the comparator.  Exception
    // neutrality is achieved by ensuring that this list is in a valid state,
    // with no disconnected nodes, before the comparator is called.

    // Having the two sublists be contiguous parts of the same list has the
    // following advantages:
    //: 1 When we reach the end of a sublist, there is no "finalization" step
    //:   where the end of the remaining sublist must be spliced onto the
    //:   merged list.
    //: 2 No cleanup needed if an exception is thrown; the size and validity of
    //:   the resulting list needs no adjustment.

    while (node1 != node2 && node2 != finish) {
        // Loop invariants:
        // - The open range (pre, node1) is the current merged result
        // - The half-open range [node1, node2) is the 1st unmerged sequence
        // - The half-open range [node2, finish) is the 2nd unmerged sequence

        if (comparator(node2->d_value, node1->d_value)) {
            // 'node2' should come before 'node1'.

            // Find the end of the sequence of elements that belong before
            // node1 so that we can splice them all at once.

            NodePtr lastMove = node2;
            NodePtr next2    = node2->d_next_p;
            while (next2 != finish && comparator(next2->d_value,
                                                 node1->d_value)) {
                lastMove = next2;
                next2 = lastMove->d_next_p;
            }

            linkNodes(node2->d_prev_p, next2);
            linkNodes(node1->d_prev_p, node2);
            linkNodes(lastMove, node1);

            // Advance to next node in the 2nd unmerged sequence.

            node2 = next2;
        }
        else {
            // Advance to next node in the 1st unmerged sequence.

            node1 = node1->d_next_p;
        }
    }

    return pre->d_next_p;
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::quickSwap(list *other)
{
    BSLS_ASSERT_SAFE(allocatorImp() == other->allocatorImp());

    using std::swap;

    swap(d_sentinel, other->d_sentinel);
    swap(sizeRef(),  other->sizeRef());
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::AllocTraits::size_type&
list<VALUE, ALLOCATOR>::sizeRef() BSLS_KEYWORD_NOEXCEPT
{
    return d_alloc_and_size.size();
}

template <class VALUE, class ALLOCATOR>
template <class COMPARE>
typename list<VALUE, ALLOCATOR>::NodePtr
list<VALUE, ALLOCATOR>::sortImp(NodePtr        *nodePtrPtr,
                                size_type       size,
                                const COMPARE&  comparator)
{
    BSLS_ASSERT(size > 0);

    NodePtr node1 = *nodePtrPtr;
    if (size < 2) {
        return node1->d_next_p;                                       // RETURN
    }

    size_type half = size / 2;

    NodePtr node2 = sortImp(&node1, half,        comparator);
    NodePtr next  = sortImp(&node2, size - half, comparator);

    *nodePtrPtr = mergeImp(node1, node2, next, comparator);
    return next;
}

// PRIVATE ACCESSORS
template <class VALUE, class ALLOCATOR>
inline
const typename list<VALUE, ALLOCATOR>::NodeAlloc&
                                   list<VALUE, ALLOCATOR>::allocatorImp() const
{
    return d_alloc_and_size;  // implicit cast to base class
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::NodePtr list<VALUE, ALLOCATOR>::headNode()
                                                                          const
{
    return d_sentinel->d_next_p;
}

template <class VALUE, class ALLOCATOR>
inline
const typename list<VALUE, ALLOCATOR>::AllocTraits::size_type&
list<VALUE, ALLOCATOR>::sizeRef() const BSLS_KEYWORD_NOEXCEPT
{
    return d_alloc_and_size.size();
}

// CREATORS
template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>::list()
: d_sentinel()
, d_alloc_and_size(ALLOCATOR(), 0)
{
    BSLMF_ASSERT((bsl::is_same<size_type,
                                     typename AllocTraits::size_type>::value));
    BSLMF_ASSERT((bsl::is_same<difference_type,
                               typename AllocTraits::difference_type>::value));
    createSentinel();
}

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>::list(const ALLOCATOR& basicAllocator)
: d_sentinel()
, d_alloc_and_size(basicAllocator, 0)
{
    createSentinel();
}

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>::list(size_type numElements)
: d_sentinel()
, d_alloc_and_size(ALLOCATOR(), size_type(-1))
{
    // '*this' is in an invalid but destructible state (size == -1).

    list tmp(this->allocatorImp());

    // Default-construct (value-initialize) 'n' elements into 'tmp'.  'tmp's
    // destructor will clean up if an exception is thrown.

    iterator pos = tmp.end();
    for (size_type i = 0; i < numElements; ++i) {
        tmp.emplace(pos);
    }

    quickSwap(&tmp);  // Leave 'tmp' in an invalid but destructible state.
}

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>::list(size_type        numElements,
                             const ALLOCATOR& basicAllocator)
: d_sentinel()
, d_alloc_and_size(basicAllocator, size_type(-1))
{
    // '*this' is in an invalid but destructible state (size == -1).

    list tmp(this->allocatorImp());

    // Default-construct (value-initialize) 'n' elements into 'tmp'.  'tmp's
    // destructor will clean up if an exception is thrown.

    const_iterator pos = tmp.cend();
    for (size_type i = 0; i < numElements; ++i) {
        tmp.emplace(pos);
    }

    quickSwap(&tmp);  // Leave 'tmp' in an invalid but destructible state.
}

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>::list(size_type        numElements,
                             const VALUE&     value,
                             const ALLOCATOR& basicAllocator)
: d_sentinel()
, d_alloc_and_size(basicAllocator, size_type(-1))
{
    // '*this' is in an invalid but destructible state (size == -1).

    list tmp(this->allocatorImp());
    tmp.insert(tmp.cbegin(), numElements, value);    // 'tmp's destructor will
                                                     // clean up on throw.
    quickSwap(&tmp);      // Leave 'tmp' in an invalid but destructible state.
}

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>::list(const list& original)
: d_sentinel()
, d_alloc_and_size(
   AllocTraits::select_on_container_copy_construction(original.allocatorImp()),
   size_type(-1))
{
    list tmp(this->allocatorImp());

    tmp.insert(tmp.cbegin(), original.begin(), original.end());

    quickSwap(&tmp);  // Leave 'tmp' in an invalid but destructible state.
}

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>::list(const list&                        original,
                 const typename type_identity<ALLOCATOR>::type& basicAllocator)
: d_sentinel()
, d_alloc_and_size(basicAllocator, size_type(-1))
{
    list tmp(this->allocatorImp());

    tmp.insert(tmp.cbegin(), original.begin(), original.end());

    quickSwap(&tmp);  // Leave 'tmp' in an invalid but destructible state.
}

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>::list(BloombergLP::bslmf::MovableRef<list> original)
: d_sentinel()
, d_alloc_and_size(MoveUtil::access(original).allocatorImp(), 0)
{
    // Allocator should be copied, not moved, to ensure identical allocators
    // between this and 'original', otherwise 'swap' is undefined.

    // An rvalue must be left in a valid state after a move.

    createSentinel();

    // '*this' is now in a valid state.

    quickSwap(&MoveUtil::access(original));
}

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>::list(
                 BloombergLP::bslmf::MovableRef<list>           original,
                 const typename type_identity<ALLOCATOR>::type& basicAllocator)
: d_sentinel()
, d_alloc_and_size(basicAllocator, size_type(-1))
{
    // '*this' is in an invalid but destructible state (size == -1).

    list& lvalue = original;
    if (this->allocatorImp() == lvalue.allocatorImp()) {
        // An rvalue must be left in a valid state after a move.

        createSentinel();      // '*this' is now in a valid state.
        quickSwap(&lvalue);
    }
    else {
        // different allocators, must copy

        list tmp(this->allocatorImp());

        // Avoid relying on VALUE's copy c'tor unless no move c'tor is
        // available.

        NodePtr endPtr = lvalue.d_sentinel;
        for (NodePtr p = lvalue.headNode(); endPtr != p;  p = p->d_next_p) {
            tmp.emplace_back(MoveUtil::move(p->d_value));
        }

        quickSwap(&tmp);  // Leave 'tmp' in an invalid but destructible state.
    }
}

#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
template <class VALUE, class ALLOCATOR>
inline
list<VALUE, ALLOCATOR>::list(std::initializer_list<VALUE> values,
                             const ALLOCATOR&             basicAllocator)
: d_alloc_and_size(basicAllocator, size_type(-1))
{
    // '*this' is in an invalid but destructible state (size == -1).  Create a
    // temporary list, 'tmp', with the specified data.  If an exception is
    // thrown, 'tmp's destructor will clean up.  Otherwise, swap 'tmp' with
    // '*this', leaving 'tmp' in an invalid but destructible state and leaving
    // '*this' fully constructed.

    list tmp(this->allocatorImp());
    tmp.insert(tmp.cbegin(), values.begin(), values.end());

    quickSwap(&tmp);
}
#endif

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>::~list()
{
    // A size of -1 means a special incompletely-initialized state with no
    // sentinel, which requires no destruction.

    if (sizeRef() != size_type(-1)) {
        destroyAll();
    }
}

// MANIPULATORS

                            // *** assignment ***

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>& list<VALUE, ALLOCATOR>::operator=(const list& rhs)
{
    if (this == &rhs) {
        return *this;                                                 // RETURN
    }

    if (AllocTraits::propagate_on_container_copy_assignment::value
       && allocatorImp() != rhs.allocatorImp()) {
        // We can't simply swap containers, as we aren't allowed to modify
        // 'rhs'.

        // Completely destroy and rebuild list using new allocator.

        // Create a new list with the new allocator.  This operation might
        // throw, so we do it before destroying the old list.

        list tmp(rhs, rhs.allocatorImp());

        // Clear existing list and leave in an invalid but destructible state.

        destroyAll();

        // Assign allocator (here we are relying on the C++11 standard, which
        // requires that the allocator type not throw on copy or assign) as
        // 'quickSwap' requires the entities to have the same allocator.

        allocatorImp() = rhs.allocatorImp();

        // Now swap lists, leaving 'tmp' in an invalid but destructible state.

        quickSwap(&tmp);
    }
    else {
        assign(rhs.begin(), rhs.end());
    }

    return *this;
}

template <class VALUE, class ALLOCATOR>
list<VALUE, ALLOCATOR>& list<VALUE, ALLOCATOR>::operator=(
                                      BloombergLP::bslmf::MovableRef<list> rhs)
    BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocTraits::is_always_equal::value)
{
    list& lvalue = rhs;

    if (this == &lvalue) {
        return *this;                                                 // RETURN
    }

    if (this->allocatorImp() == lvalue.allocatorImp()) {
        // Equal allocators, just swap contents, will never throw.

        quickSwap(&lvalue);
    }
    else if (AllocTraits::propagate_on_container_move_assignment::value) {
        // An rvalue must be left in a valid state after a move.  Both '*this'
        // and 'rhs' must be left in valid states after a throw.

        // Note: tearing everything down, then changing the allocator, then
        // doing 'quickSwap(&lvalue)' has a problem in that it could leave
        // 'rhs' in an invalid state, since if 'this->createSentinel()' were
        // called after the tearing down to render '*this' to a valid value,
        // 'createSentinel' might throw, leaving '*this' in an invalid state.

        // Swap everything, including the allocator (here we are relying on the
        // C++11 standard, which requires that the allocator type not throw on
        // copy or assign).

        list other(MoveUtil::move(lvalue));

        using std::swap;

        swap(allocatorImp(), other.allocatorImp()); // won't throw
        swap(d_sentinel,     other.d_sentinel);     // swap of pointer type
        swap(sizeRef(),      other.sizeRef());      // swap of fundamental type
    }
    else {
        // Unequal allocators and the allocator of the destination is to remain
        // unchanged.  Copy using 'move', which will use copy functions where
        // 'value_type' doesn't support moving.  Note that if this throws part
        // way through, both '*this' and 'rhs' may be left changed.

        NodePtr              dstPtr    = this->headNode();
        const const_iterator dstEnd    = this->cend();
        const NodePtr        dstEndPtr = dstEnd.d_node_p;

        NodePtr              srcPtr    = lvalue.headNode();
        const NodePtr        srcEndPtr = lvalue.d_sentinel;

        for (; srcEndPtr != srcPtr && dstEndPtr != dstPtr;
                        srcPtr = srcPtr->d_next_p, dstPtr = dstPtr->d_next_p) {
            dstPtr->d_value = MoveUtil::move(srcPtr->d_value);
        }

        erase(const_iterator(dstPtr), dstEnd);

        for (; srcEndPtr != srcPtr; srcPtr = srcPtr->d_next_p) {
            emplace(dstEnd, MoveUtil::move(srcPtr->d_value));
        }
    }

    return *this;
}

#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
template <class VALUE, class ALLOCATOR>
inline
list<VALUE, ALLOCATOR>& list<VALUE, ALLOCATOR>::operator=(
                                              std::initializer_list<VALUE> rhs)
{
    assign(rhs.begin(), rhs.end());
    return *this;
}
#endif

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::assign(size_type numElements, const VALUE& value)
{
    NodePtr              dst_p    = this->headNode();
    const const_iterator dstEnd   = this->cend();
    const NodePtr        dstEnd_p = dstEnd.d_node_p;

    for (; 0 < numElements && dstEnd_p != dst_p;
                                      --numElements, dst_p = dst_p->d_next_p) {
        dst_p->d_value = value;
    }

    erase(const_iterator(dst_p), dstEnd);

    for (; 0 < numElements; --numElements) {
        insert(dstEnd, value);
    }
}

#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::assign(std::initializer_list<VALUE> values)
{
    assign(values.begin(), values.end());
}
#endif

                              // *** iterators ***

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::iterator list<VALUE, ALLOCATOR>::begin()
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return iterator(headNode());
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::iterator list<VALUE, ALLOCATOR>::end()
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return iterator(d_sentinel);
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::reverse_iterator
list<VALUE, ALLOCATOR>::rbegin() BSLS_KEYWORD_NOEXCEPT
{
    return reverse_iterator(end());
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::reverse_iterator
list<VALUE, ALLOCATOR>::rend() BSLS_KEYWORD_NOEXCEPT
{
    return reverse_iterator(begin());
}

                            // *** modify size ***

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::clear() BSLS_KEYWORD_NOEXCEPT
{
    const NodePtr e = d_sentinel;
    for (NodePtr p = d_sentinel->d_next_p; e != p; ) {
        NodePtr condemned = p;
        p = p->d_next_p;
        deleteNode(condemned);
    }

    linkNodes(d_sentinel, d_sentinel);
    sizeRef() = 0;
}

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::resize(size_type newSize)
{
    if (newSize > sizeRef()) {
        const_iterator ce = cend();
        do {
            emplace(ce);
        } while (newSize > sizeRef());
    }
    else {
        NodePtr e = d_sentinel;
        NodePtr p = e->d_prev_p;
        for (size_type d = sizeRef() - newSize; d > 0; --d) {
            NodePtr condemned = p;
            p = p->d_prev_p;
            deleteNode(condemned);
        }
        linkNodes(p, e);
        sizeRef() = newSize;
    }
}

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::resize(size_type newSize, const VALUE& value)
{
    if (newSize > sizeRef()) {
        const_iterator ce = cend();
        do {
            emplace(ce, value);
        } while (newSize > sizeRef());
    }
    else {
        NodePtr e = d_sentinel;
        NodePtr p = e->d_prev_p;
        for (size_type d = sizeRef() - newSize; d > 0; --d) {
            NodePtr condemned = p;
            p = p->d_prev_p;
            deleteNode(condemned);
        }
        linkNodes(p, e);
        sizeRef() = newSize;
    }
}

                                // element access:

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::back()
{
    BSLS_ASSERT_SAFE(sizeRef() > 0);

    return d_sentinel->d_prev_p->d_value;
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::front()
{
    BSLS_ASSERT_SAFE(sizeRef() > 0);

    return headNode()->d_value;
}

                                // *** end erase ***

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::pop_back()
{
    BSLS_ASSERT_SAFE(sizeRef() > 0);

    erase(--cend());
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::pop_front()
{
    BSLS_ASSERT_SAFE(sizeRef() > 0);

    erase(cbegin());
}

                         // *** random access erase ***

template <class VALUE, class ALLOCATOR>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::erase(const_iterator position)
{
    BSLS_ASSERT(position.d_node_p != d_sentinel);

    NodePtr  condemned = position.d_node_p;
    iterator ret(condemned->d_next_p);

    linkNodes(condemned->d_prev_p, condemned->d_next_p);
    deleteNode(condemned);
    --sizeRef();
    return ret;
}

template <class VALUE, class ALLOCATOR>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::erase(const_iterator dstBegin, const_iterator dstEnd)
{
    NodePtr       p = dstBegin.d_node_p;
    const NodePtr e = dstEnd.  d_node_p;

    linkNodes(p->d_prev_p, e);

    size_type numDeleted = 0;
    for (; e != p; ++numDeleted) {
        NodePtr condemned = p;
        p = p->d_next_p;
        deleteNode(condemned);
    }

    sizeRef() -= numDeleted;

    return iterator(e);
}

                            // *** end inserts ***

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_list.h
#ifndef BSLSTL_LIST_VARIADIC_LIMIT
#define BSLSTL_LIST_VARIADIC_LIMIT 10
#endif
#ifndef BSLSTL_LIST_VARIADIC_LIMIT_D
#define BSLSTL_LIST_VARIADIC_LIMIT_D BSLSTL_LIST_VARIADIC_LIMIT
#endif
#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 0
template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                          )
{
    emplace(cend());
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 0

#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 1
template <class VALUE, class ALLOCATOR>
template <class ARGS_01>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01));
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 1

#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 2
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02));
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 2

#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 3
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03));
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 3

#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 4
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04));
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 4

#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 5
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05));
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 5

#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 6
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06));
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 6

#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 7
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07));
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 7

#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 8
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08));
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 8

#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 9
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09));
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 9

#if BSLSTL_LIST_VARIADIC_LIMIT_D >= 10
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09,
          class ARGS_10>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09),
                    BSLS_COMPILERFEATURES_FORWARD(ARGS_10, arguments_10));
    return back();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_D >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
template <class VALUE, class ALLOCATOR>
template <class... ARGS>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_back(
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments)
{
    emplace(cend(), BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
    return back();
}
// }}} END GENERATED CODE
#endif

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_list.h
#ifndef BSLSTL_LIST_VARIADIC_LIMIT
#define BSLSTL_LIST_VARIADIC_LIMIT 10
#endif
#ifndef BSLSTL_LIST_VARIADIC_LIMIT_E
#define BSLSTL_LIST_VARIADIC_LIMIT_E BSLSTL_LIST_VARIADIC_LIMIT
#endif
#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 0
template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                          )
{
    emplace(cbegin());
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 0

#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 1
template <class VALUE, class ALLOCATOR>
template <class ARGS_01>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01));
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 1

#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 2
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02));
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 2

#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 3
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03));
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 3

#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 4
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04));
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 4

#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 5
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05));
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 5

#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 6
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06));
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 6

#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 7
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07));
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 7

#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 8
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08));
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 8

#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 9
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09));
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 9

#if BSLSTL_LIST_VARIADIC_LIMIT_E >= 10
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09,
          class ARGS_10>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09),
                      BSLS_COMPILERFEATURES_FORWARD(ARGS_10, arguments_10));
    return front();
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_E >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
template <class VALUE, class ALLOCATOR>
template <class... ARGS>
inline
typename list<VALUE, ALLOCATOR>::reference
list<VALUE, ALLOCATOR>::emplace_front(
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments)
{
    emplace(cbegin(), BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
    return front();
}
// }}} END GENERATED CODE
#endif

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::push_back(const VALUE& value)
{
    emplace(cend(), value);
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::push_back(
                                   BloombergLP::bslmf::MovableRef<VALUE> value)
{
    emplace(cend(), MoveUtil::move(value));
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::push_front(const VALUE& value)
{
    emplace(cbegin(), value);
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::push_front(
                                   BloombergLP::bslmf::MovableRef<VALUE> value)
{
    emplace(cbegin(), MoveUtil::move(value));
}

                       // *** random access inserts ***

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_list.h
#ifndef BSLSTL_LIST_VARIADIC_LIMIT
#define BSLSTL_LIST_VARIADIC_LIMIT 10
#endif
#ifndef BSLSTL_LIST_VARIADIC_LIMIT_F
#define BSLSTL_LIST_VARIADIC_LIMIT_F BSLSTL_LIST_VARIADIC_LIMIT
#endif
#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 0
template <class VALUE, class ALLOCATOR>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 0

#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 1
template <class VALUE, class ALLOCATOR>
template <class ARGS_01>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 1

#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 2
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 2

#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 3
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 3

#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 4
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 4

#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 5
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 5

#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 6
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 6

#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 7
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 7

#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 8
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 8

#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 9
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 9

#if BSLSTL_LIST_VARIADIC_LIMIT_F >= 10
template <class VALUE, class ALLOCATOR>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09,
          class ARGS_10>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09),
                         BSLS_COMPILERFEATURES_FORWARD(ARGS_10, arguments_10));
    proctor.release();
    return insertNode(position, p);
}
#endif  // BSLSTL_LIST_VARIADIC_LIMIT_F >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
template <class VALUE, class ALLOCATOR>
template <class... ARGS>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::emplace(const_iterator position,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments)
{
    NodePtr p = allocateNode();
    NodeProctor proctor(this, p);
    AllocTraits::construct(allocatorImp(),
                           BloombergLP::bsls::Util::addressOf(p->d_value),
                           BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
    proctor.release();
    return insertNode(position, p);
}
// }}} END GENERATED CODE
#endif

template <class VALUE, class ALLOCATOR>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::insert(const_iterator dstPosition, const VALUE& value)
{
    return emplace(dstPosition, value);
}

template <class VALUE, class ALLOCATOR>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::insert(
                             const_iterator                        dstPosition,
                             BloombergLP::bslmf::MovableRef<VALUE> value)
{
    return emplace(dstPosition, MoveUtil::move(value));
}

template <class VALUE, class ALLOCATOR>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::insert(const_iterator dstPosition,
                               size_type      numElements,
                               const VALUE&   value)
{
    if (0 == numElements) {
        return dstPosition.unconst();                                 // RETURN
    }

    // Remember the position of the first node inserted before 'dstPosition'.

    iterator ret = emplace(dstPosition, value);

    // And put the rest of the nodes after it.

    for (--numElements; numElements > 0; --numElements) {
        emplace(dstPosition, value);
    }

    return ret;
}

#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
template <class VALUE, class ALLOCATOR>
typename list<VALUE, ALLOCATOR>::iterator
list<VALUE, ALLOCATOR>::insert(const_iterator               dstPosition,
                               std::initializer_list<VALUE> values)
{
    return insert(dstPosition, values.begin(), values.end());
}
#endif

                          // *** list operations ***

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::merge(list& other)
{
    BSLS_ASSERT_SAFE(this->allocatorImp() == other.allocatorImp());

    merge(other, DefaultLessThan());
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::merge(BloombergLP::bslmf::MovableRef<list> other)
{
    list& lvalue = other;

    BSLS_ASSERT_SAFE(this->allocatorImp() == lvalue.allocatorImp());

    merge(lvalue, DefaultLessThan());
}

template <class VALUE, class ALLOCATOR>
template <class COMPARE>
void list<VALUE, ALLOCATOR>::merge(list& other, COMPARE comparator)
{
    if (&other == this) {
        return;                                                       // RETURN
    }

    BSLS_ASSERT(this->allocatorImp() == other.allocatorImp());

    if (other.empty()) {
        // This is an important special case to avoid pointing to sentinel.

        return;                                                       // RETURN
    }

    // Splice 'other' to the end of '*this', but remember the first node of the
    // appended sequence.

    NodePtr xfirst = other.d_sentinel->d_next_p;
    splice(end(), other);

    // Call 'mergeImp' with a pointer to the first node of the original list, a
    // pointer to the first node of 'other' (which also ends the original
    // list), and a pointer to the sentinel (which now ends 'other').

    mergeImp(d_sentinel->d_next_p, xfirst, d_sentinel, comparator);
}

template <class VALUE, class ALLOCATOR>
template <class COMPARE>
inline
void list<VALUE, ALLOCATOR>::merge(
                               BloombergLP::bslmf::MovableRef<list> other,
                               COMPARE                              comparator)
{
    list& lvalue = other;

    BSLS_ASSERT_SAFE(this->allocatorImp() == lvalue.allocatorImp());

    merge(lvalue, comparator);
}

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::remove(const VALUE& value)
{
    const const_iterator e = cend();
    for (const_iterator i = cbegin(); e != i; ) {
        // Standard says to use 'operator==', not 'std::equal_to'.

        if (value == *i) {
            i = erase(i);
        }
        else {
            ++i;
        }
    }
}

template <class VALUE, class ALLOCATOR>
template <class PREDICATE>
void list<VALUE, ALLOCATOR>::remove_if(PREDICATE predicate)
{
    const iterator e = end();
    for (iterator i = begin(); e != i; ) {
        if (predicate(*i)) {
            i = erase(i);
        }
        else {
            ++i;
        }
    }
}

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::reverse() BSLS_KEYWORD_NOEXCEPT
{
    NodePtr sentinel = d_sentinel;
    NodePtr p = sentinel;

    do {
        NodePtr tmp = p->d_next_p;
        p->d_next_p = p->d_prev_p;
        p->d_prev_p = tmp;
        p = tmp;
    } while (p != sentinel);
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::sort()
{
    sort(DefaultLessThan());
}

template <class VALUE, class ALLOCATOR>
template <class COMPARE>
void list<VALUE, ALLOCATOR>::sort(COMPARE comparator)
{
    if (sizeRef() < 2) {
        return;                                                       // RETURN
    }
    NodePtr node1 = d_sentinel->d_next_p;
    sortImp(&node1, size(), comparator);
}

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::splice(const_iterator dstPosition, list& src)
{
    BSLS_ASSERT(allocatorImp() == src.allocatorImp());
    BSLS_ASSERT(&src != this);

    if (src.empty()) {
        return;                                                       // RETURN
    }

    NodePtr   pPos   = dstPosition.d_node_p;
    NodePtr   pFirst = src.headNode();
    NodePtr   pLast  = src.d_sentinel->d_prev_p;
    size_type n      = src.sizeRef();

    // Splice contents out of 'src'.

    linkNodes(src.d_sentinel, src.d_sentinel);
    src.sizeRef() = 0;

    // Splice contents into '*this'.

    linkNodes(pPos->d_prev_p, pFirst);
    linkNodes(pLast,          pPos);
    sizeRef() += n;
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::splice(
                              const_iterator                       dstPosition,
                              BloombergLP::bslmf::MovableRef<list> src)
{
    splice(dstPosition, MoveUtil::access(src));
}

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::splice(const_iterator dstPosition,
                                    list&          src,
                                    const_iterator srcNode)
{
    BSLS_ASSERT(allocatorImp() == src.allocatorImp());

    NodePtr pPos          = dstPosition.d_node_p;
    NodePtr pSrcNode      = srcNode.d_node_p;
    NodePtr pAfterSrcNode = pSrcNode->d_next_p;

    if (pPos == pSrcNode || pPos == pAfterSrcNode) {
        return;                                                       // RETURN
    }

    // Splice contents out of 'src'.

    linkNodes(pSrcNode->d_prev_p, pAfterSrcNode);
    --src.sizeRef();

    // Splice contents into '*this'.

    linkNodes(pPos->d_prev_p, pSrcNode);
    linkNodes(pSrcNode,       pPos);
    ++sizeRef();
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::splice(
                              const_iterator                       dstPosition,
                              BloombergLP::bslmf::MovableRef<list> src,
                              const_iterator                       srcNode)
{
    splice(dstPosition, MoveUtil::access(src), srcNode);
}

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::splice(const_iterator dstPosition,
                                    list&          src,
                                    const_iterator first,
                                    const_iterator last)
{
    BSLS_ASSERT(allocatorImp() == src.allocatorImp());

    size_type n = bsl::distance(first, last);

    if (0 == n) {
        return;                                                       // RETURN
    }

    NodePtr pPos     = dstPosition.d_node_p;
    NodePtr pFirst   = first.d_node_p;
    NodePtr pLast    = last.d_node_p;
    NodePtr pSrcLast = pLast->d_prev_p;

    // Splice contents out of 'src'.

    linkNodes(pFirst->d_prev_p, pLast);
    src.sizeRef() -= n;

    // Splice contents into '*this'.

    linkNodes(pPos->d_prev_p, pFirst);
    linkNodes(pSrcLast,       pPos);
    sizeRef() += n;
}

template <class VALUE, class ALLOCATOR>
inline
void list<VALUE, ALLOCATOR>::splice(
                              const_iterator                       dstPosition,
                              BloombergLP::bslmf::MovableRef<list> src,
                              const_iterator                       first,
                              const_iterator                       last)
{
    splice(dstPosition, MoveUtil::access(src), first, last);
}

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::unique()
{
    if (size() < 2) {
        return;                                                       // RETURN
    }

    iterator i = begin();
    iterator e = end();
    while (i != e) {
        reference match = *i++;
        while (i != e && *i == match) {
            i = erase(i);
        }
    }
}

template <class VALUE, class ALLOCATOR>
template <class EQ_PREDICATE>
void list<VALUE, ALLOCATOR>::unique(EQ_PREDICATE binaryPredicate)
{
    if (size() < 2) {
        return;                                                       // RETURN
    }

    iterator i = begin();
    iterator e = end();
    while (i != e) {
        reference match = *i++;
        while (i != e && binaryPredicate(*i, match)) {
            i = erase(i);
        }
    }
}

                              // *** misc ***

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::swap(list& other)
    BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocTraits::is_always_equal::value)
{
    // C++11 behavior for member 'swap': undefined for unequal allocators.
    // BSLS_ASSERT(allocatorImp() == other.allocatorImp());

    if (AllocTraits::propagate_on_container_swap::value) {
        using std::swap;

        swap(d_sentinel,     other.d_sentinel);
        swap(allocatorImp(), other.allocatorImp());
        swap(sizeRef(),      other.sizeRef());
    }
    else if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(
                                     allocatorImp() == other.allocatorImp())) {
        quickSwap(&other);
    }
    else {
        BSLS_PERFORMANCEHINT_UNLIKELY_HINT;

        // Create copies using the move constructor, then swap both containers
        // with them.  Note that if no move constructor exists, but a copy
        // constructor does, the copy constructor will be used.

        // Also note that if either of these copies throws, it could leave the
        // two containers in a changed state.  They are, however, guaranteed to
        // be left in valid state.

        list toOtherCopy(MoveUtil::move(*this), other.allocatorImp());
        list toThisCopy( MoveUtil::move(other), this->allocatorImp());

        toOtherCopy.quickSwap(&other);
        toThisCopy .quickSwap(this);
    }
}

// ACCESSORS

                               // *** iterators ***

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::const_iterator
list<VALUE, ALLOCATOR>::begin() const BSLS_KEYWORD_NOEXCEPT
{
    return const_iterator(headNode());
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::const_iterator
list<VALUE, ALLOCATOR>::end() const BSLS_KEYWORD_NOEXCEPT
{
    return const_iterator(d_sentinel);
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::const_iterator
list<VALUE, ALLOCATOR>::cbegin() const BSLS_KEYWORD_NOEXCEPT
{
    return begin();
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::const_iterator
list<VALUE, ALLOCATOR>::cend() const BSLS_KEYWORD_NOEXCEPT
{
    return end();
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::const_reverse_iterator
list<VALUE, ALLOCATOR>::crbegin() const BSLS_KEYWORD_NOEXCEPT
{
    return rbegin();
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::const_reverse_iterator
list<VALUE, ALLOCATOR>::crend() const BSLS_KEYWORD_NOEXCEPT
{
    return rend();
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::const_reverse_iterator
list<VALUE, ALLOCATOR>::rbegin() const BSLS_KEYWORD_NOEXCEPT
{
    return const_reverse_iterator(end());
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::const_reverse_iterator
list<VALUE, ALLOCATOR>::rend() const BSLS_KEYWORD_NOEXCEPT
{
    return const_reverse_iterator(begin());
}

                                  // *** size ***

template <class VALUE, class ALLOCATOR>
inline
bool list<VALUE, ALLOCATOR>::empty() const BSLS_KEYWORD_NOEXCEPT
{
    return 0 == sizeRef();
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::size_type
list<VALUE, ALLOCATOR>::max_size() const BSLS_KEYWORD_NOEXCEPT
{
    return AllocTraits::max_size(allocatorImp());
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::size_type list<VALUE, ALLOCATOR>::size() const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return sizeRef();
}

                           // *** element access ***

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::const_reference
list<VALUE, ALLOCATOR>::back() const
{
    BSLS_ASSERT_SAFE(sizeRef() > 0);

    return d_sentinel->d_prev_p->d_value;
}

template <class VALUE, class ALLOCATOR>
inline
typename list<VALUE, ALLOCATOR>::const_reference
list<VALUE, ALLOCATOR>::front() const
{
    BSLS_ASSERT_SAFE(sizeRef() > 0);

    return headNode()->d_value;
}

                                // *** misc ***

template <class VALUE, class ALLOCATOR>
inline
ALLOCATOR list<VALUE, ALLOCATOR>::get_allocator() const BSLS_KEYWORD_NOEXCEPT
{
    return allocatorImp();
}

}  // close namespace bsl

// FREE OPERATORS
template <class VALUE, class ALLOCATOR>
inline
bool bsl::operator==(const list<VALUE, ALLOCATOR>& lhs,
                     const list<VALUE, ALLOCATOR>& rhs)
{
    return BloombergLP::bslalg::RangeCompare::equal(lhs.begin(),
                                                    lhs.end(),
                                                    lhs.size(),
                                                    rhs.begin(),
                                                    rhs.end(),
                                                    rhs.size());
}

template <class VALUE, class ALLOCATOR>
inline
bool bsl::operator!=(const list<VALUE, ALLOCATOR>& lhs,
                     const list<VALUE, ALLOCATOR>& rhs)
{
    return ! (lhs == rhs);
}

template <class VALUE, class ALLOCATOR>
inline
bool bsl::operator< (const list<VALUE, ALLOCATOR>& lhs,
                     const list<VALUE, ALLOCATOR>& rhs)
{
    return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.begin(),
                                                                  lhs.end(),
                                                                  lhs.size(),
                                                                  rhs.begin(),
                                                                  rhs.end(),
                                                                  rhs.size());
}

template <class VALUE, class ALLOCATOR>
inline
bool bsl::operator> (const list<VALUE, ALLOCATOR>& lhs,
                     const list<VALUE, ALLOCATOR>& rhs)
{
    return rhs < lhs;
}

template <class VALUE, class ALLOCATOR>
inline
bool bsl::operator<=(const list<VALUE, ALLOCATOR>& lhs,
                     const list<VALUE, ALLOCATOR>& rhs)
{
    return !(rhs < lhs);
}

template <class VALUE, class ALLOCATOR>
inline
bool bsl::operator>=(const list<VALUE, ALLOCATOR>& lhs,
                     const list<VALUE, ALLOCATOR>& rhs)
{
    return !(lhs < rhs);
}

// FREE FUNCTIONS
template <class VALUE, class ALLOCATOR, class BDE_OTHER_TYPE>
inline typename bsl::list<VALUE, ALLOCATOR>::size_type
bsl::erase(list<VALUE, ALLOCATOR>& l, const BDE_OTHER_TYPE& value)
{
    // We could use the erase/remove idiom here like we do in the other
    // sequence containers, but this is more efficient, since we just unlink
    // and delete nodes from the list.
    typename list<VALUE, ALLOCATOR>::size_type oldSize = l.size();
    for (typename list<VALUE, ALLOCATOR>::iterator it = l.begin();
                                                                it != l.end();)
    {
        if (value == *it) {
            it = l.erase(it);
        }
        else {
            ++it;
        }
    }
    return oldSize - l.size();
}

template <class VALUE, class ALLOCATOR, class PREDICATE>
inline typename bsl::list<VALUE, ALLOCATOR>::size_type
bsl::erase_if(list<VALUE, ALLOCATOR>& l, PREDICATE predicate)
{
    return BloombergLP::bslstl::AlgorithmUtil::containerEraseIf(l, predicate);
}

template <class VALUE, class ALLOCATOR>
inline
void bsl::swap(list<VALUE, ALLOCATOR>& a, list<VALUE, ALLOCATOR>& b)
    BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR(
                                                                    a.swap(b)))
{
    a.swap(b);
}

// ============================================================================
//                                TYPE TRAITS
// ============================================================================

// Type traits for STL *sequence* containers:
//: o A sequence container defines STL iterators.
//: o A sequence container uses 'bslma' allocators if the (template parameter)
//:   type 'ALLOCATOR' is convertible from 'bslma::Allocator*'.

namespace BloombergLP {

namespace bslalg {

template <class VALUE, class ALLOCATOR>
struct HasStlIterators<bsl::list<VALUE, ALLOCATOR> >
    : bsl::true_type
{};

}  // close namespace bslalg

namespace bslma {

template <class VALUE, class ALLOCATOR>
struct UsesBslmaAllocator<bsl::list<VALUE, ALLOCATOR> >
    : bsl::is_convertible<Allocator*, ALLOCATOR>
{};

}  // close namespace bslma

namespace bslmf {

// A list is bitwise movable if its allocator is bitwise movable.

template <class VALUE, class ALLOCATOR>
struct IsBitwiseMoveable<bsl::list<VALUE, ALLOCATOR> >
    : BloombergLP::bslmf::IsBitwiseMoveable<ALLOCATOR>
{};

}  // close namespace bslmf
}  // close enterprise namespace

#else // if ! defined(DEFINED_BSLSTL_LIST_H)
# error Not valid except when included from bslstl_list.h
#endif // ! defined(COMPILING_BSLSTL_LIST_H)

#endif // ! defined(INCLUDED_BSLSTL_LIST_CPP03)

// ----------------------------------------------------------------------------
// Copyright 2022 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------