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