// 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 ----------------------------------