text: // bslstl_vector.h                                                    -*-C++-*-
  #ifndef INCLUDED_BSLSTL_VECTOR
  #define INCLUDED_BSLSTL_VECTOR
  
  #include <bsls_ident.h>
  BSLS_IDENT("$Id: $")
  
  //@PURPOSE: Provide an STL-compliant vector class.
  //
  //@CLASSES:
  //  bsl::vector: STL-compatible vector template
  //
  //@SEE_ALSO: bslstl_deque
  //
  //@DESCRIPTION: This component defines a single class template, 'bsl::vector',
  // implementing the standard sequential container, 'std::vector', holding a
  // dynamic array of values of a template parameter type.
  //
  // An instantiation of 'vector' is an allocator-aware, value-semantic type
  // whose salient attributes are its size (number of values) and the sequence of
  // values the vector contains.  If 'vector' is instantiated with a value type
  // that is not value-semantic, then the vector will not retain all of its
  // value-semantic qualities.  In particular, if a value type cannot be tested
  // for equality, then a 'vector' containing objects of that type cannot be
  // tested for equality.  It is even possible to instantiate 'vector' with a
  // value type that does not have a copy-constructor, in which case the 'vector'
  // will not be copyable.
  //
  // A vector meets the requirements of a sequential container with random access
  // iterators in the C++ standard [vector].  The 'vector' implemented here
  // adheres to the C++11 standard when compiled with a C++11 compiler, and makes
  // the best approximation when compiled with a C++03 compiler.  In particular,
  // for C++03 we emulate move semantics, but limit forwarding (in 'emplace') to
  // 'const' lvalues, and make no effort to emulate 'noexcept' or initializer
  // lists.
  //
  ///Requirements on 'VALUE_TYPE'
  ///----------------------------
  // A 'vector' is a fully Value-Semantic Type (see {'bsldoc_glossary'}) only if
  // the supplied 'VALUE_TYPE' template parameter is fully value-semantic.  It is
  // possible to instantiate a 'vector' with a 'VALUE_TYPE' parameter that does
  // not have a full set of value-semantic operations, but then some methods of
  // the container may not be instantiable.  The following terminology, adopted
  // from the C++11 standard, is used in the function documentation of 'vector'
  // to describe a function's requirements for the 'VALUE_TYPE' template
  // parameter.  These terms are also defined in section [17.6.3.1] of the C++11
  // standard.  Note that, in the context of a 'vector' instantiation, the
  // requirements apply specifically to the vector's entry type, 'value_type',
  // which is an alias for 'VALUE_TYPE'.
  //
  ///Glossary
  ///--------
  //..
  //  Legend
  //  ------
  //  'X'    - denotes an allocator-aware container type (e.g., 'vector')
  //  'T'    - 'value_type' associated with 'X'
  //  'A'    - type of the allocator used by 'X'
  //  'm'    - lvalue of type 'A' (allocator)
  //  'p'    - address ('T *') of uninitialized storage for a 'T' within an 'X'
  //  'rv'   - rvalue of type (non-'const') 'T'
  //  'v'    - rvalue or lvalue of type (possibly 'const') 'T'
  //  'args' - 0 or more arguments
  //..
  // The following terms are used to more precisely specify the requirements on
  // template parameter types in function-level documentation.
  //
  //: *default-insertable*: 'T' has a default constructor.  More precisely, 'T'
  //:   is 'default-insertable' into 'X' means that the following expression is
  //:   well-formed:
  //:   'allocator_traits<A>::construct(m, p)'
  //:
  //: *move-insertable*: 'T' provides a constructor that takes an rvalue of type
  //:   (non-'const') 'T'.  More precisely, 'T' is 'move-insertable' into 'X'
  //:   means that the following expression is well-formed:
  //:   'allocator_traits<A>::construct(m, p, rv)'
  //:
  //: *copy-insertable*: 'T' provides a constructor that takes an lvalue or
  //:   rvalue of type (possibly 'const') 'T'.  More precisely, 'T' is
  //:   'copy-insertable' into 'X' means that the following expression is
  //:   well-formed:
  //:   'allocator_traits<A>::construct(m, p, v)'
  //:
  //: *move-assignable*: 'T' provides an assignment operator that takes an rvalue
  //:   of type (non-'const') 'T'.
  //:
  //: *copy-assignable*: 'T' provides an assignment operator that takes an lvalue
  //:   or rvalue of type (possibly 'const') 'T'.
  //:
  //: *emplace-constructible*: 'T' is 'emplace-constructible' into 'X' from
  //:   'args' means that the following expression is well-formed:
  //:   'allocator_traits<A>::construct(m, p, args)'
  //:
  //: *erasable*: 'T' provides a destructor.  More precisely, 'T' is 'erasable'
  //:   from 'X' means that the following expression is well-formed:
  //:   'allocator_traits<A>::destroy(m, p)'
  //:
  //: *equality-comparable*: The type provides an equality-comparison operator
  //:   that defines an equivalence relationship and is both reflexive and
  //:   transitive.
  //
  ///Memory Allocation
  ///-----------------
  // The type supplied as a vector's 'ALLOCATOR' template parameter determines
  // how that vector will allocate memory.  The 'vector' template supports
  // allocators meeting the requirements of the C++03 standard; in addition, it
  // supports scoped-allocators derived from the 'bslma::Allocator' memory
  // allocation protocol.  Clients intending to use 'bslma'-style allocators
  // should use the template's default 'ALLOCATOR' type: The default type for the
  // 'ALLOCATOR' template parameter, 'bsl::allocator', provides a C++11
  // standard-compatible adapter for a 'bslma::Allocator' object.
  //
  ///'bslma'-Style Allocators
  /// - - - - - - - - - - - -
  // If the (template parameter) type 'ALLOCATOR' of a 'vector' instantiation' is
  // 'bsl::allocator', then objects of that vector type will conform to the
  // standard behavior of a 'bslma'-allocator-enabled type.  Such a vector
  // accepts an optional 'bslma::Allocator' argument at construction.  If the
  // address of a 'bslma::Allocator' object is explicitly supplied at
  // construction, it is used to supply memory for the vector throughout its
  // lifetime; otherwise, the vector will use the default allocator installed at
  // the time of the vector's construction (see 'bslma_default').  In addition to
  // directly allocating memory from the indicated 'bslma::Allocator', a vector
  // supplies that allocator's address to the constructors of contained objects
  // of the (template parameter) type 'VALUE_TYPE', if it defines the
  // 'bslma::UsesBslmaAllocator' trait.
  //
  ///Operations
  ///----------
  // This section describes the run-time complexity of operations on instances
  // of 'vector':
  //..
  //  Legend
  //  ------
  //  'V'             - (template parameter) 'VALUE_TYPE' of the vector
  //  'a', 'b'        - two distinct objects of type 'vector<V>'
  //  'rv'            - modifiable rvalue of type 'vector<V>'
  //  'n', 'm'        - number of elements in 'a' and 'b', respectively
  //  'k'             - non-negative integer
  //  'al'            - an STL-style memory allocator
  //  'i1', 'i2'      - two iterators defining a sequence of 'V' objects
  //  'il'            - object of type 'std::initializer_list<V>'
  //  'lil'           - length of 'il'
  //  'vt'            - object of type 'VALUE_TYPE'
  //  'rvt'           - modifiable rvalue of type 'VALUE_TYPE'
  //  'p1', 'p2'      - two 'const' iterators belonging to 'a'
  //  distance(i1,i2) - the number of elements in the range [i1, i2)
  //
  //  |-----------------------------------------+-------------------------------|
  //  | Operation                               | Complexity                    |
  //  |=========================================+===============================|
  //  | vector<V> a      (default construction) | O[1]                          |
  //  | vector<V> a(al)                         |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | vector<V> a(b)   (copy construction)    | O[n]                          |
  //  | vector<V> a(b, al)                      |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | vector<V> a(rv)  (move construction)    | O[1] if 'a' and 'rv' use the  |
  //  | vector<V> a(rv, al)                     | same allocator; O[n] otherwise|
  //  |-----------------------------------------+-------------------------------|
  //  | vector<V> a(k)                          | O[k]                          |
  //  | vector<V> a(k, al)                      |                               |
  //  | vector<V> a(k, vt)                      |                               |
  //  | vector<V> a(k, vt, al)                  |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | vector<V> a(i1, i2)                     | O[distance(i1, i2)]           |
  //  | vector<V> a(i1, i2, al)                 |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | vector<V> a(il)                         | O[lil]                        |
  //  | vector<V> a(il, al)                     |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | a.~vector<V>()  (destruction)           | O[n]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.assign(k, vt)                         | O[k]                          |
  //  | a.assign(k, rvt)                        |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | a.assign(i1, i2)                        | O[distance(i1, i2)]           |
  //  |-----------------------------------------+-------------------------------|
  //  | a.assign(il)                            | O[lil]                        |
  //  |-----------------------------------------+-------------------------------|
  //  | get_allocator()                         | O[1]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.begin(), a.end(),                     | O[1]                          |
  //  | a.cbegin(), a.cend(),                   |                               |
  //  | a.rbegin(), a.rend(),                   |                               |
  //  | a.crbegin(), a.crend()                  |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | a.size()                                | O[1]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.max_size()                            | O[1]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.resize(k)                             | O[k]                          |
  //  | a.resize(k, vt)                         |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | a.empty()                               | O[1]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.reserve(k)                            | O[k]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.shrink_to_fit()                       | O[n]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a[k]                                    | O[1]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.at(k)                                 | O[1]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.front()                               | O[1]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.back()                                | O[1]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.push_back(vt)                         | O[1]                          |
  //  | a.push_back(rvt)                        |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | a.pop_back()                            | O[1]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.emplace_back(args)                    | O[1]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a.emplace(p1, args)                     | O[1 + distance(p1, a.end())]  |
  //  |-----------------------------------------+-------------------------------|
  //  | a.insert(p1, vt)                        | O[1 + distance(p1, a.end())]  |
  //  | a.insert(p1, rvt)                       |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | a.insert(p1, k, vt)                     | O[k + distance(p1, a.end())]  |
  //  | a.insert(p1, k, rvt)                    |                               |
  //  |-----------------------------------------+-------------------------------|
  //  | a.insert(p1, i1, i2)                    | O[distance(i1, i2)            |
  //  |                                         |      + distance(p1, a.end())] |
  //  |-----------------------------------------+-------------------------------|
  //  | a.insert(p1, il)                        | O[lil                         |
  //  |                                         |      + distance(p1, a.end())] |
  //  |-----------------------------------------+-------------------------------|
  //  | a.erase(p1)                             | O[1 + distance(p1, a.end())]  |
  //  |-----------------------------------------+-------------------------------|
  //  | a.erase(p1, p2)                         | O[distance(p1, p2)            |
  //  |                                         |      + distance(p1, a.end())] |
  //  |-----------------------------------------+-------------------------------|
  //  | a.swap(b), swap(a,b)                    | O[1] if 'a' and 'b' use the   |
  //  |                                         | same allocator; O[n + m]      |
  //  |                                         | otherwise                     |
  //  |-----------------------------------------+-------------------------------|
  //  | a.clear()                               | O[n]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a = b;           (copy assignment)      | O[n]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a = rv;          (move assignment)      | O[1] if 'a' and 'rv' use the  |
  //  |                                         | same allocator; O[n] otherwise|
  //  |-----------------------------------------+-------------------------------|
  //  | a = il;                                 | O[lil]                        |
  //  |-----------------------------------------+-------------------------------|
  //  | a == b, a != b                          | O[n]                          |
  //  |-----------------------------------------+-------------------------------|
  //  | a < b, a <= b, a > b, a >= b            | O[n]                          |
  //  |-----------------------------------------+-------------------------------|
  //..
  //
  ///Usage
  ///-----
  // In this section we show intended use of this component.
  //
  ///Example 1: Creating a Matrix Type
  ///- - - - - - - - - - - - - - - - -
  // Suppose we want to define a value-semantic type representing a dynamically
  // resizable two-dimensional matrix.
  //
  // First, we define the public interface for the 'MyMatrix' class template:
  //..
  //  template <class TYPE>
  //  class MyMatrix {
  //      // This value-semantic type characterizes a two-dimensional matrix of
  //      // objects of the (template parameter) 'TYPE'.  The numbers of columns
  //      // and rows of the matrix can be specified at construction and, at any
  //      // time, via the 'reset', 'insertRow', and 'insertColumn' methods.  The
  //      // value of each element in the matrix can be set and accessed using
  //      // the 'theValue', and 'theModifiableValue' methods respectively.
  //
  //    public:
  //      // PUBLIC TYPES
  //..
  // Here, we create a type alias, 'RowType', for an instantiation of
  // 'bsl::vector' to represent a row of 'TYPE' objects in the matrix.  We create
  // another type alias, 'MatrixType', for an instantiation of 'bsl::vector' to
  // represent the entire matrix of 'TYPE' objects as a list of rows:
  //..
  //      typedef bsl::vector<TYPE>    RowType;
  //          // This is an alias representing a row of values of the (template
  //          // parameter) 'TYPE'.
  //
  //      typedef bsl::vector<RowType> MatrixType;
  //          // This is an alias representing a two-dimensional matrix of values
  //          // of the (template parameter) 'TYPE'.
  //
  //    private:
  //      // DATA
  //      MatrixType d_matrix;      // matrix of values
  //      int        d_numColumns;  // number of columns
  //
  //      // FRIENDS
  //      template <class T>
  //      friend bool operator==(const MyMatrix<T>&, const MyMatrix<T>&);
  //
  //    public:
  //      // PUBLIC TYPES
  //      typedef typename MatrixType::const_iterator ConstRowIterator;
  //
  //      // CREATORS
  //      MyMatrix(int               numRows,
  //               int               numColumns,
  //               bslma::Allocator *basicAllocator = 0);
  //          // Create a 'MyMatrix' object having the specified 'numRows' and
  //          // the specified 'numColumns'.  All elements of the (template
  //          // parameter) 'TYPE' in the matrix will have the
  //          // default-constructed value.  Optionally specify a
  //          // 'basicAllocator' used to supply memory.  If 'basicAllocator' is
  //          // 0, the currently installed default allocator is used.  The
  //          // behavior is undefined unless '0 <= numRows' and
  //          // '0 <= numColumns'
  //
  //      MyMatrix(const MyMatrix&   original,
  //               bslma::Allocator *basicAllocator = 0);
  //          // Create a 'MyMatrix' object having the same value as the
  //          // specified 'original' object.  Optionally specify a
  //          // 'basicAllocator' used to supply memory.  If 'basicAllocator' is
  //          // 0, the currently installed default allocator is used.
  //
  //      //! ~MyMatrix = default;
  //          // Destroy this object.
  //
  //      // MANIPULATORS
  //      MyMatrix& operator=(const MyMatrix& rhs);
  //          // Assign to this object the value of the specified 'rhs' object,
  //          // and return a reference providing modifiable access to this
  //          // object.
  //
  //      void clear();
  //          // Remove all rows and columns from this object.
  //
  //      void insertColumn(int columnIndex);
  //          // Insert, into this matrix, an column at the specified
  //          // 'columnIndex'.  All elements of the (template parameter) 'TYPE'
  //          // in the column will have the default-constructed value.  The
  //          // behavior is undefined unless '0 <= columnIndex <= numColumns()'.
  //
  //      void insertRow(int rowIndex);
  //          // Insert, into this matrix, a row at the specified 'rowIndex'.
  //          // All elements of the (template parameter) 'TYPE' in the row will
  //          // have the default-constructed value.  The behavior is undefined
  //          // unless '0 <= rowIndex <= numRows()'.
  //
  //      TYPE& theModifiableValue(int rowIndex, int columnIndex);
  //          // Return a reference providing modifiable access to the element at
  //          // the specified 'rowIndex' and the specified 'columnIndex' in this
  //          // matrix.  The behavior is undefined unless
  //          // '0 <= rowIndex < numRows()' and
  //          // '0 <= columnIndex < numColumns()'.
  //
  //      // ACCESSORS
  //      int numRows() const;
  //          // Return the number of rows in this matrix.
  //
  //      int numColumns() const;
  //          // Return the number of columns in this matrix.
  //
  //      ConstRowIterator beginRow() const;
  //          // Return an iterator providing non-modifiable access to the
  //          // 'RowType' objects representing the first row in this matrix.
  //
  //      ConstRowIterator endRow() const;
  //          // Return an iterator providing non-modifiable access to the
  //          // 'RowType' objects representing the past-the-end row in this
  //          // matrix.
  //
  //      const TYPE& theValue(int rowIndex, int columnIndex) const;
  //          // Return a reference providing non-modifiable access to the
  //          // element at the specified 'rowIndex' and the specified
  //          // 'columnIndex' in this matrix.  The behavior is undefined unless
  //          // '0 <= rowIndex < numRows()' and
  //          // '0 <= columnIndex < numColumns()'.
  //  };
  //..
  // Then we declare the free operator for 'MyMatrix':
  //..
  //  // FREE OPERATORS
  //  template <class TYPE>
  //  MyMatrix<TYPE> operator==(const MyMatrix<TYPE>& lhs,
  //                            const MyMatrix<TYPE>& rhs);
  //      // Return 'true' if the specified 'lhs' and 'rhs' objects have the same
  //      // value, and 'false' otherwise.  Two 'MyMatrix' objects have the same
  //      // value if they have the same number of rows and columns and every
  //      // element in both matrices compare equal.
  //
  //  template <class TYPE>
  //  MyMatrix<TYPE> operator!=(const MyMatrix<TYPE>& lhs,
  //                            const MyMatrix<TYPE>& rhs);
  //      // Return 'true' if the specified 'lhs' and 'rhs' objects do not have
  //      // the same value, and 'false' otherwise.  Two 'MyMatrix' objects do
  //      // not have the same value if they do not have the same number of rows
  //      // and columns or every element in both matrices do not compare equal.
  //
  //  template <class TYPE>
  //  MyMatrix<TYPE> operator*(const MyMatrix<TYPE>& lhs,
  //                           const MyMatrix<TYPE>& rhs);
  //      // Return a 'MyMatrix' objects that is the product of the specified
  //      // 'lhs' and 'rhs'.  The behavior is undefined unless
  //      // 'lhs.numColumns() == rhs.numRows()'.
  //..
  // Now, we define the methods of 'MyMatrix':
  //..
  //  // CREATORS
  //  template <class TYPE>
  //  MyMatrix<TYPE>::MyMatrix(int numRows,
  //                           int numColumns,
  //                           bslma::Allocator *basicAllocator)
  //  : d_matrix(numRows, basicAllocator)
  //  , d_numColumns(numColumns)
  //  {
  //      BSLS_ASSERT(0 <= numRows);
  //      BSLS_ASSERT(0 <= numColumns);
  //
  //      for (typename MatrixType::iterator itr = d_matrix.begin();
  //           itr != d_matrix.end();
  //           ++itr) {
  //          itr->resize(d_numColumns);
  //      }
  //  }
  //  template <class TYPE>
  //  MyMatrix<TYPE>::MyMatrix(const MyMatrix& original,
  //                           bslma::Allocator *basicAllocator)
  //  : d_matrix(original.d_matrix, basicAllocator)
  //  , d_numColumns(original.d_numColumns)
  //  {
  //  }
  //..
  // Notice that we pass the contained 'bsl::vector' ('d_matrix') the allocator
  // specified at construction to supply memory.  If the (template parameter)
  // 'TYPE' of the elements has the 'bslalg_TypeTraitUsesBslmaAllocator' trait,
  // this allocator will be passed by the vector to the elements as well.
  //..
  //  // MANIPULATORS
  //  template <class TYPE>
  //  MyMatrix<TYPE>& MyMatrix<TYPE>::operator=(const MyMatrix& rhs)
  //  {
  //      d_matrix = rhs.d_matrix;
  //      d_numColumns = rhs.d_numColumns;
  //  }
  //
  //  template <class TYPE>
  //  void MyMatrix<TYPE>::clear()
  //  {
  //      d_matrix.clear();
  //      d_numColumns = 0;
  //  }
  //
  //  template <class TYPE>
  //  void MyMatrix<TYPE>::insertColumn(int colIndex) {
  //      for (typename MatrixType::iterator itr = d_matrix.begin();
  //           itr != d_matrix.end();
  //           ++itr) {
  //          itr->insert(itr->begin() + colIndex, TYPE());
  //      }
  //      ++d_numColumns;
  //  }
  //
  //  template <class TYPE>
  //  void MyMatrix<TYPE>::insertRow(int rowIndex)
  //  {
  //      typename MatrixType::iterator itr =
  //          d_matrix.insert(d_matrix.begin() + rowIndex, RowType());
  //      itr->resize(d_numColumns);
  //  }
  //
  //  template <class TYPE>
  //  TYPE& MyMatrix<TYPE>::theModifiableValue(int rowIndex, int columnIndex)
  //  {
  //      BSLS_ASSERT(0 <= rowIndex);
  //      BSLS_ASSERT(rowIndex < d_matrix.size());
  //      BSLS_ASSERT(0 <= columnIndex);
  //      BSLS_ASSERT(columnIndex < d_numColumns);
  //
  //      return d_matrix[rowIndex][columnIndex];
  //  }
  //
  //  // ACCESSORS
  //  template <class TYPE>
  //  int MyMatrix<TYPE>::numRows() const
  //  {
  //      return d_matrix.size();
  //  }
  //
  //  template <class TYPE>
  //  int MyMatrix<TYPE>::numColumns() const
  //  {
  //      return d_numColumns;
  //  }
  //
  //  template <class TYPE>
  //  typename MyMatrix<TYPE>::ConstRowIterator MyMatrix<TYPE>::beginRow() const
  //  {
  //      return d_matrix.begin();
  //  }
  //
  //  template <class TYPE>
  //  typename MyMatrix<TYPE>::ConstRowIterator MyMatrix<TYPE>::endRow() const
  //  {
  //      return d_matrix.end();
  //  }
  //
  //  template <class TYPE>
  //  const TYPE& MyMatrix<TYPE>::theValue(int rowIndex, int columnIndex) const
  //  {
  //      BSLS_ASSERT(0 <= rowIndex);
  //      BSLS_ASSERT(rowIndex < d_matrix.size());
  //      BSLS_ASSERT(0 <= columnIndex);
  //      BSLS_ASSERT(columnIndex < d_numColumns);
  //
  //      return d_matrix[rowIndex][columnIndex];
  //  }
  //..
  // Finally, we defines the free operators for 'MyMatrix':
  //..
  //  // FREE OPERATORS
  //  template <class TYPE>
  //  MyMatrix<TYPE> operator==(const MyMatrix<TYPE>& lhs,
  //                            const MyMatrix<TYPE>& rhs)
  //  {
  //      return lhs.d_numColumns == rhs.d_numColumns &&
  //                                                lhs.d_matrix == rhs.d_matrix;
  //  }
  //
  //  template <class TYPE>
  //  MyMatrix<TYPE> operator!=(const MyMatrix<TYPE>& lhs,
  //                            const MyMatrix<TYPE>& rhs)
  //  {
  //      return !(lhs == rhs);
  //  }
  //..
  
  // Prevent 'bslstl' headers from being included directly in 'BSL_OVERRIDES_STD'
  // mode.  Doing so is unsupported, and is likely to cause compilation errors.
  #if defined(BSL_OVERRIDES_STD) && !defined(BOS_STDHDRS_PROLOGUE_IN_EFFECT)
  #error "include <bsl_vector.h> instead of <bslstl_vector.h> in \
  BSL_OVERRIDES_STD mode"
  #endif
  #include <bslscm_version.h>
  
  #include <bslstl_hash.h>
  #include <bslstl_iterator.h>
  #include <bslstl_stdexceptutil.h>
  
  #include <bslalg_arraydestructionprimitives.h>
  #include <bslalg_arrayprimitives.h>
  #include <bslalg_containerbase.h>
  #include <bslalg_rangecompare.h>
  #include <bslalg_swaputil.h>
  #include <bslalg_typetraithasstliterators.h>
  
  #include <bslh_hash.h>
  
  #include <bslma_allocator.h>
  #include <bslma_allocatortraits.h>
  #include <bslma_autodestructor.h>
  #include <bslma_stdallocator.h>
  #include <bslma_usesbslmaallocator.h>
  
  #include <bslmf_enableif.h>
  #include <bslmf_isbitwisemoveable.h>
  #include <bslmf_isconvertible.h>
  #include <bslmf_isfundamental.h>
  #include <bslmf_isintegral.h>
  #include <bslmf_issame.h>
  #include <bslmf_matchanytype.h>
  #include <bslmf_matcharithmetictype.h>
  #include <bslmf_movableref.h>
  #include <bslmf_nil.h>
  
  #include <bsls_assert.h>
  #include <bsls_compilerfeatures.h>
  #include <bsls_keyword.h>
  #include <bsls_performancehint.h>
  #include <bsls_platform.h>
  #include <bsls_types.h>
  
  #include <cstddef>
  
  #if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
  
  #include <initializer_list>
  #endif
  
  #ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
  
  #include <stdexcept>
  #endif
  
  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 instantion 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_ACTIVE)
  
  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&                            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 VALUE_TYPE                             value_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 'bsl::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 typename ALLOCATOR::reference             reference;
      typedef typename ALLOCATOR::const_reference       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 ALLOCATOR& 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 ALLOCATOR&                       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> 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_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.  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_CPP11_FEATURES
      template <class... Args>
      reference emplace_back(Args&&... arguments);
          // Append to the end of this vector a newly created 'value_type'
          // object, constructed by forwarding 'get_allocator()' (if required)
          // and the specified (variable number of) 'arguments' to the
          // corresponding constructor of 'value_type'.  Return a reference
          // providing modifiable access to the inserted element.  If an
          // exception is thrown (other than by the move constructor of a
          // non-copy-insertable 'value_type'), '*this' is unaffected.  This
          // method requires that the (template parameter) type 'VALUE_TYPE' be
          // 'move-insertable' into this vector and 'emplace-constructible' from
          // 'arguments' (see
          // {Requirements on 'VALUE_TYPE'}).
  #elif BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
  // {{{ BEGIN GENERATED CODE
  // The following section is automatically generated.  **DO NOT EDIT**
  // Generator 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
      reference emplace_back(
                           );
  #endif  // BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 0
  
  #if BSLSTL_VECTOR_VARIADIC_LIMIT_A >= 1
      template <class Args_01>
      reference 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>
      reference 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>
      reference emplace_back(
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03);
  #endif  // BSLSTL_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>
      reference emplace_back(
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04);
  #endif  // BSLSTL_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>
      reference emplace_back(
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05);
  #endif  // BSLSTL_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>
      reference emplace_back(
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06);
  #endif  // BSLSTL_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>
      reference emplace_back(
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07);
  #endif  // BSLSTL_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>
      reference emplace_back(
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08);
  #endif  // BSLSTL_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>
      reference emplace_back(
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09);
  #endif  // BSLSTL_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>
      reference emplace_back(
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09,
                        BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) arguments_10);
  #endif  // BSLSTL_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>
      reference 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_CPP11_FEATURES
      template <class... Args>
      iterator emplace(const_iterator position, Args&&... arguments)
          // Insert at the specified 'position' in this vector a newly created
          // 'value_type' object, constructed by forwarding 'get_allocator()' (if
          // required) and the specified (variable number of) 'arguments' to the
          // corresponding constructor of 'value_type', and return an iterator
          // referring to the newly created and 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 'move-insertable' into this vector and
          // 'emplace-constructible' from 'arguments' (see {Requirements on
          // 'VALUE_TYPE'}).
          //
          // 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());
  
          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;
      }
  #elif BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
  // {{{ BEGIN GENERATED CODE
  // The following section is automatically generated.  **DO NOT EDIT**
  // Generator 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(false);
          // Exchange the value of this object with the value of the specified
          // 'other' object.  Additionally, if
          // 'bsl::allocator_traits<ALLOCATOR>::propagate_on_container_swap' is
          // 'true', then exchange the allocator of this object with that of the
          // 'other' object, and do not modify either allocator otherwise.  This
          // method provides the no-throw exception-safety guarantee and
          // guarantees 'O[1]' complexity.  Note that the exception specification
          // is a stand in until 'bsl' can assume availability of all the traits
          // for the 'noexcept' predicate on all supported platforms.  The
          // behavior is undefined unless either this object was created with the
          // same allocator as 'other' or 'propagate_on_container_swap' is
          // 'true'.
  
      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>
  void swap(vector<VALUE_TYPE, ALLOCATOR>& a,
            vector<VALUE_TYPE, ALLOCATOR>& b)
                                      BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(false);
      // Exchange the value of the specified 'a' object with the value of the
      // specified 'b' object.  Additionally, if
      // 'bsl::allocator_traits<ALLOCATOR>::propagate_on_container_swap' is
      // 'true', then exchange the allocator of 'a' with that of 'b'.  If
      // 'propagate_on_container_swap' is 'true' or 'a' and 'b' were created with
      // the same allocator, then this method provides the no-throw
      // exception-safety guarantee and has 'O[1]' complexity; otherwise, this
      // method has 'O[n + m]' complexity, where 'n' and 'm' are the number of
      // elements in 'a' and 'b', respectively.  Note that 'a' and 'b' are left
      // in valid but unspecified states if an exception is thrown, e.g., in the
      // case where 'propagate_on_container_swap' is 'false' and 'a' and 'b' were
      // created with different allocators.  Also note that the exception
      // specification is a stand in until 'bsl' can assume availability of all
      // the traits for the 'noexcept' predicate on all supported platforms.
  
  
                     // =====================================
                     // 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 typename ALLOCATOR::reference         reference;
      typedef typename ALLOCATOR::const_reference   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 VALUE_TYPE                           *value_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 ALLOCATOR& basicAllocator);
  
      vector(BloombergLP::bslmf::MovableRef<vector> original,
             const ALLOCATOR&                       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> rhs)
                                      BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(false);
  
  #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 ***
  
      reference emplace_back();
  
  # if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
      template <class ARG>
      reference emplace_back(ARG&& arg);
  # else
      reference 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& other);
  
      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(false)
      {
          a.d_impl.swap(b.d_impl);
      }
  };
  
  
  // ============================================================================
  //                  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_ACTIVE)
                          // -----------------------
                          // 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-constuctor): 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
      }
  
      typedef BloombergLP::bslalg::ArrayPrimitives ArrayPrimitives;
  
  
      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 ALLOCATOR& 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 ALLOCATOR&                       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> rhs)
  {
      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_CPP11_FEATURES
  template <class VALUE_TYPE, class ALLOCATOR>
  template <class... Args>
  inline
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  vector<VALUE_TYPE, ALLOCATOR>::emplace_back(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);
  
          // Construct before we risk invalidating the reference
          VALUE_TYPE *pos = temp.d_dataBegin_p + this->size();
          AllocatorTraits::construct(
                              ContainerBase::allocator(),
                              pos,
                              BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...);
  
          // 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);
      }
      return *(this->d_dataEnd_p - 1);
  }
  #elif BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
  // {{{ BEGIN GENERATED CODE
  // The following section is automatically generated.  **DO NOT EDIT**
  // Generator 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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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
  typename vector<VALUE_TYPE, ALLOCATOR>::reference
  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);
  }
  
  template <class VALUE_TYPE, class ALLOCATOR>
  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(false)
  {
      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 ContainerBase::allocator().max_size();
  }
  
  // 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>
  inline
  void swap(vector<VALUE_TYPE, ALLOCATOR>& a,
            vector<VALUE_TYPE, ALLOCATOR>& b)
                                       BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(false)
  {
      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 ALLOCATOR& 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 ALLOCATOR&                       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> rhs)
                                       BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(false)
  {
      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& other)
  {
      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
  
  #endif
  
  // ----------------------------------------------------------------------------
  // Copyright 2018 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 ----------------------------------
  