// bslstl_vector_cpp03.h -*-C++-*- // Automatically generated file. **DO NOT EDIT** #ifndef INCLUDED_BSLSTL_VECTOR_CPP03 #define INCLUDED_BSLSTL_VECTOR_CPP03 //@PURPOSE: Provide C++03 implementation for bslstl_vector.h // //@CLASSES: See bslstl_vector.h for list of classes // //@SEE_ALSO: bslstl_vector // //@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 Dec 14 12:21:08 2022 // Command line: sim_cpp11_features.pl bslstl_vector.h #ifdef COMPILING_BSLSTL_VECTOR_H namespace bsl { // Forward declarations template <class VALUE_TYPE, class ITERATOR> class vector_UintPtrConversionIterator; // ================== // struct Vector_Util // ================== struct Vector_Util { // This 'struct' provides a namespace for implementing the 'swap' member // function of 'vector<VALUE_TYPE, ALLOCATOR>'. 'swap' can be implemented // irrespective of the 'VALUE_TYPE' or 'ALLOCATOR' template parameters, // which is why we implement it in this non-parameterized, non-inlined // utility. // CLASS METHODS static std::size_t computeNewCapacity(std::size_t newLength, std::size_t capacity, std::size_t maxSize); // Return a capacity that is at least the specified 'newLength' and at // least the minimum of twice the specified 'capacity' and the // specified 'maxSize'. The behavior is undefined unless // 'capacity < newLength' and 'newLength <= maxSize'. Note that the // returned value is always at most 'maxSize'. static void swap(void *a, void *b); // Exchange the value of the specified 'a' vector with that of the // specified 'b' vector. }; // =================================== // class Vector_DeduceIteratorCategory // =================================== template <class BSLSTL_ITERATOR, bool BSLSTL_NOTSPECIALIZED = is_fundamental<BSLSTL_ITERATOR>::value> struct Vector_DeduceIteratorCategory { // This 'struct' provides a primitive means to distinguish between iterator // types and fundamental types, in order to dispatch to the correct // implementation of a function template (or constructor template) passed // two arguments of identical type. By default, it is assumed that any // type that is not a fundamental type, as determined by the type trait // 'bsl::is_fundamental', must be an iterator type. 'std::iterator_traits' // is updated in C++17 to provide a SFINAE-friendly instantiation of the // primary-template for types that do not provide all of the nested typedef // names, but we cannot portably rely on such a scheme yet. // PUBLIC TYPES typedef typename bsl::iterator_traits<BSLSTL_ITERATOR>::iterator_category type; }; template <class BSLSTL_ITERATOR> struct Vector_DeduceIteratorCategory<BSLSTL_ITERATOR, true> { // This partial specialization of the 'struct' template for fundamental // types provides a nested 'type' that is not an iterator category, so can // be used to control the internal dispatch of function template overloads // taking two arguments of the same type. // PUBLIC TYPES typedef BloombergLP::bslmf::Nil type; }; // ====================================== // class vector_UintPtrConversionIterator // ====================================== template <class TARGET, class ITERATOR, bool = is_integral<ITERATOR>::value> struct vector_ForwardIteratorForPtrs { // This metafunction provides an appropriate iterator adaptor for the // specified (template parameter) type 'ITERATOR' in order to implement // members of the 'vector' partial template specialization for vectors of // pointers to the (template parameter) type 'TARGET'. The metafunction // will return the original 'ITERATOR' type unless it truly is an iterator, // using 'is_integral' as a proxy for testing that a type is NOT an // iterator. This is needed to disambiguate only the cases of users // passing '0' as a null-pointer value to functions requesting a number of // identical copies of an element. // PUBLIC TYPES typedef ITERATOR type; }; template <class TARGET, class ITERATOR> struct vector_ForwardIteratorForPtrs<TARGET, ITERATOR, false> { // This metafunction specialization provides an appropriate iterator // adaptor for the specified (template parameter) type 'ITERATOR' in order // to implement members of the 'vector' partial template specialization for // vectors of pointers to the (template parameter) type 'TARGET'. // PUBLIC TYPES typedef vector_UintPtrConversionIterator<TARGET *, ITERATOR> type; }; #if defined(BSLS_ASSERT_SAFE_IS_USED) template <class BSLSTL_ITERATOR> struct Vector_IsRandomAccessIterator : bsl::is_same<typename Vector_DeduceIteratorCategory<BSLSTL_ITERATOR>::type, bsl::random_access_iterator_tag>::type { }; // ======================= // class Vector_RangeCheck // ======================= struct Vector_RangeCheck { // This utility class provides a test-support facility to diagnose when a // pair of iterators do *not* form a valid range. This support is offered // only for random access iterators, and identifies only the case of two // valid iterators into the same range forming a "reverse" range. Note // that the two functions declared using 'enable_if' must be defined inline // in the class definition due to a bug in the Microsoft C++ compiler (see // 'bslmf_enableif'). // CLASS METHODS template <class BSLSTL_ITERATOR> static typename bsl::enable_if< !Vector_IsRandomAccessIterator<BSLSTL_ITERATOR>::VALUE, bool>::type isInvalidRange(BSLSTL_ITERATOR, BSLSTL_ITERATOR); // Return 'false'. Note that we know of no way to identify an input // iterator range that is guaranteed to be invalid. template <class BSLSTL_ITERATOR> static typename bsl::enable_if< Vector_IsRandomAccessIterator<BSLSTL_ITERATOR>::VALUE, bool>::type isInvalidRange(BSLSTL_ITERATOR first, BSLSTL_ITERATOR last); // Return 'true' if 'last < first', and 'false' otherwise. The // behavior is undefined unless both 'first' and 'last' are valid // iterators that refer to the same range. }; #endif // ================ // class vectorBase // ================ template <class VALUE_TYPE> class vectorBase { // This class describes the basic layout for a vector class, to be included // into the 'vector' layout *before* the allocator (provided by // 'bslalg::ContainerBase') to take better advantage of cache prefetching. // It is parameterized by 'VALUE_TYPE' only, and implements the portion of // 'vector' that does not need to know about its (template parameter) type // 'ALLOCATOR' (in order to generate shorter debug strings). This class // intentionally has *no* creators (other than the compiler-generated // ones). // PRIVATE TYPES typedef BloombergLP::bslmf::MovableRefUtil MoveUtil; // This 'typedef' is a convenient alias for the utility associated with // movable references. protected: // PROTECTED DATA VALUE_TYPE *d_dataBegin_p; // beginning of data storage (owned) VALUE_TYPE *d_dataEnd_p; // one past the end of data storage std::size_t d_capacity; // capacity of data storage in # of elements public: // PUBLIC TYPES typedef VALUE_TYPE value_type; typedef VALUE_TYPE& reference; typedef VALUE_TYPE const& const_reference; typedef VALUE_TYPE *iterator; typedef VALUE_TYPE const *const_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef bsl::reverse_iterator<iterator> reverse_iterator; typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator; public: // CREATORS vectorBase(); // Create an empty base object with no capacity. // MANIPULATORS void adopt(BloombergLP::bslmf::MovableRef<vectorBase> base); // Adopt all outstanding memory allocations associated with the // specified 'base' object. The behavior is undefined unless this // object is in a default-constructed state. // *** iterators *** iterator begin() BSLS_KEYWORD_NOEXCEPT; // Return an iterator providing modifiable access to the first element // in this vector, or the past-the-end iterator if this vector is // empty. iterator end() BSLS_KEYWORD_NOEXCEPT; // Return the past-the-end iterator providing modifiable access to this // vector. reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT; // Return a reverse iterator providing modifiable access to the last // element in this vector, and the past-the-end reverse iterator if // this vector is empty. reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT; // Return the past-the-end reverse iterator providing modifiable access // to this vector. // *** element access *** reference operator[](size_type position); // Return a reference providing modifiable access to the element at the // specified 'position' in this vector. The behavior is undefined // unless 'position < size()'. reference at(size_type position); // Return a reference providing modifiable access to the element at the // specified 'position' in this vector. Throw a 'std::out_of_range' // exception if 'position >= size()'. reference front(); // Return a reference providing modifiable access to the first element // in this vector. The behavior is undefined unless this vector is not // empty. reference back(); // Return a reference providing modifiable access to the last element // in this vector. The behavior is undefined unless this vector is not // empty. VALUE_TYPE *data() BSLS_KEYWORD_NOEXCEPT; // Return the address of the modifiable first element in this vector, // or a valid, but non-dereferenceable pointer value if this vector is // empty. // 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 // element in this vector, and the past-the-end iterator if this vector // 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 vector. 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 vector, and the past-the-end reverse iterator // if this vector 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 vector. // *** capacity *** size_type size() const BSLS_KEYWORD_NOEXCEPT; // Return the number of elements in this vector. size_type capacity() const BSLS_KEYWORD_NOEXCEPT; // Return the capacity of this vector, i.e., the maximum number of // elements for which resizing is guaranteed not to trigger a // reallocation. bool empty() const BSLS_KEYWORD_NOEXCEPT; // Return 'true' if this vector has size 0, and 'false' otherwise. // *** element access *** const_reference operator[](size_type position) const; // Return a reference providing non-modifiable access to the element at // the specified 'position' in this vector. The behavior is undefined // unless 'position < size()'. const_reference at(size_type position) const; // Return a reference providing non-modifiable access to the element at // the specified 'position' in this vector. Throw a // 'bsl::out_of_range' exception if 'position >= size()'. const_reference front() const; // Return a reference providing non-modifiable access to the first // element in this vector. The behavior is undefined unless this // vector is not empty. const_reference back() const; // Return a reference providing non-modifiable access to the last // element in this vector. The behavior is undefined unless this // vector is not empty. const VALUE_TYPE *data() const BSLS_KEYWORD_NOEXCEPT; // Return the address of the non-modifiable first element in this // vector, or a valid, but non-dereferenceable pointer value if this // vector is empty. }; // ============ // class vector // ============ template <class VALUE_TYPE, class ALLOCATOR = allocator<VALUE_TYPE> > class vector : public vectorBase<VALUE_TYPE> , private BloombergLP::bslalg::ContainerBase<ALLOCATOR> { // This class template provides an STL-compliant 'vector' that conforms to // the 'bslma::Allocator' model. For the requirements of a vector class, // consult the C++11 standard. In particular, this implementation offers // the general rules that: // //: 1 A call to any method that would result in a vector having a size //: or capacity greater than the value returned by 'max_size' triggers a //: call to 'bslstl::StdExceptUtil::throwLengthError'. //: //: 2 A call to an 'at' method that attempts to access a position outside //: of the valid range of a vector triggers a call to //: 'bslstl::StdExceptUtil::throwOutOfRange'. // // Note that portions of the standard methods are implemented in // 'vectorBase', which is parameterized on only 'VALUE_TYPE' in order to // generate smaller debug strings. // // This class: //: o supports a complete set of *value-semantic* operations //: o except for 'BDEX' serialization //: o is *exception-neutral* //: o is *alias-safe* //: o is 'const' *thread-safe* // For terminology see {'bsldoc_glossary'}. // // In addition, the following members offer a full guarantee of rollback: // if an exception is thrown during the invocation of 'push_back' or // 'insert' with a single element at the end of a pre-existing object, the // object is left in a valid state and its value is unchanged. // PRIVATE TYPES typedef BloombergLP::bslalg::ArrayPrimitives ArrayPrimitives; // This 'typedef' is an alias for a utility class that provides many // useful functions that operate on arrays. typedef BloombergLP::bslmf::MovableRefUtil MoveUtil; // This 'typedef' is a convenient alias for the utility associated with // movable references. typedef allocator_traits<ALLOCATOR> AllocatorTraits; // This 'typedef' is an alias for the allocator traits type associated // with this container. public: // PUBLIC TYPES typedef VALUE_TYPE value_type; typedef ALLOCATOR allocator_type; typedef VALUE_TYPE& reference; typedef const VALUE_TYPE& const_reference; typedef typename AllocatorTraits::size_type size_type; typedef typename AllocatorTraits::difference_type difference_type; typedef typename AllocatorTraits::pointer pointer; typedef typename AllocatorTraits::const_pointer const_pointer; typedef VALUE_TYPE *iterator; typedef VALUE_TYPE const *const_iterator; typedef bsl::reverse_iterator<iterator> reverse_iterator; typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator; private: // PRIVATE TYPES typedef vectorBase<VALUE_TYPE> ImpBase; // Implementation base type, with iterator-related functionality. typedef BloombergLP::bslalg::ContainerBase<ALLOCATOR> ContainerBase; // Container base type, containing the allocator and applying the empty // base class optimization (EBO) whenever appropriate. class Proctor { // This class provides a proctor for deallocating an array of // 'VALUE_TYPE' objects, to be used in the 'vector' constructors. // DATA VALUE_TYPE *d_data_p; // array pointer std::size_t d_capacity; // capacity of the array ContainerBase *d_container_p; // container base pointer private: // NOT IMPLEMENTED Proctor(const Proctor&); Proctor& operator=(const Proctor&); public: // CREATORS Proctor(VALUE_TYPE *data, std::size_t capacity, ContainerBase *container); // Create a proctor for the specified 'data' array of the specified // 'capacity', using the 'deallocateN' method of the specified // 'container' to return 'data' to its allocator upon destruction, // unless this proctor's 'release' is called prior. ~Proctor(); // Destroy this proctor, deallocating any data under management. // MANIPULATORS void release(); // Release the data from management by this proctor. }; // PRIVATE MANIPULATORS template <class FWD_ITER> void constructFromRange(FWD_ITER first, FWD_ITER last, std::forward_iterator_tag); template <class INPUT_ITER> void constructFromRange(INPUT_ITER first, INPUT_ITER last, std::input_iterator_tag); // Populate a default-constructed vector with the values held in the // specified range '[first, last)'. The additional // 'std::*iterator__tag' should be a default-constructed tag that // corresponds to that found in 'std::iterator_traits' for the // (template parameter) '*_ITER' type. This method should be called // only from a constructor. The behavior is undefined unless // 'first != last'. template <class INTEGRAL> void constructFromRange(INTEGRAL initialSize, INTEGRAL value, BloombergLP::bslmf::Nil); // Populate a default-constructed vector with the specified // 'initialSize' elements, where each such element is a copy of the // specified 'value'. The 'bslmf::Nil' traits value distinguished this // overload of two identical (presumed integral) types from the pair of // iterator overloads above. This method should be called only from a // constructor. template <class INPUT_ITER> void privateInsertDispatch( const_iterator position, INPUT_ITER count, INPUT_ITER value, BloombergLP::bslmf::MatchArithmeticType , BloombergLP::bslmf::Nil ); // Match integral type for 'INPUT_ITER'. template <class INPUT_ITER> void privateInsertDispatch(const_iterator position, INPUT_ITER first, INPUT_ITER last, BloombergLP::bslmf::MatchAnyType , BloombergLP::bslmf::MatchAnyType ); // Match non-integral type for 'INPUT_ITER'. template <class INPUT_ITER> void privateInsert(const_iterator position, INPUT_ITER first, INPUT_ITER last, const std::input_iterator_tag&); // Specialized insertion for input iterators. template <class FWD_ITER> void privateInsert(const_iterator position, FWD_ITER first, FWD_ITER last, const std::forward_iterator_tag&); // Specialized insertion for forward, bidirectional, and random-access // iterators. void privateMoveInsert(vector *fromVector, const_iterator position); // Destructive move insertion from a temporary vector, to avoid // duplicate copies after importing from an input iterator into a // temporary vector. void privateReserveEmpty(size_type numElements); // Reserve exactly the specified 'numElements'. The behavior is // undefined unless this vector is empty and has no capacity. public: // CREATORS // *** construct/copy/destroy *** vector() BSLS_KEYWORD_NOEXCEPT; explicit vector(const ALLOCATOR& basicAllocator) BSLS_KEYWORD_NOEXCEPT; // Create an empty vector. Optionally specify a 'basicAllocator' used // to supply memory. If 'basicAllocator' is not specified, a // default-constructed object of the (template parameter) type // 'ALLOCATOR' is used. If the type 'ALLOCATOR' is 'bsl::allocator' // and 'basicAllocator' is not supplied, the currently installed // default allocator is used. Note that a 'bslma::Allocator *' can be // supplied for 'basicAllocator' if the type 'ALLOCATOR' is // 'bsl::allocator' (the default). explicit vector(size_type initialSize, const ALLOCATOR& basicAllocator = ALLOCATOR()); // Create a vector of the specified 'initialSize' whose every element // is a default-constructed object of the (template parameter) type // 'VALUE_TYPE'. Optionally specify a 'basicAllocator' used to supply // memory. If 'basicAllocator' is not specified, a default-constructed // object of the (template parameter) type 'ALLOCATOR' is used. If the // type 'ALLOCATOR' is 'bsl::allocator' and 'basicAllocator' is not // supplied, the currently installed default allocator is used. Throw // 'std::length_error' if 'initialSize > max_size()'. This method // requires that the type 'VALUE_TYPE' be 'default-insertable' into // this vector (see {Requirements on 'VALUE_TYPE'}). Note that a // 'bslma::Allocator *' can be supplied for 'basicAllocator' if the // type 'ALLOCATOR' is 'bsl::allocator' (the default). vector(size_type initialSize, const VALUE_TYPE& value, const ALLOCATOR& basicAllocator = ALLOCATOR()); // Create a vector of the specified 'initialSize' whose every element // is a copy of the specified 'value'. Optionally specify a // 'basicAllocator' used to supply memory. If 'basicAllocator' is not // specified, a default-constructed object of the (template parameter) // type 'ALLOCATOR' is used. If the type 'ALLOCATOR' is // 'bsl::allocator' and 'basicAllocator' is not supplied, the currently // installed default allocator is used. Throw 'std::length_error' if // 'initialSize > max_size()'. This method requires that the (template // parameter) type 'VALUE_TYPE' be 'copy-insertable' into this vector // (see {Requirements on 'VALUE_TYPE'}). Note that a // 'bslma::Allocator *' can be supplied for 'basicAllocator' if the // type 'ALLOCATOR' is 'bsl::allocator' (the default). template <class INPUT_ITER> vector(INPUT_ITER first, INPUT_ITER last, const ALLOCATOR& basicAllocator = ALLOCATOR()); // Create a vector, and insert (in order) each 'VALUE_TYPE' object in // the range starting at the specified 'first' element, and ending // immediately before the specified 'last' element. Optionally specify // a 'basicAllocator' used to supply memory. If 'basicAllocator' is // not specified, a default-constructed object of the (template // parameter) type 'ALLOCATOR' is used. If the type 'ALLOCATOR' is // 'bsl::allocator' and 'basicAllocator' is not supplied, the currently // installed default allocator is used. Throw 'std::length_error' if // the number of elements in '[first .. last)' exceeds the value // returned by the method 'max_size'. The (template parameter) type // 'INPUT_ITER' 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 vector, where 'i' is a // dereferenceable iterator in the range '[first .. last)' (see // {Requirements on 'VALUE_TYPE'}). The behavior is undefined unless // 'first' and 'last' refer to a range of valid values where 'first' // is at a position at or before 'last'. Note that a // 'bslma::Allocator *' can be supplied for 'basicAllocator' if the // type 'ALLOCATOR' is 'bsl::allocator' (the default). vector(const vector& original); // Create a vector 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_TYPE' be 'copy-insertable' into this vector (see // {Requirements on 'VALUE_TYPE'}). vector(BloombergLP::bslmf::MovableRef<vector> original) BSLS_KEYWORD_NOEXCEPT; // IMPLICIT // Create a vector having the same value as the specified 'original' // object by moving (in constant time) the contents of 'original' to // the new vector. The allocator associated with 'original' is // propagated for use in the newly-created vector. 'original' is left // in a valid but unspecified state. vector(const vector& original, const typename type_identity<ALLOCATOR>::type& basicAllocator); // Create a vector having the same value as the specified 'original' // object that uses the specified 'basicAllocator' to supply memory. // This method requires that the (template parameter) type 'VALUE_TYPE' // be 'copy-insertable' into this vector (see {Requirements on // 'VALUE_TYPE'}). Note that a 'bslma::Allocator *' can be supplied // for 'basicAllocator' if the (template parameter) type 'ALLOCATOR' is // 'bsl::allocator' (the default). vector(BloombergLP::bslmf::MovableRef<vector> original, const typename type_identity<ALLOCATOR>::type& basicAllocator); // Create a vector 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 // vector 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) type 'VALUE_TYPE' be // 'move-insertable' into this vector (see {Requirements on // 'VALUE_TYPE'}). Note that a 'bslma::Allocator *' can be supplied // for 'basicAllocator' if the (template parameter) type 'ALLOCATOR' is // 'bsl::allocator' (the default). #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) vector(std::initializer_list<VALUE_TYPE> values, const ALLOCATOR& basicAllocator = ALLOCATOR()); // IMPLICIT // Create a vector and insert (in order) each 'VALUE_TYPE' object in // the specified 'values' initializer list. Optionally specify a // 'basicAllocator' used to supply memory. If 'basicAllocator' is not // specified, a default-constructed object of the (template parameter) // type 'ALLOCATOR' is used. 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) type 'VALUE_TYPE' be 'copy-insertable' into // this vector (see {Requirements on 'VALUE_TYPE'}). Note that a // 'bslma::Allocator *' can be supplied for 'basicAllocator' if the // type 'ALLOCATOR' is 'bsl::allocator' (the default). #endif ~vector(); // Destroy this vector. // MANIPULATORS vector& operator=(const vector& 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_TYPE' be 'copy-assignable' and 'copy-insertable' into this // vector (see {Requirements on 'VALUE_TYPE'}). vector& operator=( BloombergLP::bslmf::MovableRef<vector<VALUE_TYPE, ALLOCATOR> > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION( AllocatorTraits::propagate_on_container_move_assignment::value || AllocatorTraits::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 vector if // 'get_allocator() == rhs.get_allocator()' (after accounting for the // aforementioned trait); otherwise, all elements in this vector are // either destroyed or move-assigned to and each additional element in // 'rhs' is move-inserted into this vector. '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_TYPE' be 'move-assignable' and // 'move-insertable' into this vector (see {Requirements on // 'VALUE_TYPE'}). #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) vector& operator=(std::initializer_list<VALUE_TYPE> values); // Assign to this object the value resulting from first clearing this // vector and then inserting (in order) each 'VALUE_TYPE' object in the // specified 'values' initializer list, 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_TYPE' be // 'copy-insertable' into this vector (see {Requirements on // 'VALUE_TYPE'}). void assign(std::initializer_list<VALUE_TYPE> values); // Assign to this object the value resulting from first clearing this // vector and then inserting (in order) each 'VALUE_TYPE' object in the // specified 'values' initializer list. If an exception is thrown, // '*this' is left in a valid but unspecified state. This method // requires that the (template parameter) type 'VALUE_TYPE' be // 'copy-insertable' into this vector (see {Requirements on // 'VALUE_TYPE'}). #endif template <class INPUT_ITER> void assign(INPUT_ITER first, INPUT_ITER last); // Assign to this object the value resulting from first clearing this // vector and then inserting (in order) each 'value_type' object in the // range starting at the specified 'first' element, and ending // immediately before the specified 'last' element. If an exception is // thrown, '*this' is left in a valid but unspecified state. Throw // 'std::length_error' if 'distance(first,last) > max_size()'. The // (template parameter) type 'INPUT_ITER' 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 // vector, where 'i' is a dereferenceable iterator in the range // '[first .. last)' (see {Requirements on 'VALUE_TYPE'}). The // behavior is undefined unless 'first' and 'last' refer to a range of // valid values where 'first' is at a position at or before 'last'. void assign(size_type numElements, const VALUE_TYPE& value); // Assign to this object the value resulting from first clearing this // vector and then inserting the specified 'numElements' copies of the // specified 'value'. If an exception is thrown, '*this' is left in a // valid but unspecified state. Throw 'std::length_error' if // 'numElements > max_size()'. This method requires that the (template // parameter) type 'VALUE_TYPE' be 'copy-insertable' into this vector // (see {Requirements on 'VALUE_TYPE'}). // *** capacity *** void resize(size_type newSize); // Change the size of this vector to the specified 'newSize'. If // 'newSize < size()', the elements in the range '[newSize .. size())' // are erased, and this function does not throw. If // 'newSize > size()', the (newly created) elements in the range // '[size() .. newSize)' are default-constructed 'value_type' objects, // and if an exception is thrown (other than by the move constructor of // a non-copy-insertable 'value_type'), '*this' is unaffected. Throw // 'std::length_error' if 'newSize > max_size()'. This method requires // that the (template parameter) type 'VALUE_TYPE' be // 'default-insertable' and 'move-insertable' into this vector (see // {Requirements on 'VALUE_TYPE'}). void resize(size_type newSize, const VALUE_TYPE& value); // Change the size of this vector to the specified 'newSize', inserting // 'newSize - size()' copies of the specified 'value' at the end of // this vector if 'newSize > size()'. If 'newSize < size()', the // elements in the range '[newSize .. size())' are erased, 'value' is // ignored, and this method does not throw. If 'newSize > size()' and // an exception is thrown, '*this' is unaffected. Throw // 'std::length_error' if 'newSize > max_size()'. This method requires // that the (template parameter) type 'VALUE_TYPE' be 'copy-insertable' // into this vector (see {Requirements on 'VALUE_TYPE'}). void reserve(size_type newCapacity); // Change the capacity of this vector to the specified 'newCapacity'. // If an exception is thrown (other than by the move constructor of a // non-copy-insertable 'value_type'), '*this' is unaffected. Throw // 'bsl::length_error' if 'newCapacity > max_size()'. This method // requires that the (template parameter) type 'VALUE_TYPE' be // 'move-insertable' into this vector (see {Requirements on // 'VALUE_TYPE'}). Note that the capacity of this vector after this // operation has completed may be greater than 'newCapacity'. void shrink_to_fit(); // Reduce the capacity of this vector to its size. If an exception is // thrown (other than by the move constructor of a non-copy-insertable // 'value_type'), '*this' is unaffected. Note that this method has no // effect if the capacity is equivalent to the size. // *** modifiers *** #if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES // {{{ BEGIN GENERATED CODE // Command line: sim_cpp11_features.pl bslstl_vector.h #ifndef BSLSTL_VECTOR_VARIADIC_LIMIT #define BSLSTL_VECTOR_VARIADIC_LIMIT 10 #endif #ifndef BSLSTL_VECTOR_VARIADIC_LIMIT_A #define BSLSTL_VECTOR_VARIADIC_LIMIT_A BSLSTL_VECTOR_VARIADIC_LIMIT #endif #if BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 0 VALUE_TYPE &emplace_back( ); #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 0 #if BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 1 template <class Args_01> VALUE_TYPE &emplace_back( BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01); #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 1 #if BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 2 template <class Args_01, class Args_02> VALUE_TYPE &emplace_back( BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02); #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 2 #if BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 3 template <class Args_01, class Args_02, class Args_03> VALUE_TYPE &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_VECTOR_VARIADIC_LIMIT_A >= 3 #if BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 4 template <class Args_01, class Args_02, class Args_03, class Args_04> VALUE_TYPE &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_VECTOR_VARIADIC_LIMIT_A >= 4 #if BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 5 template <class Args_01, class Args_02, class Args_03, class Args_04, class Args_05> VALUE_TYPE &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_VECTOR_VARIADIC_LIMIT_A >= 5 #if BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 6 template <class Args_01, class Args_02, class Args_03, class Args_04, class Args_05, class Args_06> VALUE_TYPE &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_VECTOR_VARIADIC_LIMIT_A >= 6 #if BSLSTL_VECTOR_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> VALUE_TYPE &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_VECTOR_VARIADIC_LIMIT_A >= 7 #if BSLSTL_VECTOR_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> VALUE_TYPE &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_VECTOR_VARIADIC_LIMIT_A >= 8 #if BSLSTL_VECTOR_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> VALUE_TYPE &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_VECTOR_VARIADIC_LIMIT_A >= 9 #if BSLSTL_VECTOR_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> VALUE_TYPE &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_VECTOR_VARIADIC_LIMIT_A >= 10 #else // The generated code below is a workaround for the absence of perfect // forwarding in some compilers. template <class... Args> VALUE_TYPE &emplace_back( BSLS_COMPILERFEATURES_FORWARD_REF(Args)... arguments); // }}} END GENERATED CODE #endif void push_back(const VALUE_TYPE& value); // Append to the end of this vector a copy of the specified 'value'. // If an exception is thrown, '*this' is unaffected. Throw // 'std::length_error' if 'size() == max_size()'. This method // requires that the (template parameter) type 'VALUE_TYPE' be // 'copy-constructible' (see {Requirements on 'VALUE_TYPE'}). void push_back(BloombergLP::bslmf::MovableRef<VALUE_TYPE> value); // Append to the end of this vector 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' is unaffected. Throw // 'std::length_error' if 'size() == max_size()'. This method requires // that the (template parameter) type 'VALUE_TYPE' be 'move-insertable' // into this vector (see {Requirements on 'VALUE_TYPE'}). void pop_back(); // Erase the last element from this vector. The behavior is undefined // if this vector is empty. #if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES // {{{ BEGIN GENERATED CODE // Command line: sim_cpp11_features.pl bslstl_vector.h #ifndef BSLSTL_VECTOR_VARIADIC_LIMIT #define BSLSTL_VECTOR_VARIADIC_LIMIT 10 #endif #ifndef BSLSTL_VECTOR_VARIADIC_LIMIT_B #define BSLSTL_VECTOR_VARIADIC_LIMIT_B BSLSTL_VECTOR_VARIADIC_LIMIT #endif #if BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 0 iterator emplace(const_iterator position) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator()); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator()); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 0 #if BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 1 template <class Args_01> iterator emplace(const_iterator position, BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01)); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 1 #if BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 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) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01), BSLS_COMPILERFEATURES_FORWARD(Args_02, arguments_02)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01), BSLS_COMPILERFEATURES_FORWARD(Args_02, arguments_02)); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 2 #if BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 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) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01), BSLS_COMPILERFEATURES_FORWARD(Args_02, arguments_02), BSLS_COMPILERFEATURES_FORWARD(Args_03, arguments_03)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01), BSLS_COMPILERFEATURES_FORWARD(Args_02, arguments_02), BSLS_COMPILERFEATURES_FORWARD(Args_03, arguments_03)); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 3 #if BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 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) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), 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)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), 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)); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 4 #if BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 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) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), 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)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), 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)); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 5 #if BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 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) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), 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)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), 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)); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 6 #if BSLSTL_VECTOR_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> 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_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), 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)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), 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)); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 7 #if BSLSTL_VECTOR_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> 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_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), 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)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), 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)); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 8 #if BSLSTL_VECTOR_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> 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_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), 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)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), 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)); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 9 #if BSLSTL_VECTOR_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> 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) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), 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)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), 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)); ++this->d_dataEnd_p; } return this->begin() + index; } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_B >= 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) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::emplace(pos,arguments): vector too long"); } const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::emplace( pos, this->end(), ContainerBase::allocator(), BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...); ++this->d_dataEnd_p; } return this->begin() + index; } // }}} END GENERATED CODE #endif iterator insert(const_iterator position, const VALUE_TYPE& value); // Insert at the specified 'position' in this vector a copy of the // specified 'value', and return an iterator referring to the newly // inserted element. If an exception is thrown (other than by the copy // constructor, move constructor, assignment operator, or move // assignment operator of 'VALUE_TYPE'), '*this' is unaffected. Throw // 'std::length_error' if 'size() == max_size()'. The behavior is // undefined unless 'position' is an iterator in the range // '[begin() .. end()]' (both endpoints included). This method // requires that the (template parameter) type 'VALUE_TYPE' be // 'copy-insertable' into this vector (see {Requirements on // 'VALUE_TYPE'}). iterator insert(const_iterator position, BloombergLP::bslmf::MovableRef<VALUE_TYPE> value); // Insert at the specified 'position' in this vector the specified // move-insertable 'value', and return an iterator referring 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' is unaffected. Throw // 'std::length_error' if 'size() == max_size()'. The behavior is // undefined unless 'position' is an iterator in the range // '[begin() .. end()]' (both endpoints included). This method // requires that the (template parameter) type 'VALUE_TYPE' be // 'move-insertable' into this vector (see {Requirements on // 'VALUE_TYPE'}). iterator insert(const_iterator position, size_type numElements, const VALUE_TYPE& value); // Insert at the specified 'position' in this vector the specified // 'numElements' copies of the specified 'value', and return an // iterator referring to the first newly inserted element. If an // exception is thrown (other than by the copy constructor, move // constructor, assignment operator, or move assignment operator of // 'VALUE_TYPE'), '*this' is unaffected. Throw 'std::length_error' if // 'size() + numElements > max_size()'. The behavior is undefined // unless 'position' is an iterator in the range '[begin() .. end()]' // (both endpoints included). This method requires that the (template // parameter) type 'VALUE_TYPE' be 'copy-insertable' into this vector // (see {Requirements on 'VALUE_TYPE'}). template <class INPUT_ITER> iterator insert(const_iterator position, INPUT_ITER first, INPUT_ITER last) // Insert at the specified 'position' in this vector the values in the // range starting at the specified 'first' element, and ending // immediately before the specified 'last' element. Return an iterator // referring to the first newly inserted element. If an exception is // thrown (other than by the copy constructor, move constructor, // assignment operator, or move assignment operator of 'value_type'), // '*this' is unaffected. Throw 'std::length_error' if // 'size() + distance(first, last) > max_size()'. The (template // parameter) type 'INPUT_ITER' 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 vector, where 'i' is // a dereferenceable iterator in the range '[first .. last)' (see // {Requirements on 'VALUE_TYPE'}). The behavior is undefined unless // 'position' is an iterator in the range '[begin() .. end()]' (both // endpoints included), and 'first' and 'last' refer to a range of // valid values where 'first' is at a position at or before 'last'. // // NOTE: This function has been implemented inline due to an issue with // the Sun compiler. { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last)); // If 'first' and 'last' are integral, then they are not iterators and // we should call 'insert(position, first, last)', where 'first' is // actually a misnamed count, and 'last' is a misnamed value. We can // assume that any fundamental type passed to this function is integral // or else compilation errors will result. The extra argument, // 'bslmf::Nil()', is to avoid an overloading ambiguity: In case // 'first' is an integral type, it would be convertible both to // 'bslmf::MatchArithmeticType' and 'bslmf::MatchAnyType'; but the // 'bslmf::Nil()' will be an exact match to 'bslmf::Nil', so the // overload with 'bslmf::MatchArithmeticType' will be preferred. const size_type index = position - this->begin(); privateInsertDispatch( position, first, last, first, BloombergLP::bslmf::Nil()); return this->begin() + index; } #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) iterator insert(const_iterator position, std::initializer_list<VALUE_TYPE> values); // Insert at the specified 'position' in this vector each 'VALUE_TYPE' // object in the specified 'values' initializer list, and return an // iterator referring to the first newly inserted element. If an // exception is thrown (other than by the copy constructor, move // constructor, assignment operator, and move assignment operator of // 'VALUE_TYPE'), '*this' is unaffected. Throw 'std::length_error' if // 'size() + values.size() > max_size()'. The behavior is undefined // unless 'position' is an iterator in the range '[begin() .. end()]' // (both endpoints included). This method requires that the (template // parameter) type 'VALUE_TYPE' be 'copy-insertable' into this vector // (see {Requirements on 'VALUE_TYPE'}). #endif iterator erase(const_iterator position); // Remove from this vector the element at the specified 'position', and // return an iterator providing modifiable access to the element // immediately following the removed element, or the position returned // by the method 'end' if the removed element was the last in the // sequence. The behavior is undefined unless 'position' is an // iterator in the range '[cbegin() .. cend())'. iterator erase(const_iterator first, const_iterator last); // Remove from this vector the sequence of elements starting at the // specified 'first' position and ending before the specified 'last' // position, and return an iterator providing modifiable access to the // element immediately following the last removed element, or the // position returned by the method 'end' if the removed elements were // last in the sequence. The behavior is undefined unless 'first' is // an iterator in the range '[cbegin() .. cend()]' (both endpoints // included) and 'last' is an iterator in the range // '[first .. cend()]' (both endpoints included). void swap(vector& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION( AllocatorTraits::propagate_on_container_swap::value || AllocatorTraits::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. void clear() BSLS_KEYWORD_NOEXCEPT; // Remove all elements from this vector making its size 0. Note that // although this vector is empty after this method returns, it // preserves the same capacity it had before the method was called. // ACCESSORS allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT; // Return (a copy of) the allocator used for memory allocation by this // vector. size_type max_size() const BSLS_KEYWORD_NOEXCEPT; // Return a theoretical upper bound on the largest number of elements // that this vector could possibly hold. Note that there is no // guarantee that the vector can successfully grow to the returned // size, or even close to that size without running out of resources. // Also note that requests to create a vector longer than this number // of elements are guaranteed to raise a 'std::length_error' exception. }; // FREE OPERATORS // *** relational operators *** template <class VALUE_TYPE, class ALLOCATOR> bool operator==(const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs); // Return 'true' if the specified 'lhs' and 'rhs' objects have the same // value, and 'false' otherwise. Two 'vector' 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_TYPE' be 'equality-comparable' (see {Requirements on // 'VALUE_TYPE'}). template <class VALUE_TYPE, class ALLOCATOR> bool operator!=(const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs); // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the // same value, and 'false' otherwise. Two 'vector' 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_TYPE' be 'equality-comparable' (see {Requirements // on 'VALUE_TYPE'}). template <class VALUE_TYPE, class ALLOCATOR> bool operator<(const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs); // Return 'true' if the value of the specified 'lhs' vector is // lexicographically less than that of the specified 'rhs' vector, and // 'false' otherwise. Given iterators 'i' and 'j' over the respective // sequences '[lhs.begin() .. lhs.end())' and '[rhs.begin() .. rhs.end())', // the value of vector 'lhs' is lexicographically less than that of vector // '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_TYPE, class ALLOCATOR> bool operator>(const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs); // Return 'true' if the value of the specified 'lhs' vector is // lexicographically greater than that of the specified 'rhs' vector, and // 'false' otherwise. The value of vector 'lhs' is lexicographically // greater than that of vector '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_TYPE, class ALLOCATOR> bool operator<=(const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs); // Return 'true' if the value of the specified 'lhs' vector is // lexicographically less than or equal to that of the specified 'rhs' // vector, and 'false' otherwise. The value of vector 'lhs' is // lexicographically less than or equal to that of vector '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_TYPE, class ALLOCATOR> bool operator>=(const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs); // Return 'true' if the value of the specified 'lhs' vector is // lexicographically greater than or equal to that of the specified 'rhs' // vector, and 'false' otherwise. The value of vector 'lhs' is // lexicographically greater than or equal to that of vector '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_TYPE, class ALLOCATOR, class BDE_OTHER_TYPE> typename vector<VALUE_TYPE, ALLOCATOR>::size_type erase(vector<VALUE_TYPE, ALLOCATOR>& vec, const BDE_OTHER_TYPE& value); // Erase all the elements in the specified vector 'vec' that compare equal // to the specified 'value'. Return the number of elements erased. template <class VALUE_TYPE, class ALLOCATOR, class PREDICATE> typename vector<VALUE_TYPE, ALLOCATOR>::size_type erase_if(vector<VALUE_TYPE, ALLOCATOR>& vec, PREDICATE predicate); // Erase all the elements in the specified vector 'vec' that satisfy the // specified predicate 'predicate'. Return the number of elements erased. template <class VALUE_TYPE, class ALLOCATOR> void swap(vector<VALUE_TYPE, ALLOCATOR>& a, vector<VALUE_TYPE, 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. // ===================================== // class vector<VALUE_TYPE *, ALLOCATOR> // ===================================== template <class VALUE_TYPE, class ALLOCATOR> class vector<VALUE_TYPE *, ALLOCATOR> { // This partial specialization of 'vector' for pointer types to a (template // parameter) 'VALUE_TYPE' type is implemented in terms of // 'vector<UintPtr>' to reduce the amount of code generated. Note that // this specialization rebinds the (template parameter) 'ALLOCATOR' type to // an allocator of 'UintPtr' so as to satisfy the invariant in the 'vector' // base class. Note that the contract for all members is the same as the // primary template, so documentation is not repeated to avoid accidentally // introducing inconsistency over time. // PRIVATE TYPES typedef BloombergLP::bsls::Types::UintPtr UintPtr; #if defined(BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES) typedef typename allocator_traits<ALLOCATOR>:: template rebind_alloc<UintPtr> ImplAlloc; #else typedef typename ALLOCATOR::template rebind<UintPtr>::other ImplAlloc; #endif typedef vector<UintPtr, ImplAlloc> Impl; typedef BloombergLP::bslmf::MovableRefUtil MoveUtil; // PRIVATE DATA Impl d_impl; // The 'UintPtr' vector used for the implementation. public: // PUBLIC TYPES typedef VALUE_TYPE *value_type; typedef value_type& reference; typedef const value_type& const_reference; typedef VALUE_TYPE **iterator; typedef VALUE_TYPE *const *const_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef ALLOCATOR allocator_type; typedef typename ALLOCATOR::pointer pointer; typedef typename ALLOCATOR::const_pointer const_pointer; typedef bsl::reverse_iterator<iterator> reverse_iterator; typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator; // *** construct/copy/destroy *** // CREATORS vector() BSLS_KEYWORD_NOEXCEPT; explicit vector(const ALLOCATOR& basicAllocator) BSLS_KEYWORD_NOEXCEPT; explicit vector(size_type initialSize, const ALLOCATOR& basicAllocator = ALLOCATOR()); vector(size_type initialSize, VALUE_TYPE *value, const ALLOCATOR& basicAllocator = ALLOCATOR()); template <class INPUT_ITER> vector(INPUT_ITER first, INPUT_ITER last, const ALLOCATOR& basicAllocator = ALLOCATOR()); vector(const vector& original); vector(BloombergLP::bslmf::MovableRef<vector> original) BSLS_KEYWORD_NOEXCEPT; // IMPLICIT vector(const vector& original, const typename type_identity<ALLOCATOR>::type& basicAllocator); vector(BloombergLP::bslmf::MovableRef<vector> original, const typename type_identity<ALLOCATOR>::type& basicAllocator); #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) vector(std::initializer_list<VALUE_TYPE *> values, const ALLOCATOR& basicAllocator = ALLOCATOR()); #endif ~vector(); // MANIPULATORS vector& operator=(const vector& rhs); vector& operator=( BloombergLP::bslmf::MovableRef<vector<VALUE_TYPE *, ALLOCATOR> > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR( d_impl = MoveUtil::move(MoveUtil::access(rhs).d_impl))); #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) vector& operator=(std::initializer_list<VALUE_TYPE *> values); void assign(std::initializer_list<VALUE_TYPE *> values); #endif template <class INPUT_ITER> void assign(INPUT_ITER first, INPUT_ITER last); void assign(size_type numElements, VALUE_TYPE *value); // *** iterators *** iterator begin() BSLS_KEYWORD_NOEXCEPT; iterator end() BSLS_KEYWORD_NOEXCEPT; reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT; reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT; // *** element access *** reference operator[](size_type position); reference at(size_type position); reference front(); reference back(); VALUE_TYPE **data() BSLS_KEYWORD_NOEXCEPT; // *** capacity *** void resize(size_type newLength); void resize(size_type newLength, VALUE_TYPE *value); void reserve(size_type newCapacity); void shrink_to_fit(); // *** modifiers *** value_type &emplace_back(); # if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class ARG> value_type &emplace_back(ARG&& arg); # else value_type &emplace_back(VALUE_TYPE *ptr); # endif void push_back(VALUE_TYPE *value); void pop_back(); iterator emplace(const_iterator position); # if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class ARG> iterator emplace(const_iterator position, ARG&& arg); # else iterator emplace(const_iterator position, VALUE_TYPE *ptr); # endif iterator insert(const_iterator position, VALUE_TYPE *value); iterator insert(const_iterator position, size_type numElements, VALUE_TYPE *value); template <class INPUT_ITER> iterator insert(const_iterator position, INPUT_ITER first, INPUT_ITER last) { // NOTE: This function has been implemented inline due to an issue with // the Sun compiler. typedef typename vector_ForwardIteratorForPtrs<VALUE_TYPE, INPUT_ITER>::type Iter; return (iterator)d_impl.insert( (const UintPtr *)position, Iter(first), Iter(last)); } #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) iterator insert(const_iterator position, std::initializer_list<VALUE_TYPE *> values); #endif iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); void swap(vector<VALUE_TYPE *, ALLOCATOR>& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR( d_impl.swap(other.d_impl))); void clear() BSLS_KEYWORD_NOEXCEPT; // ACCESSORS allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT; size_type max_size() const BSLS_KEYWORD_NOEXCEPT; // *** iterators *** const_iterator begin() const BSLS_KEYWORD_NOEXCEPT; const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT; const_iterator end() const BSLS_KEYWORD_NOEXCEPT; const_iterator cend() const BSLS_KEYWORD_NOEXCEPT; const_reverse_iterator rbegin() const BSLS_KEYWORD_NOEXCEPT; const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT; const_reverse_iterator rend() const BSLS_KEYWORD_NOEXCEPT; const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT; // *** capacity *** size_type size() const BSLS_KEYWORD_NOEXCEPT; size_type capacity() const BSLS_KEYWORD_NOEXCEPT; bool empty() const BSLS_KEYWORD_NOEXCEPT; // *** element access *** const_reference operator[](size_type position) const; const_reference at(size_type position) const; const_reference front() const; const_reference back() const; VALUE_TYPE *const *data() const BSLS_KEYWORD_NOEXCEPT; // FRIENDS friend bool operator==(const vector& lhs, const vector& rhs) { return lhs.d_impl == rhs.d_impl; } friend bool operator!=(const vector& lhs, const vector& rhs) { return lhs.d_impl != rhs.d_impl; } friend bool operator<(const vector& lhs, const vector& rhs) { return lhs.d_impl < rhs.d_impl; } friend bool operator>(const vector& lhs, const vector& rhs) { return lhs.d_impl > rhs.d_impl; } friend bool operator<=(const vector& lhs, const vector& rhs) { return lhs.d_impl <= rhs.d_impl; } friend bool operator>=(const vector& lhs, const vector& rhs) { return lhs.d_impl >= rhs.d_impl; } friend void swap(vector& a, vector& b) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR( a.d_impl.swap(b.d_impl))) { a.d_impl.swap(b.d_impl); } }; #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< SIZE_TYPE, typename bsl::allocator_traits<DEFAULT_ALLOCATOR>::size_type>>, class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>> > vector(SIZE_TYPE, VALUE, ALLOC *) -> vector<VALUE>; // Deduce the template parameter 'VALUE' from the corresponding parameter // supplied to the constructor of 'vector'. 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> > vector(INPUT_ITERATOR, INPUT_ITERATOR) -> vector<VALUE>; // Deduce the template parameter 'VALUE' from the 'value_type' of the // iterators supplied to the constructor of 'vector'. 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>> > vector(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR) -> vector<VALUE, ALLOCATOR>; // Deduce the template parameter 'VALUE' from the 'value_type' of the // iterators supplied to the constructor of 'vector'. 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>> > vector(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *) -> vector<VALUE>; // Deduce the template parameter 'VALUE' from the 'value_type' of the // iterators supplied to the constructor of 'vector'. This deduction // guide does not participate unless the supplied allocator is convertible // to 'bsl::allocator<VALUE>'. template< class VALUE, class ALLOC, class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>, class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>> > vector(std::initializer_list<VALUE>, ALLOC *) -> vector<VALUE>; // Deduce the template parameter 'VALUE' from the 'value_type' of the // initializer_list supplied to the constructor of 'vector'. This // deduction guide does not participate unless the supplied allocator is // convertible to 'bsl::allocator<VALUE>'. #endif // ============================================================================ // TEMPLATE AND INLINE FUNCTION DEFINITIONS // ============================================================================ // See IMPLEMENTATION NOTES in the .cpp before modifying anything below. // ====================================== // class vector_UintPtrConversionIterator // ====================================== template <class VALUE_TYPE, class ITERATOR> class vector_UintPtrConversionIterator { // This class provides a minimal proxy iterator adapter, transforming // pointers to 'uintptr_t' values on the fly, for only the operations // needed to implement the member functions and constructors of the // 'vector' partial template specialization that take iterator ranges as // arguments. While it does not provide a standard conforming iterator // itself, if provides exactly sufficient behavior to implement all the // needed members. 'VALUE_TYPE' shall be a pointer type, and 'ITERATOR' // shall be a standard conforming iterator that dereferences to a type // implicitly convertible to 'VALUE_TYPE' private: // DATA ITERATOR d_iter; public: // PUBLIC TYPES typedef BloombergLP::bsls::Types::UintPtr UintPtr; typedef UintPtr value_type; typedef UintPtr *pointer; typedef UintPtr reference; typedef typename iterator_traits<ITERATOR>::difference_type difference_type; typedef typename iterator_traits<ITERATOR>::iterator_category iterator_category; // CREATORS vector_UintPtrConversionIterator(ITERATOR it); // IMPLICIT // Create a proxy iterator adapting the specified 'it'. // MANIPULATORS vector_UintPtrConversionIterator& operator++(); // Increment this iterator to refer to the next element in the // underlying sequence, and return a reference to this object. // ACCESSORS UintPtr operator*() const; // Return the value of the pointer this iterator refers to, converted // to an unsigned integer. // FRIENDS friend bool operator==(const vector_UintPtrConversionIterator& lhs, const vector_UintPtrConversionIterator& rhs) // Return 'true' if the specified 'lhs' and 'rhs' iterators refer to // the same element in the same underlying sequence or both refer to // the past-the-end element of the same sequence, and 'false' // otherwise. The behavior is undefined if 'lhs' and 'rhs' do not // iterate over the same sequence. { return lhs.d_iter == rhs.d_iter; } friend bool operator!=(const vector_UintPtrConversionIterator& lhs, const vector_UintPtrConversionIterator& rhs) // Return 'true' if the specified 'lhs' and 'rhs' iterators do not // refer to the same element in the same underlying sequence and no // more than one refers to the past-the-end element of the sequence, // and 'false' otherwise. The behavior is undefined if 'lhs' and 'rhs' // do not iterate over the same sequence. { return lhs.d_iter != rhs.d_iter; } friend bool operator<(const vector_UintPtrConversionIterator& lhs, const vector_UintPtrConversionIterator& rhs) // Return 'true' if the specified 'lhs' iterator is earlier in the // underlying sequence than the specified 'rhs' iterator, and 'false' // otherwise. The behavior is undefined if 'lhs' and 'rhs' do not // iterate over the same sequence, or if the (template parameter) type // 'ITERATOR' is not a random access iterator. { return lhs.d_iter < rhs.d_iter; } friend difference_type operator-(const vector_UintPtrConversionIterator& lhs, const vector_UintPtrConversionIterator& rhs) // Return the distance between the specified 'lhs' iterator and the // specified 'rhs' iterator. The behavior is undefined if 'lhs' and // 'rhs' do not iterate over the same sequence, or if the (template // parameter) type 'ITERATOR' is not a random access iterator. { return lhs.d_iter - rhs.d_iter; } }; // -------------------------------------- // class vector_UintPtrConversionIterator // -------------------------------------- // CREATORS template <class VALUE_TYPE, class ITERATOR> inline vector_UintPtrConversionIterator<VALUE_TYPE, ITERATOR>:: vector_UintPtrConversionIterator(ITERATOR it) : d_iter(it) { } // MANIPULATORS template <class VALUE_TYPE, class ITERATOR> inline vector_UintPtrConversionIterator<VALUE_TYPE, ITERATOR>& vector_UintPtrConversionIterator<VALUE_TYPE, ITERATOR>::operator++() { ++d_iter; return *this; } // ACCESSORS template <class VALUE_TYPE, class ITERATOR> inline BloombergLP::bsls::Types::UintPtr vector_UintPtrConversionIterator<VALUE_TYPE, ITERATOR>::operator*() const { VALUE_TYPE const ptr = *d_iter; return reinterpret_cast<UintPtr>(ptr); } // ======================== // class Vector_PushProctor // ======================== template <class VALUE_TYPE, class ALLOCATOR> class Vector_PushProctor { // This class template provides a proctor for a newly created object that // is managed by an allocator. The object will be constructed through a // call to 'allocator_traits<ALLOCATOR>::construct', and it should be // destroyed by a call to 'allocator_traits<ALLOCATOR>::destroy'. Note // that this proctor takes no responsibility for the allocated memory that // the supplied value is constructed in. // DATA VALUE_TYPE *d_target_p; // managed object ALLOCATOR d_allocator; // allocator to be used to destroy managed object private: // NOT IMPLEMENTED Vector_PushProctor(const Vector_PushProctor&); // = delete; Vector_PushProctor& operator=(const Vector_PushProctor&); // = delete; public: // CREATORS Vector_PushProctor(VALUE_TYPE *target, const ALLOCATOR& allocator); // Create a proctor that conditionally manages the specified 'target' // object (if non-zero) by destroying the managed object with a call to // 'allocator_traits<ALLOCATOR>::destroy' using the specified // 'allocator' upon destruction of this proctor, unless the managed // objects has been released. ~Vector_PushProctor(); // Destroy this proctor, and destroy the object it manages (if any) by // a call to 'allocator_traits<ALLOCATOR>::destroy' using the allocator // supplied at construction. If no object is currently being managed, // this method has no effect. // MANIPULATORS void release(); // Release from management the object currently managed by this // proctor. If no object is currently being managed, this method has // no effect. }; // ------------------------ // class Vector_PushProctor // ------------------------ // CREATORS template <class VALUE_TYPE, class ALLOCATOR> inline Vector_PushProctor<VALUE_TYPE,ALLOCATOR>::Vector_PushProctor( VALUE_TYPE *target, const ALLOCATOR& allocator) : d_target_p(target) , d_allocator(allocator) { } template <class VALUE_TYPE, class ALLOCATOR> inline Vector_PushProctor<VALUE_TYPE,ALLOCATOR>::~Vector_PushProctor() { if (d_target_p) { bsl::allocator_traits<ALLOCATOR>::destroy(d_allocator, d_target_p); } } // MANIPULATORS template <class VALUE_TYPE, class ALLOCATOR> inline void Vector_PushProctor<VALUE_TYPE,ALLOCATOR>::release() { d_target_p = 0; } #if defined(BSLS_ASSERT_SAFE_IS_USED) // ----------------------- // class Vector_RangeCheck // ----------------------- template <class BSLSTL_ITERATOR> inline typename enable_if<!Vector_IsRandomAccessIterator<BSLSTL_ITERATOR>::VALUE, bool>::type Vector_RangeCheck::isInvalidRange(BSLSTL_ITERATOR, BSLSTL_ITERATOR) { return false; } template <class BSLSTL_ITERATOR> inline typename enable_if<Vector_IsRandomAccessIterator<BSLSTL_ITERATOR>::VALUE, bool>::type Vector_RangeCheck::isInvalidRange(BSLSTL_ITERATOR first, BSLSTL_ITERATOR last) { return last < first; } #endif // ---------------- // class vectorBase // ---------------- // CREATORS template <class VALUE_TYPE> inline vectorBase<VALUE_TYPE>::vectorBase() : d_dataBegin_p(0) , d_dataEnd_p(0) , d_capacity(0) { } // MANIPULATORS template <class VALUE_TYPE> inline void vectorBase<VALUE_TYPE>::adopt(BloombergLP::bslmf::MovableRef<vectorBase> base) { BSLS_ASSERT_SAFE(0 == d_dataBegin_p); BSLS_ASSERT_SAFE(0 == d_dataEnd_p); BSLS_ASSERT_SAFE(0 == d_capacity); vectorBase& lvalue = base; d_dataBegin_p = lvalue.d_dataBegin_p; d_dataEnd_p = lvalue.d_dataEnd_p; d_capacity = lvalue.d_capacity; lvalue.d_dataBegin_p = 0; lvalue.d_dataEnd_p = 0; lvalue.d_capacity = 0; } // *** iterators *** template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::iterator vectorBase<VALUE_TYPE>::begin() BSLS_KEYWORD_NOEXCEPT { return d_dataBegin_p; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::iterator vectorBase<VALUE_TYPE>::end() BSLS_KEYWORD_NOEXCEPT { return d_dataEnd_p; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::reverse_iterator vectorBase<VALUE_TYPE>::rbegin() BSLS_KEYWORD_NOEXCEPT { return reverse_iterator(end()); } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::reverse_iterator vectorBase<VALUE_TYPE>::rend() BSLS_KEYWORD_NOEXCEPT { return reverse_iterator(begin()); } // *** element access *** template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::reference vectorBase<VALUE_TYPE>::operator[](size_type position) { BSLS_ASSERT_SAFE(size() > position); return d_dataBegin_p[position]; } template <class VALUE_TYPE> typename vectorBase<VALUE_TYPE>::reference vectorBase<VALUE_TYPE>::at(size_type position) { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(position >= size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwOutOfRange( "vector<...>::at(position): invalid position"); } return d_dataBegin_p[position]; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::reference vectorBase<VALUE_TYPE>::front() { BSLS_ASSERT_SAFE(!empty()); return *d_dataBegin_p; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::reference vectorBase<VALUE_TYPE>::back() { BSLS_ASSERT_SAFE(!empty()); return *(d_dataEnd_p - 1); } template <class VALUE_TYPE> inline VALUE_TYPE * vectorBase<VALUE_TYPE>::data() BSLS_KEYWORD_NOEXCEPT { return d_dataBegin_p; } // ACCESSORS // *** iterators *** template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_iterator vectorBase<VALUE_TYPE>::begin() const BSLS_KEYWORD_NOEXCEPT { return d_dataBegin_p; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_iterator vectorBase<VALUE_TYPE>::cbegin() const BSLS_KEYWORD_NOEXCEPT { return d_dataBegin_p; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_iterator vectorBase<VALUE_TYPE>::end() const BSLS_KEYWORD_NOEXCEPT { return d_dataEnd_p; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_iterator vectorBase<VALUE_TYPE>::cend() const BSLS_KEYWORD_NOEXCEPT { return d_dataEnd_p; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_reverse_iterator vectorBase<VALUE_TYPE>::rbegin() const BSLS_KEYWORD_NOEXCEPT { return const_reverse_iterator(end()); } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_reverse_iterator vectorBase<VALUE_TYPE>::crbegin() const BSLS_KEYWORD_NOEXCEPT { return const_reverse_iterator(end()); } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_reverse_iterator vectorBase<VALUE_TYPE>::rend() const BSLS_KEYWORD_NOEXCEPT { return const_reverse_iterator(begin()); } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_reverse_iterator vectorBase<VALUE_TYPE>::crend() const BSLS_KEYWORD_NOEXCEPT { return const_reverse_iterator(begin()); } // *** capacity *** template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::size_type vectorBase<VALUE_TYPE>::size() const BSLS_KEYWORD_NOEXCEPT { return d_dataEnd_p - d_dataBegin_p; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::size_type vectorBase<VALUE_TYPE>::capacity() const BSLS_KEYWORD_NOEXCEPT { return d_capacity; } template <class VALUE_TYPE> inline bool vectorBase<VALUE_TYPE>::empty() const BSLS_KEYWORD_NOEXCEPT { return d_dataEnd_p == d_dataBegin_p; } // *** element access *** template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_reference vectorBase<VALUE_TYPE>::operator[](size_type position) const { BSLS_ASSERT_SAFE(size() > position); return d_dataBegin_p[position]; } template <class VALUE_TYPE> typename vectorBase<VALUE_TYPE>::const_reference vectorBase<VALUE_TYPE>::at(size_type position) const { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(position >= size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwOutOfRange( "const vector<...>::at(position): invalid position"); } return d_dataBegin_p[position]; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_reference vectorBase<VALUE_TYPE>::front() const { BSLS_ASSERT_SAFE(!empty()); return *d_dataBegin_p; } template <class VALUE_TYPE> inline typename vectorBase<VALUE_TYPE>::const_reference vectorBase<VALUE_TYPE>::back() const { BSLS_ASSERT_SAFE(!empty()); return *(d_dataEnd_p - 1); } template <class VALUE_TYPE> inline const VALUE_TYPE * vectorBase<VALUE_TYPE>::data() const BSLS_KEYWORD_NOEXCEPT { return d_dataBegin_p; } // -------------------------------------------- // class vector<VALUE_TYPE, ALLOCATOR>::Proctor // -------------------------------------------- // CREATORS template <class VALUE_TYPE, class ALLOCATOR> BSLS_PLATFORM_AGGRESSIVE_INLINE vector<VALUE_TYPE, ALLOCATOR>::Proctor::Proctor(VALUE_TYPE *data, std::size_t capacity, ContainerBase *container) : d_data_p(data) , d_capacity(capacity) , d_container_p(container) { } template <class VALUE_TYPE, class ALLOCATOR> BSLS_PLATFORM_AGGRESSIVE_INLINE vector<VALUE_TYPE, ALLOCATOR>::Proctor::~Proctor() { if (d_data_p) { d_container_p->deallocateN(d_data_p, d_capacity); } } // MANIPULATORS template <class VALUE_TYPE, class ALLOCATOR> BSLS_PLATFORM_AGGRESSIVE_INLINE void vector<VALUE_TYPE, ALLOCATOR>::Proctor::release() { d_data_p = 0; } // ------------ // class vector // ------------ // PRIVATE MANIPULATORS template <class VALUE_TYPE, class ALLOCATOR> template <class FWD_ITER> void vector<VALUE_TYPE, ALLOCATOR>::constructFromRange( FWD_ITER first, FWD_ITER last, std::forward_iterator_tag) { // Specialization for all iterators except input iterators: 'size' can be // computed in advance. BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last)); const size_type maxSize = max_size(); const size_type newSize = bsl::distance(first, last); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(newSize > maxSize)) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::(range-constructor): input too long"); } size_type newCapacity = Vector_Util::computeNewCapacity(newSize, 0, maxSize); this->privateReserveEmpty(newCapacity); Proctor proctor(this->d_dataBegin_p, this->d_capacity, static_cast<ContainerBase *>(this)); ArrayPrimitives::copyConstruct(this->d_dataEnd_p, first, last, ContainerBase::allocator()); proctor.release(); this->d_dataEnd_p += newSize; } template <class VALUE_TYPE, class ALLOCATOR> template <class INPUT_ITER> void vector<VALUE_TYPE, ALLOCATOR>::constructFromRange( INPUT_ITER first, INPUT_ITER last, std::input_iterator_tag) { // IMPLEMENTATION NOTES: construct this vector by iterated 'push_back', // which may reallocate memory multiple times, but unfortunately is // required because we can't compute the size in advance (as with // 'forward_iterator_tag') because input iterators can be traversed only // once. A temporary vector is populated and then swapped to ensure that // all memory is reclaimed if 'emplace_back' throws, as the destructor will // not run when this method is called from a constructor. vector temp(this->get_allocator()); while (first != last) { temp.emplace_back(*first); ++first; } Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } template <class VALUE_TYPE, class ALLOCATOR> template <class INTEGRAL> void vector<VALUE_TYPE, ALLOCATOR>::constructFromRange( INTEGRAL initialSize, INTEGRAL value, BloombergLP::bslmf::Nil) { // IMPLEMENTATION NOTES: this constructor is trying to construct a range of // 'initialSize' elements having the specified integral 'value'. Without // this extra overload, such calls would match an attempt to construct from // a range specified by two iterators. Note that as 'VALUE_TYPE' must be // a (trivial) integral type, a proctor is almost certainly not needed. // The only risk of a throw is for user-defined allocators doing strange // extra (potentially throwing) work in their 'construct' call. if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY( static_cast<size_type>(initialSize) > max_size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::(repeated-value constructor): input too long"); } if (initialSize > 0) { privateReserveEmpty(initialSize); Proctor proctor(this->d_dataBegin_p, this->d_capacity, static_cast<ContainerBase *>(this)); ArrayPrimitives::uninitializedFillN(this->d_dataBegin_p, initialSize, static_cast<VALUE_TYPE>(value), ContainerBase::allocator()); proctor.release(); this->d_dataEnd_p += initialSize; } } template <class VALUE_TYPE, class ALLOCATOR> template <class INPUT_ITER> inline void vector<VALUE_TYPE, ALLOCATOR>::privateInsertDispatch( const_iterator position, INPUT_ITER count, INPUT_ITER value, BloombergLP::bslmf::MatchArithmeticType , BloombergLP::bslmf::Nil ) { // 'count' and 'value' are integral types that just happen to be the same. // They are not iterators, so we call 'insert(position, count, value)'. this->insert(position, static_cast<size_type>(count), static_cast<VALUE_TYPE>(value)); } template <class VALUE_TYPE, class ALLOCATOR> template <class INPUT_ITER> inline void vector<VALUE_TYPE, ALLOCATOR>::privateInsertDispatch( const_iterator position, INPUT_ITER first, INPUT_ITER last, BloombergLP::bslmf::MatchAnyType , BloombergLP::bslmf::MatchAnyType ) { // Dispatch based on iterator category. BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last)); typedef typename iterator_traits<INPUT_ITER>::iterator_category Tag; this->privateInsert(position, first, last, Tag()); } template <class VALUE_TYPE, class ALLOCATOR> template <class INPUT_ITER> void vector<VALUE_TYPE, ALLOCATOR>::privateInsert( const_iterator position, INPUT_ITER first, INPUT_ITER last, const std::input_iterator_tag&) { // IMPLEMENTATION NOTES: We can't compute the size in advance. Append onto // the back of the current vector while capacity remains. This honors the // idea of not allocating unnecessarily for the temporary vector, and so // saves important cycles from a sequential allocator. We then need to // shuffle the data back into the correct position. If capacity must grow, // then create a new vector and move just the newly inserted elements into // place, moving the original vector elements only in the event that all // iterated elements are correctly inserted. // Short-circuit if there is nothing to do, do not allocate for an empty // 'vector' as that would invalidate 'begin'. if (first == last) { return; // RETURN } if (!this->capacity()) { privateReserveEmpty(size_type(1)); position = this->d_dataBegin_p; // 'position' must have been null } size_type insertOffset = position - this->d_dataBegin_p; size_type initialEnd = this->size(); size_type tailLength = this->end() - position; VALUE_TYPE *emplaceBegin = this->d_dataEnd_p; VALUE_TYPE *emplaceEnd = this->d_dataBegin_p + this->d_capacity; VALUE_TYPE *emplacePosition = emplaceBegin; allocator_type alloc(this->get_allocator()); // need non-'const' lvalue vector resultState(alloc); // vector that will build the final state // This vector is not used if sufficient capacity can be found in the // current vector for all the insertions. However, it must have a // lifetime longer than the destructor guard below, in order to ensure // that the guarded elements are destroyed before the allocated storage // that holds them if an exception is thrown. // TBD: We really need an allocator-aware 'AutoDestructor' that will call // 'allocator_traits<ALLOC>::destroy(allocator, pointer)' rather than // invoke the destructor directly. 'bslalg::AutoArrayDestructor' is close, // but lacks 'reset'. BloombergLP::bslma::AutoDestructor<VALUE_TYPE> insertProctor( emplacePosition); while (emplacePosition != emplaceEnd) { AllocatorTraits::construct(alloc, emplacePosition, *first); ++insertProctor; ++emplacePosition; if (++first == last) { this->d_dataEnd_p = emplacePosition; insertProctor.release(); ArrayPrimitives::rotate(this->d_dataBegin_p + insertOffset, this->d_dataBegin_p + initialEnd, this->d_dataEnd_p); return; // RETURN } } // Now we need to grow a buffer and destructive-move only the new elements. // This needs to be handled in a loop that can allow for multiple growth // spurts. resultState.reserve(this->d_capacity*2); emplacePosition = resultState.d_dataBegin_p + insertOffset; ArrayPrimitives::destructiveMove(emplacePosition, emplaceBegin, emplaceEnd, alloc); size_type emplaceOffset = (emplaceEnd - emplaceBegin); insertProctor.reset(emplacePosition); emplaceBegin = emplacePosition; emplaceEnd = resultState.d_dataBegin_p + resultState.d_capacity - tailLength; emplacePosition += emplaceOffset; while (first != last) { if (emplacePosition == emplaceEnd) { // need to grow again vector nextResult(alloc); nextResult.reserve(resultState.d_capacity*2); emplacePosition = nextResult.d_dataBegin_p + insertOffset; ArrayPrimitives::destructiveMove(emplacePosition, emplaceBegin, emplaceEnd, alloc); insertProctor.reset(emplacePosition); emplaceOffset = (emplaceEnd - emplaceBegin); emplaceBegin = emplacePosition; emplaceEnd = nextResult.d_dataBegin_p + nextResult.d_capacity - tailLength; emplacePosition += emplaceOffset; Vector_Util::swap(&nextResult.d_dataBegin_p, &resultState.d_dataBegin_p); } AllocatorTraits::construct(alloc, emplacePosition, *first); ++insertProctor; ++emplacePosition; ++first; } // move tail ArrayPrimitives::destructiveMove(emplacePosition, this->d_dataBegin_p + insertOffset, this->d_dataBegin_p + initialEnd, alloc); // reset 'end' in case a throw follows: this->d_dataEnd_p = this->d_dataBegin_p + insertOffset; emplacePosition += (initialEnd - insertOffset); insertProctor.setLength( insertProctor.length() + static_cast<int>(initialEnd - insertOffset)); // move prefix ArrayPrimitives::destructiveMove(resultState.d_dataBegin_p, this->d_dataBegin_p, this->d_dataBegin_p + insertOffset, alloc); // Nothing after this point can throw. // 'resultState' adopts ownership of all elements resultState.d_dataEnd_p = emplacePosition; // We no longer own any data to protect insertProctor.release(); this->d_dataEnd_p = this->d_dataBegin_p; // Finally, swap states Vector_Util::swap(&this->d_dataBegin_p, &resultState.d_dataBegin_p); } template <class VALUE_TYPE, class ALLOCATOR> template <class FWD_ITER> void vector<VALUE_TYPE, ALLOCATOR>::privateInsert( const_iterator position, FWD_ITER first, FWD_ITER last, const std::forward_iterator_tag&) { // Specialization for all iterators except input iterators: 'size' can be // computed in advance. BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last)); const iterator& pos = const_cast<iterator>(position); const size_type maxSize = max_size(); const size_type n = bsl::distance(first, last); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(n > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::insert(pos,first,last): vector too long"); } const size_type newSize = this->size() + n; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndInsert(temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, first, last, n, ContainerBase::allocator()); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::insert(pos, this->end(), first, last, n, ContainerBase::allocator()); this->d_dataEnd_p += n; } } template <class VALUE_TYPE, class ALLOCATOR> void vector<VALUE_TYPE, ALLOCATOR>::privateMoveInsert( vector *fromVector, const_iterator position) { const iterator& pos = const_cast<const iterator&>(position); const size_type maxSize = max_size(); const size_type n = fromVector->size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(n > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::insert(pos,first,last): vector too long"); } const size_type newSize = this->size() + n; if (newSize > this->d_capacity) { const size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndMoveInsert( temp.d_dataBegin_p, &this->d_dataEnd_p, &fromVector->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, fromVector->d_dataBegin_p, fromVector->d_dataEnd_p, n, ContainerBase::allocator()); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::moveInsert(pos, this->end(), &fromVector->d_dataEnd_p, fromVector->d_dataBegin_p, fromVector->d_dataEnd_p, n, ContainerBase::allocator()); this->d_dataEnd_p += n; } } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE, ALLOCATOR>::privateReserveEmpty(size_type numElements) { BSLS_ASSERT_SAFE(this->empty()); BSLS_ASSERT_SAFE(0 == this->capacity()); this->d_dataBegin_p = this->d_dataEnd_p = this->allocateN( (VALUE_TYPE *) 0, numElements); this->d_capacity = numElements; } // CREATORS // *** construct/copy/destroy *** template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE, ALLOCATOR>::vector() BSLS_KEYWORD_NOEXCEPT : vectorBase<VALUE_TYPE>() , ContainerBase(ALLOCATOR()) { } template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE, ALLOCATOR>::vector(const ALLOCATOR& basicAllocator) BSLS_KEYWORD_NOEXCEPT : vectorBase<VALUE_TYPE>() , ContainerBase(basicAllocator) { } template <class VALUE_TYPE, class ALLOCATOR> vector<VALUE_TYPE, ALLOCATOR>::vector(size_type initialSize, const ALLOCATOR& basicAllocator) : vectorBase<VALUE_TYPE>() , ContainerBase(basicAllocator) { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(initialSize > max_size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::vector(n,v): vector too long"); } if (initialSize > 0) { privateReserveEmpty(initialSize); Proctor proctor(this->d_dataBegin_p, this->d_capacity, static_cast<ContainerBase *>(this)); ArrayPrimitives::defaultConstruct(this->d_dataBegin_p, initialSize, ContainerBase::allocator()); proctor.release(); this->d_dataEnd_p += initialSize; } } template <class VALUE_TYPE, class ALLOCATOR> vector<VALUE_TYPE, ALLOCATOR>::vector(size_type initialSize, const VALUE_TYPE& value, const ALLOCATOR& basicAllocator) : vectorBase<VALUE_TYPE>() , ContainerBase(basicAllocator) { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(initialSize > max_size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::vector(n,v): vector too long"); } if (initialSize > 0) { privateReserveEmpty(initialSize); Proctor proctor(this->d_dataBegin_p, this->d_capacity, static_cast<ContainerBase *>(this)); ArrayPrimitives::uninitializedFillN(this->d_dataBegin_p, initialSize, value, ContainerBase::allocator()); proctor.release(); this->d_dataEnd_p += initialSize; } } template <class VALUE_TYPE, class ALLOCATOR> template <class INPUT_ITER> BSLS_PLATFORM_AGGRESSIVE_INLINE vector<VALUE_TYPE, ALLOCATOR>::vector(INPUT_ITER first, INPUT_ITER last, const ALLOCATOR& basicAllocator) : vectorBase<VALUE_TYPE>() , ContainerBase(basicAllocator) { BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last)); typedef typename Vector_DeduceIteratorCategory<INPUT_ITER>::type Tag; if (is_same<Tag, BloombergLP::bslmf::Nil>::value || first != last) { // Range-check avoids allocating on an empty sequence. constructFromRange(first, last, Tag()); } } template <class VALUE_TYPE, class ALLOCATOR> vector<VALUE_TYPE, ALLOCATOR>::vector(const vector& original) : vectorBase<VALUE_TYPE>() , ContainerBase(AllocatorTraits::select_on_container_copy_construction( original.ContainerBase::allocator())) { if (original.size() > 0) { privateReserveEmpty(original.size()); Proctor proctor(this->d_dataBegin_p, this->d_capacity, static_cast<ContainerBase *>(this)); ArrayPrimitives::copyConstruct(this->d_dataBegin_p, original.begin(), original.end(), ContainerBase::allocator()); proctor.release(); this->d_dataEnd_p += original.size(); } } template <class VALUE_TYPE, class ALLOCATOR> vector<VALUE_TYPE, ALLOCATOR>:: vector(const vector& original, const typename type_identity<ALLOCATOR>::type& basicAllocator) : vectorBase<VALUE_TYPE>() , ContainerBase(basicAllocator) { if (original.size() > 0) { privateReserveEmpty(original.size()); Proctor proctor(this->d_dataBegin_p, this->d_capacity, static_cast<ContainerBase *>(this)); ArrayPrimitives::copyConstruct(this->d_dataBegin_p, original.begin(), original.end(), ContainerBase::allocator()); proctor.release(); this->d_dataEnd_p += original.size(); } } template <class VALUE_TYPE, class ALLOCATOR> vector<VALUE_TYPE, ALLOCATOR>::vector( BloombergLP::bslmf::MovableRef<vector> original) BSLS_KEYWORD_NOEXCEPT : vectorBase<VALUE_TYPE>() , ContainerBase(MoveUtil::access(original).get_allocator()) { vector& lvalue = original; ImpBase::adopt(MoveUtil::move(static_cast<ImpBase&>(lvalue))); } template <class VALUE_TYPE, class ALLOCATOR> vector<VALUE_TYPE, ALLOCATOR>::vector( BloombergLP::bslmf::MovableRef<vector> original, const typename type_identity<ALLOCATOR>::type& basicAllocator) : vectorBase<VALUE_TYPE>() , ContainerBase(basicAllocator) { vector& lvalue = original; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(get_allocator() == lvalue.get_allocator())) { ImpBase::adopt(MoveUtil::move(static_cast<ImpBase&>(lvalue))); } else { if (lvalue.size() > 0) { privateReserveEmpty(lvalue.size()); Proctor proctor(this->d_dataBegin_p, this->d_capacity, static_cast<ContainerBase *>(this)); ArrayPrimitives::moveConstruct(this->d_dataBegin_p, lvalue.begin(), lvalue.end(), ContainerBase::allocator()); proctor.release(); this->d_dataEnd_p += lvalue.size(); } } } #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE, ALLOCATOR>::vector( std::initializer_list<VALUE_TYPE> values, const ALLOCATOR& basicAllocator) : vectorBase<VALUE_TYPE>() , ContainerBase(basicAllocator) { if (values.begin() != values.end()) { constructFromRange(values.begin(), values.end(), std::random_access_iterator_tag()); } } #endif template <class VALUE_TYPE, class ALLOCATOR> BSLS_PLATFORM_AGGRESSIVE_INLINE vector<VALUE_TYPE, ALLOCATOR>::~vector() { if (this->d_dataBegin_p) { BloombergLP::bslalg::ArrayDestructionPrimitives::destroy( this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); this->deallocateN(this->d_dataBegin_p, this->d_capacity); } } // MANIPULATORS template <class VALUE_TYPE, class ALLOCATOR> vector<VALUE_TYPE, ALLOCATOR>& vector<VALUE_TYPE, ALLOCATOR>::operator=(const vector& rhs) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &rhs)) { if (AllocatorTraits::propagate_on_container_copy_assignment::value) { vector other(rhs, rhs.get_allocator()); Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p); using std::swap; swap(ContainerBase::allocator(), other.ContainerBase::allocator()); } else { // Invoke 'erase' only if the current vector is not empty. if (!this->empty()) { erase(this->begin(), this->end()); } insert(this->begin(), rhs.begin(), rhs.end()); } } return *this; } template <class VALUE_TYPE, class ALLOCATOR> vector<VALUE_TYPE, ALLOCATOR>& vector<VALUE_TYPE, ALLOCATOR>::operator=( BloombergLP::bslmf::MovableRef<vector<VALUE_TYPE, ALLOCATOR> > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION( AllocatorTraits::propagate_on_container_move_assignment::value || AllocatorTraits::is_always_equal::value) { vector& lvalue = rhs; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &lvalue)) { if (get_allocator() == lvalue.get_allocator()) { vector other(MoveUtil::move(lvalue)); Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p); } else if (AllocatorTraits:: propagate_on_container_move_assignment::value) { vector other(MoveUtil::move(lvalue)); using std::swap; swap(ContainerBase::allocator(), other.ContainerBase::allocator()); Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p); } else { vector other(MoveUtil::move(lvalue), ContainerBase::allocator()); Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p); } } return *this; } #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE, ALLOCATOR>& vector<VALUE_TYPE, ALLOCATOR>::operator=( std::initializer_list<VALUE_TYPE> values) { this->assign(values.begin(), values.end()); return *this; } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE, ALLOCATOR>::assign( std::initializer_list<VALUE_TYPE> values) { assign(values.begin(), values.end()); } #endif template <class VALUE_TYPE, class ALLOCATOR> template <class INPUT_ITER> inline void vector<VALUE_TYPE, ALLOCATOR>::assign(INPUT_ITER first, INPUT_ITER last) { BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last)); if (!this->empty()) { erase(this->begin(), this->end()); } insert(this->begin(), first, last); } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE, ALLOCATOR>::assign(size_type numElements, const VALUE_TYPE& value) { if (!this->empty()) { erase(this->begin(), this->end()); } insert(this->begin(), numElements, value); } // *** capacity *** template <class VALUE_TYPE, class ALLOCATOR> void vector<VALUE_TYPE, ALLOCATOR>::resize(size_type newSize) { // This function provides the *strong* exception guarantee (except when // the move constructor of a non-copy-insertable 'value_type' throws). // Cannot use copy constructor since the only requirements on 'VALUE_TYPE' // are 'move-insertable' and 'default-constructible'. if (newSize <= this->size()) { BloombergLP::bslalg::ArrayDestructionPrimitives::destroy( this->d_dataBegin_p + newSize, this->d_dataEnd_p, ContainerBase::allocator()); this->d_dataEnd_p = this->d_dataBegin_p + newSize; } else if (0 == this->d_capacity) { // Because of {DRQS 99966534}, we check for zero capacity here and // handle it separately rather than falling into the case below. vector temp(newSize, this->get_allocator()); Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else if (newSize > this->d_capacity) { const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(newSize > maxSize)) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::resize(n): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndInsert( temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, this->d_dataEnd_p, this->d_dataEnd_p, newSize - this->size(), ContainerBase::allocator()); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::defaultConstruct(this->d_dataEnd_p, newSize - this->size(), ContainerBase::allocator()); this->d_dataEnd_p = this->d_dataBegin_p + newSize; } } template <class VALUE_TYPE, class ALLOCATOR> void vector<VALUE_TYPE, ALLOCATOR>::resize(size_type newSize, const VALUE_TYPE& value) { // This function provides the *strong* exception guarantee (except when // the move constructor of a non-copy-insertable 'value_type' throws). if (newSize <= this->size()) { BloombergLP::bslalg::ArrayDestructionPrimitives::destroy( this->d_dataBegin_p + newSize, this->d_dataEnd_p, ContainerBase::allocator()); this->d_dataEnd_p = this->d_dataBegin_p + newSize; } else { insert(this->d_dataEnd_p, newSize - this->size(), value); } } template <class VALUE_TYPE, class ALLOCATOR> void vector<VALUE_TYPE, ALLOCATOR>::reserve(size_type newCapacity) { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(newCapacity > max_size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::reserve(newCapacity): vector too long"); } if (0 == this->d_capacity && 0 != newCapacity) { privateReserveEmpty(newCapacity); } else if (this->d_capacity < newCapacity) { vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); temp.d_dataEnd_p += this->size(); this->d_dataEnd_p = this->d_dataBegin_p; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } } template <class VALUE_TYPE, class ALLOCATOR> void vector<VALUE_TYPE, ALLOCATOR>::shrink_to_fit() { if (this->size() < this->d_capacity) { vector temp(this->get_allocator()); temp.privateReserveEmpty(this->size()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); temp.d_dataEnd_p += this->size(); this->d_dataEnd_p = this->d_dataBegin_p; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } } // *** modifiers *** #if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES // {{{ BEGIN GENERATED CODE // Command line: sim_cpp11_features.pl bslstl_vector.h #ifndef BSLSTL_VECTOR_VARIADIC_LIMIT #define BSLSTL_VECTOR_VARIADIC_LIMIT 10 #endif #ifndef BSLSTL_VECTOR_VARIADIC_LIMIT_C #define BSLSTL_VECTOR_VARIADIC_LIMIT_C BSLSTL_VECTOR_VARIADIC_LIMIT #endif #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 0 template <class VALUE_TYPE, class ALLOCATOR> inline VALUE_TYPE & vector<VALUE_TYPE, ALLOCATOR>::emplace_back( ) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 0 #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 1 template <class VALUE_TYPE, class ALLOCATOR> template <class Args_01> inline VALUE_TYPE & vector<VALUE_TYPE, ALLOCATOR>::emplace_back( BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01)); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 1 #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 2 template <class VALUE_TYPE, class ALLOCATOR> template <class Args_01, class Args_02> inline VALUE_TYPE & vector<VALUE_TYPE, ALLOCATOR>::emplace_back( BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01), BSLS_COMPILERFEATURES_FORWARD(Args_02, arguments_02)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01), BSLS_COMPILERFEATURES_FORWARD(Args_02, arguments_02)); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 2 #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 3 template <class VALUE_TYPE, class ALLOCATOR> template <class Args_01, class Args_02, class Args_03> inline VALUE_TYPE & vector<VALUE_TYPE, 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) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01), BSLS_COMPILERFEATURES_FORWARD(Args_02, arguments_02), BSLS_COMPILERFEATURES_FORWARD(Args_03, arguments_03)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, BSLS_COMPILERFEATURES_FORWARD(Args_01, arguments_01), BSLS_COMPILERFEATURES_FORWARD(Args_02, arguments_02), BSLS_COMPILERFEATURES_FORWARD(Args_03, arguments_03)); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 3 #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 4 template <class VALUE_TYPE, class ALLOCATOR> template <class Args_01, class Args_02, class Args_03, class Args_04> inline VALUE_TYPE & vector<VALUE_TYPE, 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) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, 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)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, 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)); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 4 #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 5 template <class VALUE_TYPE, class ALLOCATOR> template <class Args_01, class Args_02, class Args_03, class Args_04, class Args_05> inline VALUE_TYPE & vector<VALUE_TYPE, 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) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, 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)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, 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)); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 5 #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 6 template <class VALUE_TYPE, class ALLOCATOR> template <class Args_01, class Args_02, class Args_03, class Args_04, class Args_05, class Args_06> inline VALUE_TYPE & vector<VALUE_TYPE, 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) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, 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)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, 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)); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 6 #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 7 template <class VALUE_TYPE, 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 VALUE_TYPE & vector<VALUE_TYPE, 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) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, 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)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, 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)); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 7 #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 8 template <class VALUE_TYPE, 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 VALUE_TYPE & vector<VALUE_TYPE, 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) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, 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)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, 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)); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 8 #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 9 template <class VALUE_TYPE, 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 VALUE_TYPE & vector<VALUE_TYPE, 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) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, 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)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, 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)); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 9 #if BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 10 template <class VALUE_TYPE, 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 VALUE_TYPE & vector<VALUE_TYPE, 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) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, 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)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, 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)); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } #endif // BSLSTL_VECTOR_VARIADIC_LIMIT_C >= 10 #else // The generated code below is a workaround for the absence of perfect // forwarding in some compilers. template <class VALUE_TYPE, class ALLOCATOR> template <class... Args> inline VALUE_TYPE & vector<VALUE_TYPE, ALLOCATOR>::emplace_back( BSLS_COMPILERFEATURES_FORWARD_REF(Args)...arguments) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct( ContainerBase::allocator(), this->d_dataEnd_p, BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:emplace_back(args...): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct( ContainerBase::allocator(), pos, BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...); Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } return *(this->d_dataEnd_p - 1); } // }}} END GENERATED CODE #endif template <class VALUE_TYPE, class ALLOCATOR> void vector<VALUE_TYPE, ALLOCATOR>::push_back(const VALUE_TYPE& value) { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct(ContainerBase::allocator(), this->d_dataEnd_p, value); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:push_back(lvalue): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); // Construct before we risk invalidating the reference VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct(ContainerBase::allocator(), pos, value); // Nothing else should throw, but probably worth guarding the above // 'construct' call for types with potentially-throwing destructive // moves. Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); guard.release(); // Nothing after this can throw this->d_dataEnd_p = this->d_dataBegin_p; temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } } template <class VALUE_TYPE, class ALLOCATOR> void vector<VALUE_TYPE, ALLOCATOR>::push_back( BloombergLP::bslmf::MovableRef<VALUE_TYPE> value) { VALUE_TYPE& lvalue = value; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) { AllocatorTraits::construct(ContainerBase::allocator(), this->d_dataEnd_p, MoveUtil::move(lvalue)); ++this->d_dataEnd_p; } else { if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(this->size() == max_size())){ BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>:push_back(rvalue): vector too long"); } size_type newCapacity = Vector_Util::computeNewCapacity( this->size() + 1, this->d_capacity, this->max_size()); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); // Construct before we risk invalidating the reference VALUE_TYPE *pos = temp.d_dataBegin_p + this->size(); AllocatorTraits::construct(ContainerBase::allocator(), pos, MoveUtil::move(lvalue)); // Nothing else should throw, but probably worth guarding the above // 'construct' call for types with potentially-throwing destructive // moves. Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard( pos, ContainerBase::allocator()); ArrayPrimitives::destructiveMove(temp.d_dataBegin_p, this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); this->d_dataEnd_p = this->d_dataBegin_p; guard.release(); // Nothing after this can throw temp.d_dataEnd_p = ++pos; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE, ALLOCATOR>::pop_back() { BSLS_ASSERT_SAFE(!this->empty()); AllocatorTraits::destroy(ContainerBase::allocator(), --this->d_dataEnd_p); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE, ALLOCATOR>::iterator vector<VALUE_TYPE, ALLOCATOR>::insert(const_iterator position, const VALUE_TYPE& value) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); return insert(position, size_type(1), value); } template <class VALUE_TYPE, class ALLOCATOR> typename vector<VALUE_TYPE, ALLOCATOR>::iterator vector<VALUE_TYPE, ALLOCATOR>::insert( const_iterator position, BloombergLP::bslmf::MovableRef<VALUE_TYPE> value) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::insert(pos,rv): vector too long"); } VALUE_TYPE& lvalue = value; const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type newSize = this->size() + 1; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndEmplace(temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, ContainerBase::allocator(), MoveUtil::move(lvalue)); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::insert(pos, this->end(), MoveUtil::move(lvalue), ContainerBase::allocator()); ++this->d_dataEnd_p; } return this->begin() + index; } template <class VALUE_TYPE, class ALLOCATOR> typename vector<VALUE_TYPE, ALLOCATOR>::iterator vector<VALUE_TYPE, ALLOCATOR>::insert(const_iterator position, size_type numElements, const VALUE_TYPE& value) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position <= this->end()); const size_type maxSize = max_size(); if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY( numElements > maxSize - this->size())) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; BloombergLP::bslstl::StdExceptUtil::throwLengthError( "vector<...>::insert(pos,n,v): vector too long"); } const size_type index = position - this->begin(); const iterator& pos = const_cast<const iterator&>(position); const size_type newSize = this->size() + numElements; if (newSize > this->d_capacity) { size_type newCapacity = Vector_Util::computeNewCapacity( newSize, this->d_capacity, maxSize); vector temp(this->get_allocator()); temp.privateReserveEmpty(newCapacity); ArrayPrimitives::destructiveMoveAndInsert(temp.d_dataBegin_p, &this->d_dataEnd_p, this->d_dataBegin_p, pos, this->d_dataEnd_p, value, numElements, ContainerBase::allocator()); temp.d_dataEnd_p += newSize; Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p); } else { ArrayPrimitives::insert(pos, this->end(), value, numElements, ContainerBase::allocator()); this->d_dataEnd_p += numElements; } return this->begin() + index; } #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE, ALLOCATOR>::iterator vector<VALUE_TYPE, ALLOCATOR>::insert( const_iterator position, std::initializer_list<VALUE_TYPE> values) { return insert(position, values.begin(), values.end()); } #endif template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE, ALLOCATOR>::iterator vector<VALUE_TYPE, ALLOCATOR>::erase(const_iterator position) { BSLS_ASSERT_SAFE(this->begin() <= position); BSLS_ASSERT_SAFE(position < this->end()); return erase(position, position + 1); } // This should not be inlined by default due to an XLC 16 compiler bug whereby // optimized code can spuriously core dump. This has been reported to IBM, see // DRQS 169655225 for details. template <class VALUE_TYPE, class ALLOCATOR> BSLS_PLATFORM_AGGRESSIVE_INLINE typename vector<VALUE_TYPE, ALLOCATOR>::iterator vector<VALUE_TYPE, ALLOCATOR>::erase(const_iterator first, const_iterator last) { BSLS_ASSERT_SAFE(this->begin() <= first); BSLS_ASSERT_SAFE(first <= this->end()); BSLS_ASSERT_SAFE(first <= last); BSLS_ASSERT_SAFE(last <= this->end()); const size_type n = last - first; ArrayPrimitives::erase(const_cast<VALUE_TYPE *>(first), const_cast<VALUE_TYPE *>(last), this->d_dataEnd_p, ContainerBase::allocator()); this->d_dataEnd_p -= n; return const_cast<VALUE_TYPE *>(first); } template <class VALUE_TYPE, class ALLOCATOR> void vector<VALUE_TYPE, ALLOCATOR>::swap(vector<VALUE_TYPE, ALLOCATOR>& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION( AllocatorTraits::propagate_on_container_swap::value || AllocatorTraits::is_always_equal::value) { if (AllocatorTraits::propagate_on_container_swap::value) { Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p); using std::swap; swap(ContainerBase::allocator(), other.ContainerBase::allocator()); } else { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY( this->get_allocator() == other.get_allocator())) { Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p); } else { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; vector toOtherCopy(MoveUtil::move(*this), other.get_allocator()); vector toThisCopy( MoveUtil::move(other), this->get_allocator()); Vector_Util::swap(&toOtherCopy.d_dataBegin_p, &other.d_dataBegin_p); Vector_Util::swap(&toThisCopy. d_dataBegin_p, &this->d_dataBegin_p); } } } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE, ALLOCATOR>::clear() BSLS_KEYWORD_NOEXCEPT { if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(!this->empty())) { BloombergLP::bslalg::ArrayDestructionPrimitives::destroy( this->d_dataBegin_p, this->d_dataEnd_p, ContainerBase::allocator()); this->d_dataEnd_p = this->d_dataBegin_p; } else { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; } } // ACCESSORS template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE, ALLOCATOR>::allocator_type vector<VALUE_TYPE, ALLOCATOR>::get_allocator() const BSLS_KEYWORD_NOEXCEPT { return ContainerBase::allocator(); } // *** capacity *** template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE, ALLOCATOR>::size_type vector<VALUE_TYPE, ALLOCATOR>::max_size() const BSLS_KEYWORD_NOEXCEPT { return AllocatorTraits::max_size(ContainerBase::allocator()); } // FREE OPERATORS // *** relational operators *** template <class VALUE_TYPE, class ALLOCATOR> inline bool operator==(const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs) { return BloombergLP::bslalg::RangeCompare::equal(lhs.begin(), lhs.end(), lhs.size(), rhs.begin(), rhs.end(), rhs.size()); } template <class VALUE_TYPE, class ALLOCATOR> inline bool operator!=(const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs) { return ! (lhs == rhs); } template <class VALUE_TYPE, class ALLOCATOR> inline bool operator< (const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs) { return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.begin(), lhs.end(), lhs.size(), rhs.begin(), rhs.end(), rhs.size()); } template <class VALUE_TYPE, class ALLOCATOR> inline bool operator> (const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs) { return rhs < lhs; } template <class VALUE_TYPE, class ALLOCATOR> inline bool operator<=(const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs) { return !(rhs < lhs); } template <class VALUE_TYPE, class ALLOCATOR> inline bool operator>=(const vector<VALUE_TYPE, ALLOCATOR>& lhs, const vector<VALUE_TYPE, ALLOCATOR>& rhs) { return !(lhs < rhs); } // FREE FUNCTIONS // *** specialized algorithms *** template <class VALUE_TYPE, class ALLOCATOR, class BDE_OTHER_TYPE> inline typename vector<VALUE_TYPE, ALLOCATOR>::size_type erase(vector<VALUE_TYPE, ALLOCATOR>& vec, const BDE_OTHER_TYPE& value) { typename vector<VALUE_TYPE, ALLOCATOR>::size_type oldSize = vec.size(); vec.erase(bsl::remove(vec.begin(), vec.end(), value), vec.end()); return oldSize - vec.size(); } template <class VALUE_TYPE, class ALLOCATOR, class PREDICATE> inline typename vector<VALUE_TYPE, ALLOCATOR>::size_type erase_if(vector<VALUE_TYPE, ALLOCATOR>& vec, PREDICATE predicate) { typename vector<VALUE_TYPE, ALLOCATOR>::size_type oldSize = vec.size(); vec.erase(bsl::remove_if(vec.begin(), vec.end(), predicate), vec.end()); return oldSize - vec.size(); } template <class VALUE_TYPE, class ALLOCATOR> inline void swap(vector<VALUE_TYPE, ALLOCATOR>& a, vector<VALUE_TYPE, ALLOCATOR>& b) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR( a.swap(b))) { a.swap(b); } // HASH SPECIALIZATIONS template <class HASHALG, class VALUE_TYPE, class ALLOCATOR> inline void hashAppend(HASHALG& hashAlg, const vector<VALUE_TYPE, ALLOCATOR>& input) { using ::BloombergLP::bslh::hashAppend; typedef typename vector<VALUE_TYPE, ALLOCATOR>::const_iterator ci_t; hashAppend(hashAlg, input.size()); for (ci_t b = input.begin(), e = input.end(); b != e; ++b) { hashAppend(hashAlg, *b); } } // ------------------------------------- // class vector<VALUE_TYPE *, ALLOCATOR> // ------------------------------------- // *** construct/copy/destroy *** // CREATORS template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>::vector() BSLS_KEYWORD_NOEXCEPT : d_impl() { } template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>::vector(const ALLOCATOR& basicAllocator) BSLS_KEYWORD_NOEXCEPT : d_impl(ImplAlloc(basicAllocator)) { } template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>::vector(size_type initialSize, const ALLOCATOR& basicAllocator) : d_impl(initialSize, ImplAlloc(basicAllocator)) { } template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>::vector(size_type initialSize, VALUE_TYPE *value, const ALLOCATOR& basicAllocator) : d_impl(initialSize, (UintPtr) value, ImplAlloc(basicAllocator)) { } template <class VALUE_TYPE, class ALLOCATOR> template <class INPUT_ITER> inline vector<VALUE_TYPE *, ALLOCATOR>::vector(INPUT_ITER first, INPUT_ITER last, const ALLOCATOR& basicAllocator) : d_impl(typename vector_ForwardIteratorForPtrs<VALUE_TYPE, INPUT_ITER>::type( first), typename vector_ForwardIteratorForPtrs<VALUE_TYPE, INPUT_ITER>::type( last), basicAllocator) { } template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>::vector(const vector& original) : d_impl(original.d_impl) { } template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>::vector( BloombergLP::bslmf::MovableRef<vector> original) BSLS_KEYWORD_NOEXCEPT : d_impl(MoveUtil::move(MoveUtil::access(original).d_impl)) { } template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>::vector(const vector& original, const typename type_identity<ALLOCATOR>::type& basicAllocator) : d_impl(original.d_impl, ImplAlloc(basicAllocator)) { } template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>::vector( BloombergLP::bslmf::MovableRef<vector> original, const typename type_identity<ALLOCATOR>::type& basicAllocator) : d_impl(MoveUtil::move(MoveUtil::access(original).d_impl), ImplAlloc(basicAllocator)) { } #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>::vector( std::initializer_list<VALUE_TYPE *> values, const ALLOCATOR& basicAllocator) : d_impl(typename vector_ForwardIteratorForPtrs< VALUE_TYPE, typename std::initializer_list<VALUE_TYPE *>::const_iterator>:: type(values.begin()), typename vector_ForwardIteratorForPtrs< VALUE_TYPE, typename std::initializer_list<VALUE_TYPE *>::const_iterator>:: type(values.end()), basicAllocator) { } #endif template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>::~vector() { } // MANIPULATORS template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>& vector<VALUE_TYPE *, ALLOCATOR>::operator=( const vector& rhs) { d_impl = rhs.d_impl; return *this; } template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>& vector<VALUE_TYPE *, ALLOCATOR>::operator=( BloombergLP::bslmf::MovableRef<vector<VALUE_TYPE *, ALLOCATOR> > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR( d_impl = MoveUtil::move(MoveUtil::access(rhs).d_impl))) { d_impl = MoveUtil::move(MoveUtil::access(rhs).d_impl); return *this; } #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) template <class VALUE_TYPE, class ALLOCATOR> inline vector<VALUE_TYPE *, ALLOCATOR>& vector<VALUE_TYPE *, ALLOCATOR>::operator=( std::initializer_list<VALUE_TYPE *> values) { assign(values); return *this; } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE *, ALLOCATOR>::assign( std::initializer_list<VALUE_TYPE *> values) { typedef typename std::initializer_list<VALUE_TYPE *>::const_iterator InitIter; typedef typename vector_ForwardIteratorForPtrs<VALUE_TYPE, InitIter>::type Iter; d_impl.assign(Iter(values.begin()), Iter(values.end())); } #endif template <class VALUE_TYPE, class ALLOCATOR> template <class INPUT_ITER> inline void vector<VALUE_TYPE *, ALLOCATOR>::assign(INPUT_ITER first, INPUT_ITER last) { typedef typename vector_ForwardIteratorForPtrs<VALUE_TYPE, INPUT_ITER>::type Iter; d_impl.assign(Iter(first), Iter(last)); } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE *, ALLOCATOR>::assign(size_type numElements, VALUE_TYPE *value) { d_impl.assign(numElements, (UintPtr) value); } // *** iterators *** template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::iterator vector<VALUE_TYPE *, ALLOCATOR>::begin() BSLS_KEYWORD_NOEXCEPT { return (iterator) d_impl.begin(); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::iterator vector<VALUE_TYPE *, ALLOCATOR>::end() BSLS_KEYWORD_NOEXCEPT { return (iterator) d_impl.end(); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::reverse_iterator vector<VALUE_TYPE *, ALLOCATOR>::rbegin() BSLS_KEYWORD_NOEXCEPT { return reverse_iterator((iterator) d_impl.rbegin().base()); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::reverse_iterator vector<VALUE_TYPE *, ALLOCATOR>::rend() BSLS_KEYWORD_NOEXCEPT { return reverse_iterator((iterator) d_impl.rend().base()); } // *** capacity *** template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::size_type vector<VALUE_TYPE *, ALLOCATOR>::size() const BSLS_KEYWORD_NOEXCEPT { return d_impl.size(); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::size_type vector<VALUE_TYPE *, ALLOCATOR>::capacity() const BSLS_KEYWORD_NOEXCEPT { return d_impl.capacity(); } template <class VALUE_TYPE, class ALLOCATOR> inline bool vector<VALUE_TYPE *, ALLOCATOR>::empty() const BSLS_KEYWORD_NOEXCEPT { return d_impl.empty(); } // *** element access *** template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::reference vector<VALUE_TYPE *, ALLOCATOR>::operator[](size_type position) { return (reference) d_impl.operator[](position); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::reference vector<VALUE_TYPE *, ALLOCATOR>::at(size_type position) { return (reference) d_impl.at(position); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::reference vector<VALUE_TYPE *, ALLOCATOR>::front() { return (reference) d_impl.front(); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::reference vector<VALUE_TYPE *, ALLOCATOR>::back() { return (reference) d_impl.back(); } template <class VALUE_TYPE, class ALLOCATOR> inline VALUE_TYPE **vector<VALUE_TYPE *, ALLOCATOR>::data() BSLS_KEYWORD_NOEXCEPT { return (VALUE_TYPE **) d_impl.data(); } // *** capacity *** template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE *, ALLOCATOR>::resize(size_type newLength) { d_impl.resize(newLength); } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE *, ALLOCATOR>::resize(size_type newLength, VALUE_TYPE *value) { d_impl.resize(newLength, (UintPtr) value); } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE *, ALLOCATOR>::reserve(size_type newCapacity) { d_impl.reserve(newCapacity); } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE *, ALLOCATOR>::shrink_to_fit() { d_impl.shrink_to_fit(); } // *** modifiers *** template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::reference vector<VALUE_TYPE *, ALLOCATOR>::emplace_back() { d_impl.emplace_back(); return back(); } # if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class VALUE_TYPE, class ALLOCATOR> template <class ARG> inline typename vector<VALUE_TYPE *, ALLOCATOR>::reference vector<VALUE_TYPE *, ALLOCATOR>::emplace_back(ARG&& arg) { VALUE_TYPE *ptr(arg); // Support explicit conversion operators d_impl.emplace_back(reinterpret_cast<UintPtr>(ptr)); return back(); } # else template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::reference vector<VALUE_TYPE *, ALLOCATOR>::emplace_back(VALUE_TYPE *ptr) { d_impl.emplace_back(reinterpret_cast<UintPtr>(ptr)); return back(); } # endif template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE *, ALLOCATOR>::push_back(VALUE_TYPE *value) { d_impl.emplace_back(reinterpret_cast<UintPtr>(value)); } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE *, ALLOCATOR>::pop_back() { d_impl.pop_back(); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::iterator vector<VALUE_TYPE *, ALLOCATOR>::emplace(const_iterator position) { return (iterator) d_impl.emplace((const UintPtr*) position); } # if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class VALUE_TYPE, class ALLOCATOR> template <class ARG> inline typename vector<VALUE_TYPE *, ALLOCATOR>::iterator vector<VALUE_TYPE *, ALLOCATOR>::emplace(const_iterator position, ARG&& arg) { VALUE_TYPE *ptr(arg); // Support explicit conversion operators return (iterator) d_impl.emplace((const UintPtr *)position, reinterpret_cast<UintPtr>(ptr)); } # else template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::iterator vector<VALUE_TYPE *, ALLOCATOR>::emplace(const_iterator position, VALUE_TYPE *ptr) { return (iterator) d_impl.emplace((const UintPtr*) position, reinterpret_cast<UintPtr>(ptr)); } # endif template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::iterator vector<VALUE_TYPE *, ALLOCATOR>::insert(const_iterator position, VALUE_TYPE *value) { return (iterator) d_impl.emplace((const UintPtr*) position, reinterpret_cast<UintPtr>(value)); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::iterator vector<VALUE_TYPE *, ALLOCATOR>::insert(const_iterator position, size_type numElements, VALUE_TYPE *value) { return (iterator) d_impl.insert( (const UintPtr *)position, numElements, (UintPtr)value); } #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::iterator vector<VALUE_TYPE *, ALLOCATOR>::insert( const_iterator position, std::initializer_list<VALUE_TYPE *> values) { typedef typename std::initializer_list<VALUE_TYPE *>::const_iterator InitIter; typedef typename vector_ForwardIteratorForPtrs<VALUE_TYPE, InitIter>::type Iter; return (iterator) d_impl.insert( (const UintPtr *)position, Iter(values.begin()), Iter(values.end())); } #endif template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::iterator vector<VALUE_TYPE *, ALLOCATOR>::erase(const_iterator position) { return (iterator) d_impl.erase((const UintPtr*) position); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::iterator vector<VALUE_TYPE *, ALLOCATOR>::erase(const_iterator first, const_iterator last) { return (iterator) d_impl.erase((const UintPtr*) first, (const UintPtr*) last); } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE *, ALLOCATOR>::swap( vector<VALUE_TYPE *, ALLOCATOR>& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR( d_impl.swap(other.d_impl))) { d_impl.swap(other.d_impl); } template <class VALUE_TYPE, class ALLOCATOR> inline void vector<VALUE_TYPE *, ALLOCATOR>::clear() BSLS_KEYWORD_NOEXCEPT { d_impl.clear(); } // ACCESSORS template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::allocator_type vector<VALUE_TYPE *, ALLOCATOR>::get_allocator() const BSLS_KEYWORD_NOEXCEPT { return ALLOCATOR(d_impl.get_allocator()); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::size_type vector<VALUE_TYPE *, ALLOCATOR>::max_size() const BSLS_KEYWORD_NOEXCEPT { return d_impl.max_size(); } // *** iterators *** template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_iterator vector<VALUE_TYPE *, ALLOCATOR>::begin() const BSLS_KEYWORD_NOEXCEPT { return (const_iterator) d_impl.begin(); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_iterator vector<VALUE_TYPE *, ALLOCATOR>::cbegin() const BSLS_KEYWORD_NOEXCEPT { return (const_iterator) d_impl.cbegin(); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_iterator vector<VALUE_TYPE *, ALLOCATOR>::end() const BSLS_KEYWORD_NOEXCEPT { return (const_iterator) d_impl.end(); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_iterator vector<VALUE_TYPE *, ALLOCATOR>::cend() const BSLS_KEYWORD_NOEXCEPT { return (const_iterator) d_impl.cend(); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_reverse_iterator vector<VALUE_TYPE *, ALLOCATOR>::rbegin() const BSLS_KEYWORD_NOEXCEPT { return const_reverse_iterator((const_iterator) d_impl.rbegin().base()); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_reverse_iterator vector<VALUE_TYPE *, ALLOCATOR>::crbegin() const BSLS_KEYWORD_NOEXCEPT { return const_reverse_iterator((const_iterator) d_impl.crbegin().base()); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_reverse_iterator vector<VALUE_TYPE *, ALLOCATOR>::rend() const BSLS_KEYWORD_NOEXCEPT { return const_reverse_iterator((const_iterator) d_impl.rend().base()); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_reverse_iterator vector<VALUE_TYPE *, ALLOCATOR>::crend() const BSLS_KEYWORD_NOEXCEPT { return const_reverse_iterator((const_iterator) d_impl.crend().base()); } // *** element access *** template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_reference vector<VALUE_TYPE *, ALLOCATOR>::operator[](size_type position) const { return (const_reference) d_impl.operator[](position); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_reference vector<VALUE_TYPE *, ALLOCATOR>::at(size_type position) const { return (const_reference) d_impl.at(position); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_reference vector<VALUE_TYPE *, ALLOCATOR>::front() const { return (const_reference) d_impl.front(); } template <class VALUE_TYPE, class ALLOCATOR> inline typename vector<VALUE_TYPE *, ALLOCATOR>::const_reference vector<VALUE_TYPE *, ALLOCATOR>::back() const { return (const_reference) d_impl.back(); } template <class VALUE_TYPE, class ALLOCATOR> inline VALUE_TYPE *const *vector<VALUE_TYPE *, ALLOCATOR>::data() const BSLS_KEYWORD_NOEXCEPT { return (VALUE_TYPE *const *) d_impl.data(); } } // close namespace bsl // ============================================================================ // TYPE TRAITS // ============================================================================ // Type traits for STL *sequence* containers: //: o A sequence container defines STL iterators. //: o A sequence container is bitwise movable if the allocator is bitwise //: movable. //: 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_TYPE, class ALLOCATOR> struct HasStlIterators<bsl::vector<VALUE_TYPE, ALLOCATOR> > : bsl::true_type {}; } // close namespace bslalg namespace bslma { template <class VALUE_TYPE, class ALLOCATOR> struct UsesBslmaAllocator<bsl::vector<VALUE_TYPE, ALLOCATOR> > : bsl::is_convertible<Allocator *, ALLOCATOR>::type {}; } // close namespace bslma namespace bslmf { template <class VALUE_TYPE, class ALLOCATOR> struct IsBitwiseMoveable<bsl::vector<VALUE_TYPE, ALLOCATOR> > : IsBitwiseMoveable<ALLOCATOR> {}; } // close namespace bslmf } // close enterprise namespace #ifdef BSLS_COMPILERFEATURES_SUPPORT_EXTERN_TEMPLATE extern template class bsl::vectorBase<bool>; extern template class bsl::vectorBase<char>; extern template class bsl::vectorBase<signed char>; extern template class bsl::vectorBase<unsigned char>; extern template class bsl::vectorBase<short>; extern template class bsl::vectorBase<unsigned short>; extern template class bsl::vectorBase<int>; extern template class bsl::vectorBase<unsigned int>; extern template class bsl::vectorBase<long>; extern template class bsl::vectorBase<unsigned long>; extern template class bsl::vectorBase<long long>; extern template class bsl::vectorBase<unsigned long long>; extern template class bsl::vectorBase<float>; extern template class bsl::vectorBase<double>; extern template class bsl::vectorBase<long double>; extern template class bsl::vectorBase<void *>; extern template class bsl::vectorBase<const char *>; extern template class bsl::vector<bool>; extern template class bsl::vector<char>; extern template class bsl::vector<signed char>; extern template class bsl::vector<unsigned char>; extern template class bsl::vector<short>; extern template class bsl::vector<unsigned short>; extern template class bsl::vector<int>; extern template class bsl::vector<unsigned int>; extern template class bsl::vector<long>; extern template class bsl::vector<unsigned long>; extern template class bsl::vector<long long>; extern template class bsl::vector<unsigned long long>; extern template class bsl::vector<float>; extern template class bsl::vector<double>; extern template class bsl::vector<long double>; extern template class bsl::vector<void *>; extern template class bsl::vector<const char *>; #endif #else // if ! defined(DEFINED_BSLSTL_VECTOR_H) # error Not valid except when included from bslstl_vector.h #endif // ! defined(COMPILING_BSLSTL_VECTOR_H) #endif // ! defined(INCLUDED_BSLSTL_VECTOR_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 ----------------------------------