BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_vector.h
Go to the documentation of this file.
1/// @file bslstl_vector.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_vector.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_VECTOR
9#define INCLUDED_BSLSTL_VECTOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_vector bslstl_vector
15/// @brief Provide an STL-compliant vector class.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_vector
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_vector-purpose"> Purpose</a>
25/// * <a href="#bslstl_vector-classes"> Classes </a>
26/// * <a href="#bslstl_vector-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_vector-description"> Description </a>
28/// * <a href="#bslstl_vector-requirements-on-value_type"> Requirements on VALUE_TYPE </a>
29/// * <a href="#bslstl_vector-glossary"> Glossary </a>
30/// * <a href="#bslstl_vector-memory-allocation"> Memory Allocation </a>
31/// * <a href="#bslstl_vector-bslma-style-allocators"> bslma-Style Allocators </a>
32/// * <a href="#bslstl_vector-operations"> Operations </a>
33/// * <a href="#bslstl_vector-comparing-a-vector-of-floating-point-values"> Comparing a vector of floating point values </a>
34/// * <a href="#bslstl_vector-usage"> Usage </a>
35/// * <a href="#bslstl_vector-example-1-creating-a-matrix-type"> Example 1: Creating a Matrix Type </a>
36///
37/// # Purpose {#bslstl_vector-purpose}
38/// Provide an STL-compliant vector class.
39///
40/// # Classes {#bslstl_vector-classes}
41///
42/// - bsl::vector: STL-compatible vector template
43///
44/// # Canonical Header {#bslstl_vector-canonical-header}
45/// bsl_vector.h
46///
47/// @see bslstl_deque
48///
49/// # Description {#bslstl_vector-description}
50/// This component defines a single class template, `bsl::vector`,
51/// implementing the standard sequential container, `std::vector`, holding a
52/// dynamic array of values of a template parameter type.
53///
54/// An instantiation of `vector` is an allocator-aware, value-semantic type
55/// whose salient attributes are its size (number of values) and the sequence of
56/// values the vector contains. If `vector` is instantiated with a value type
57/// that is not value-semantic, then the vector will not retain all of its
58/// value-semantic qualities. In particular, if a value type cannot be tested
59/// for equality, then a `vector` containing objects of that type cannot be
60/// tested for equality. It is even possible to instantiate `vector` with a
61/// value type that does not have a copy-constructor, in which case the `vector`
62/// will not be copyable.
63///
64/// A vector meets the requirements of a sequential container with random access
65/// iterators in the C++ standard [vector]. The `vector` implemented here
66/// adheres to the C++11 standard when compiled with a C++11 compiler, and makes
67/// the best approximation when compiled with a C++03 compiler. In particular,
68/// for C++03 we emulate move semantics, but limit forwarding (in `emplace`) to
69/// `const` lvalues, and make no effort to emulate `noexcept` or initializer
70/// lists.
71///
72/// ## Requirements on VALUE_TYPE {#bslstl_vector-requirements-on-value_type}
73///
74///
75/// A `vector` is a fully Value-Semantic Type (see @ref bsldoc_glossary ) only if
76/// the supplied `VALUE_TYPE` template parameter is fully value-semantic. It is
77/// possible to instantiate a `vector` with a `VALUE_TYPE` parameter that does
78/// not have a full set of value-semantic operations, but then some methods of
79/// the container may not be instantiable. The following terminology, adopted
80/// from the C++11 standard, is used in the function documentation of `vector`
81/// to describe a function's requirements for the `VALUE_TYPE` template
82/// parameter. These terms are also defined in section [17.6.3.1] of the C++11
83/// standard. Note that, in the context of a `vector` instantiation, the
84/// requirements apply specifically to the vector's entry type, `value_type`,
85/// which is an alias for `VALUE_TYPE`.
86///
87/// ## Glossary {#bslstl_vector-glossary}
88///
89///
90/// @code
91/// Legend
92/// ------
93/// 'X' - denotes an allocator-aware container type (e.g., 'vector')
94/// 'T' - 'value_type' associated with 'X'
95/// 'A' - type of the allocator used by 'X'
96/// 'm' - lvalue of type 'A' (allocator)
97/// 'p' - address ('T *') of uninitialized storage for a 'T' within an 'X'
98/// 'rv' - rvalue of type (non-'const') 'T'
99/// 'v' - rvalue or lvalue of type (possibly 'const') 'T'
100/// 'args' - 0 or more arguments
101/// @endcode
102/// The following terms are used to more precisely specify the requirements on
103/// template parameter types in function-level documentation.
104///
105/// *default-insertable*: `T` has a default constructor. More precisely, `T`
106/// is `default-insertable` into `X` means that the following expression is
107/// well-formed:
108/// `allocator_traits<A>::construct(m, p)`
109///
110/// *move-insertable*: `T` provides a constructor that takes an rvalue of type
111/// (non-`const`) `T`. More precisely, `T` is `move-insertable` into `X`
112/// means that the following expression is well-formed:
113/// `allocator_traits<A>::construct(m, p, rv)`
114///
115/// *copy-insertable*: `T` provides a constructor that takes an lvalue or
116/// rvalue of type (possibly `const`) `T`. More precisely, `T` is
117/// `copy-insertable` into `X` means that the following expression is
118/// well-formed:
119/// `allocator_traits<A>::construct(m, p, v)`
120///
121/// *move-assignable*: `T` provides an assignment operator that takes an rvalue
122/// of type (non-`const`) `T`.
123///
124/// *copy-assignable*: `T` provides an assignment operator that takes an lvalue
125/// or rvalue of type (possibly `const`) `T`.
126///
127/// *emplace-constructible*: `T` is `emplace-constructible` into `X` from
128/// `args` means that the following expression is well-formed:
129/// `allocator_traits<A>::construct(m, p, args)`
130///
131/// *erasable*: `T` provides a destructor. More precisely, `T` is `erasable`
132/// from `X` means that the following expression is well-formed:
133/// `allocator_traits<A>::destroy(m, p)`
134///
135/// *equality-comparable*: The type provides an equality-comparison operator
136/// that defines an equivalence relationship and is both reflexive and
137/// transitive.
138///
139/// ## Memory Allocation {#bslstl_vector-memory-allocation}
140///
141///
142/// The type supplied as a vector's `ALLOCATOR` template parameter determines
143/// how that vector will allocate memory. The `vector` template supports
144/// allocators meeting the requirements of the C++03 standard; in addition, it
145/// supports scoped-allocators derived from the `bslma::Allocator` memory
146/// allocation protocol. Clients intending to use `bslma`-style allocators
147/// should use the template's default `ALLOCATOR` type: The default type for the
148/// `ALLOCATOR` template parameter, `bsl::allocator`, provides a C++11
149/// standard-compatible adapter for a `bslma::Allocator` object.
150///
151/// ### bslma-Style Allocators {#bslstl_vector-bslma-style-allocators}
152///
153///
154/// If the (template parameter) type `ALLOCATOR` of a `vector` instantiation' is
155/// `bsl::allocator`, then objects of that vector type will conform to the
156/// standard behavior of a `bslma`-allocator-enabled type. Such a vector
157/// accepts an optional `bslma::Allocator` argument at construction. If the
158/// address of a `bslma::Allocator` object is explicitly supplied at
159/// construction, it is used to supply memory for the vector throughout its
160/// lifetime; otherwise, the vector will use the default allocator installed at
161/// the time of the vector's construction (see @ref bslma_default ). In addition to
162/// directly allocating memory from the indicated `bslma::Allocator`, a vector
163/// supplies that allocator's address to the constructors of contained objects
164/// of the (template parameter) type `VALUE_TYPE`, if it defines the
165/// `bslma::UsesBslmaAllocator` trait.
166///
167/// ## Operations {#bslstl_vector-operations}
168///
169///
170/// This section describes the run-time complexity of operations on instances
171/// of `vector`:
172/// @code
173/// Legend
174/// ------
175/// 'V' - (template parameter) 'VALUE_TYPE' of the vector
176/// 'a', 'b' - two distinct objects of type 'vector<V>'
177/// 'rv' - modifiable rvalue of type 'vector<V>'
178/// 'n', 'm' - number of elements in 'a' and 'b', respectively
179/// 'k' - non-negative integer
180/// 'al' - an STL-style memory allocator
181/// 'i1', 'i2' - two iterators defining a sequence of 'V' objects
182/// 'rg' - range of objects convertible to 'V'
183/// 'il' - object of type 'std::initializer_list<V>'
184/// 'lil' - length of 'il'
185/// 'vt' - object of type 'VALUE_TYPE'
186/// 'rvt' - modifiable rvalue of type 'VALUE_TYPE'
187/// 'p1', 'p2' - two 'const' iterators belonging to 'a'
188/// distance(i1,i2) - the number of elements in the range [i1, i2)
189///
190/// |-----------------------------------------+-------------------------------|
191/// | Operation | Complexity |
192/// |=========================================+===============================|
193/// | vector<V> a (default construction) | O[1] |
194/// | vector<V> a(al) | |
195/// |-----------------------------------------+-------------------------------|
196/// | vector<V> a(b) (copy construction) | O[n] |
197/// | vector<V> a(b, al) | |
198/// |-----------------------------------------+-------------------------------|
199/// | vector<V> a(rv) (move construction) | O[1] if 'a' and 'rv' use the |
200/// | vector<V> a(rv, al) | same allocator; O[n] otherwise|
201/// |-----------------------------------------+-------------------------------|
202/// | vector<V> a(k) | O[k] |
203/// | vector<V> a(k, al) | |
204/// | vector<V> a(k, vt) | |
205/// | vector<V> a(k, vt, al) | |
206/// |-----------------------------------------+-------------------------------|
207/// | vector<V> a(i1, i2) | O[distance(i1, i2)] |
208/// | vector<V> a(i1, i2, al) | |
209/// |-----------------------------------------+-------------------------------|
210/// | vector<V> a(from_range, rg) | O[ranges::distance(rg)] |
211/// | vector<V> a(from_range, rg, al) | |
212/// |-----------------------------------------+-------------------------------|
213/// | vector<V> a(il) | O[lil] |
214/// | vector<V> a(il, al) | |
215/// |-----------------------------------------+-------------------------------|
216/// | a.~vector<V>() (destruction) | O[n] |
217/// |-----------------------------------------+-------------------------------|
218/// | a.assign(k, vt) | O[k] |
219/// | a.assign(k, rvt) | |
220/// |-----------------------------------------+-------------------------------|
221/// | a.assign(i1, i2) | O[distance(i1, i2)] |
222/// |-----------------------------------------+-------------------------------|
223/// | a.assign_range(rg) | O[ranges::distance(rg)] |
224/// |-----------------------------------------+-------------------------------|
225/// | a.assign(il) | O[lil] |
226/// |-----------------------------------------+-------------------------------|
227/// | get_allocator() | O[1] |
228/// |-----------------------------------------+-------------------------------|
229/// | a.begin(), a.end(), | O[1] |
230/// | a.cbegin(), a.cend(), | |
231/// | a.rbegin(), a.rend(), | |
232/// | a.crbegin(), a.crend() | |
233/// |-----------------------------------------+-------------------------------|
234/// | a.size() | O[1] |
235/// |-----------------------------------------+-------------------------------|
236/// | a.max_size() | O[1] |
237/// |-----------------------------------------+-------------------------------|
238/// | a.resize(k) | O[k] |
239/// | a.resize(k, vt) | |
240/// |-----------------------------------------+-------------------------------|
241/// | a.empty() | O[1] |
242/// |-----------------------------------------+-------------------------------|
243/// | a.reserve(k) | O[k] |
244/// |-----------------------------------------+-------------------------------|
245/// | a.shrink_to_fit() | O[n] |
246/// |-----------------------------------------+-------------------------------|
247/// | a[k] | O[1] |
248/// |-----------------------------------------+-------------------------------|
249/// | a.at(k) | O[1] |
250/// |-----------------------------------------+-------------------------------|
251/// | a.front() | O[1] |
252/// |-----------------------------------------+-------------------------------|
253/// | a.back() | O[1] |
254/// |-----------------------------------------+-------------------------------|
255/// | a.push_back(vt) | O[1] |
256/// | a.push_back(rvt) | |
257/// |-----------------------------------------+-------------------------------|
258/// | a.pop_back() | O[1] |
259/// |-----------------------------------------+-------------------------------|
260/// | a.emplace_back(args) | O[1] |
261/// |-----------------------------------------+-------------------------------|
262/// | a.append_range(rg) | O[ranges::distance(rg)] |
263/// |-----------------------------------------+-------------------------------|
264/// | a.emplace(p1, args) | O[1 + distance(p1, a.end())] |
265/// |-----------------------------------------+-------------------------------|
266/// | a.insert(p1, vt) | O[1 + distance(p1, a.end())] |
267/// | a.insert(p1, rvt) | |
268/// |-----------------------------------------+-------------------------------|
269/// | a.insert(p1, k, vt) | O[k + distance(p1, a.end())] |
270/// | a.insert(p1, k, rvt) | |
271/// |-----------------------------------------+-------------------------------|
272/// | a.insert(p1, i1, i2) | O[distance(i1, i2) |
273/// | | + distance(p1, a.end())] |
274/// |-----------------------------------------+-------------------------------|
275/// | a.insert_range(p1, rg) | O[ranges::distance(rg) + |
276/// | | ranges::distance(p1, |
277/// | | a.end())] |
278/// |-----------------------------------------+-------------------------------|
279/// | a.insert(p1, il) | O[lil |
280/// | | + distance(p1, a.end())] |
281/// |-----------------------------------------+-------------------------------|
282/// | a.erase(p1) | O[1 + distance(p1, a.end())] |
283/// |-----------------------------------------+-------------------------------|
284/// | a.erase(p1, p2) | O[distance(p1, p2) |
285/// | | + distance(p1, a.end())] |
286/// |-----------------------------------------+-------------------------------|
287/// | a.swap(b), swap(a, b) | O[1] if 'a' and 'b' use the |
288/// | | same allocator; O[n + m] |
289/// | | otherwise |
290/// |-----------------------------------------+-------------------------------|
291/// | a.clear() | O[n] |
292/// |-----------------------------------------+-------------------------------|
293/// | a = b; (copy assignment) | O[n] |
294/// |-----------------------------------------+-------------------------------|
295/// | a = rv; (move assignment) | O[1] if 'a' and 'rv' use the |
296/// | | same allocator; O[n] otherwise|
297/// |-----------------------------------------+-------------------------------|
298/// | a = il; | O[lil] |
299/// |-----------------------------------------+-------------------------------|
300/// | a == b, a != b | O[n] |
301/// |-----------------------------------------+-------------------------------|
302/// | a < b, a <= b, a > b, a >= b | O[n] |
303/// |-----------------------------------------+-------------------------------|
304/// @endcode
305///
306/// ## Comparing a vector of floating point values {#bslstl_vector-comparing-a-vector-of-floating-point-values}
307///
308///
309/// The comparison operator performs a bit-wise comparison for floating point
310/// types (`float` and `double`), which produces results for NaN, +0, and -0
311/// values that do not meet the guarantees provided by the standard.
312/// The `bslmf::IsBitwiseEqualityComparable` trait for `double` and `float`
313/// types returns `true` which is incorrect because a comparison with a NaN
314/// value is always `false`, and -0 and +0 are equal.
315/// @code
316/// bsl::vector<double> v;
317/// v.push_back(bsl::numeric_limits<double>::quiet_NaN());
318/// ASSERT(v == v); // This assertion will *NOT* fail!
319/// @endcode
320/// Addressing this issue, i.e., updating `bslmf::IsBitwiseEqualityComparable`
321/// to return `false` for floating point types, could potentially destabilize
322/// production software so the change (for the moment) has not been made.
323///
324/// ## Usage {#bslstl_vector-usage}
325///
326///
327/// In this section we show intended use of this component.
328///
329/// ### Example 1: Creating a Matrix Type {#bslstl_vector-example-1-creating-a-matrix-type}
330///
331///
332/// Suppose we want to define a value-semantic type representing a dynamically
333/// resizable two-dimensional matrix.
334///
335/// First, we define the public interface for the `MyMatrix` class template:
336/// @code
337/// /// This value-semantic type characterizes a two-dimensional matrix of
338/// /// objects of the (template parameter) `TYPE`. The numbers of columns
339/// /// and rows of the matrix can be specified at construction and, at any
340/// /// time, via the `reset`, `insertRow`, and `insertColumn` methods. The
341/// /// value of each element in the matrix can be set and accessed using
342/// /// the `theValue`, and `theModifiableValue` methods respectively.
343/// template <class TYPE>
344/// class MyMatrix {
345///
346/// public:
347/// // PUBLIC TYPES
348/// @endcode
349/// Here, we create a type alias, `RowType`, for an instantiation of
350/// `bsl::vector` to represent a row of `TYPE` objects in the matrix. We create
351/// another type alias, `MatrixType`, for an instantiation of `bsl::vector` to
352/// represent the entire matrix of `TYPE` objects as a list of rows:
353/// @code
354/// /// This is an alias representing a row of values of the (template
355/// /// parameter) `TYPE`.
356/// typedef bsl::vector<TYPE> RowType;
357///
358/// /// This is an alias representing a two-dimensional matrix of values
359/// /// of the (template parameter) `TYPE`.
360/// typedef bsl::vector<RowType> MatrixType;
361///
362/// private:
363/// // DATA
364/// MatrixType d_matrix; // matrix of values
365/// int d_numColumns; // number of columns
366///
367/// // FRIENDS
368/// template <class T>
369/// friend bool operator==(const MyMatrix<T>&, const MyMatrix<T>&);
370///
371/// public:
372/// // PUBLIC TYPES
373/// typedef typename MatrixType::const_iterator ConstRowIterator;
374///
375/// // CREATORS
376///
377/// // Create a `MyMatrix` object having the specified `numRows` and
378/// // the specified `numColumns`. All elements of the (template
379/// // parameter) `TYPE` in the matrix will have the
380/// // default-constructed value. Optionally specify a
381/// // `basicAllocator` used to supply memory. If `basicAllocator` is
382/// // 0, the currently installed default allocator is used. The
383/// // behavior is undefined unless `0 <= numRows` and
384/// // `0 <= numColumns`
385/// MyMatrix(int numRows,
386/// int numColumns,
387/// bslma::Allocator *basicAllocator = 0);
388///
389/// // Create a `MyMatrix` object having the same value as the
390/// // specified `original` object. Optionally specify a
391/// // `basicAllocator` used to supply memory. If `basicAllocator` is
392/// // 0, the currently installed default allocator is used.
393/// MyMatrix(const MyMatrix& original,
394/// bslma::Allocator *basicAllocator = 0);
395///
396/// /// Destroy this object.
397/// //! ~MyMatrix = default;
398///
399/// // MANIPULATORS
400///
401/// /// Assign to this object the value of the specified `rhs` object,
402/// /// and return a reference providing modifiable access to this
403/// /// object.
404/// MyMatrix& operator=(const MyMatrix& rhs);
405///
406/// /// Remove all rows and columns from this object.
407/// void clear();
408///
409/// /// Insert, into this matrix, an column at the specified
410/// /// `columnIndex`. All elements of the (template parameter) `TYPE`
411/// /// in the column will have the default-constructed value. The
412/// /// behavior is undefined unless `0 <= columnIndex <= numColumns()`.
413/// void insertColumn(int columnIndex);
414///
415/// /// Insert, into this matrix, a row at the specified `rowIndex`.
416/// /// All elements of the (template parameter) `TYPE` in the row will
417/// /// have the default-constructed value. The behavior is undefined
418/// /// unless `0 <= rowIndex <= numRows()`.
419/// void insertRow(int rowIndex);
420///
421/// /// Return a reference providing modifiable access to the element at
422/// /// the specified `rowIndex` and the specified `columnIndex` in this
423/// /// matrix. The behavior is undefined unless
424/// /// `0 <= rowIndex < numRows()` and
425/// /// `0 <= columnIndex < numColumns()`.
426/// TYPE& theModifiableValue(int rowIndex, int columnIndex);
427///
428/// // ACCESSORS
429///
430/// /// Return the number of rows in this matrix.
431/// int numRows() const;
432///
433/// /// Return the number of columns in this matrix.
434/// int numColumns() const;
435///
436/// /// Return an iterator providing non-modifiable access to the
437/// /// `RowType` objects representing the first row in this matrix.
438/// ConstRowIterator beginRow() const;
439///
440/// /// Return an iterator providing non-modifiable access to the
441/// /// `RowType` objects representing the past-the-end row in this
442/// /// matrix.
443/// ConstRowIterator endRow() const;
444///
445/// /// Return a reference providing non-modifiable access to the
446/// /// element at the specified `rowIndex` and the specified
447/// /// `columnIndex` in this matrix. The behavior is undefined unless
448/// /// `0 <= rowIndex < numRows()` and
449/// /// `0 <= columnIndex < numColumns()`.
450/// const TYPE& theValue(int rowIndex, int columnIndex) const;
451/// };
452/// @endcode
453/// Then we declare the free operator for `MyMatrix`:
454/// @code
455/// // FREE OPERATORS
456///
457/// /// Return `true` if the specified `lhs` and `rhs` objects have the same
458/// /// value, and `false` otherwise. Two `MyMatrix` objects have the same
459/// /// value if they have the same number of rows and columns and every
460/// /// element in both matrices compare equal.
461/// template <class TYPE>
462/// MyMatrix<TYPE> operator==(const MyMatrix<TYPE>& lhs,
463/// const MyMatrix<TYPE>& rhs);
464///
465/// /// Return `true` if the specified `lhs` and `rhs` objects do not have
466/// /// the same value, and `false` otherwise. Two `MyMatrix` objects do
467/// /// not have the same value if they do not have the same number of rows
468/// /// and columns or every element in both matrices do not compare equal.
469/// template <class TYPE>
470/// MyMatrix<TYPE> operator!=(const MyMatrix<TYPE>& lhs,
471/// const MyMatrix<TYPE>& rhs);
472///
473/// /// Return a `MyMatrix` objects that is the product of the specified
474/// /// `lhs` and `rhs`. The behavior is undefined unless
475/// /// `lhs.numColumns() == rhs.numRows()`.
476/// template <class TYPE>
477/// MyMatrix<TYPE> operator*(const MyMatrix<TYPE>& lhs,
478/// const MyMatrix<TYPE>& rhs);
479/// @endcode
480/// Now, we define the methods of `MyMatrix`:
481/// @code
482/// // CREATORS
483/// template <class TYPE>
484/// MyMatrix<TYPE>::MyMatrix(int numRows,
485/// int numColumns,
486/// bslma::Allocator *basicAllocator)
487/// : d_matrix(numRows, basicAllocator)
488/// , d_numColumns(numColumns)
489/// {
490/// BSLS_ASSERT(0 <= numRows);
491/// BSLS_ASSERT(0 <= numColumns);
492///
493/// for (typename MatrixType::iterator itr = d_matrix.begin();
494/// itr != d_matrix.end();
495/// ++itr) {
496/// itr->resize(d_numColumns);
497/// }
498/// }
499/// template <class TYPE>
500/// MyMatrix<TYPE>::MyMatrix(const MyMatrix& original,
501/// bslma::Allocator *basicAllocator)
502/// : d_matrix(original.d_matrix, basicAllocator)
503/// , d_numColumns(original.d_numColumns)
504/// {
505/// }
506/// @endcode
507/// Notice that we pass the contained `bsl::vector` (`d_matrix`) the allocator
508/// specified at construction to supply memory. If the (template parameter)
509/// `TYPE` of the elements has the `bslalg_TypeTraitUsesBslmaAllocator` trait,
510/// this allocator will be passed by the vector to the elements as well.
511/// @code
512/// // MANIPULATORS
513/// template <class TYPE>
514/// MyMatrix<TYPE>& MyMatrix<TYPE>::operator=(const MyMatrix& rhs)
515/// {
516/// d_matrix = rhs.d_matrix;
517/// d_numColumns = rhs.d_numColumns;
518/// }
519///
520/// template <class TYPE>
521/// void MyMatrix<TYPE>::clear()
522/// {
523/// d_matrix.clear();
524/// d_numColumns = 0;
525/// }
526///
527/// template <class TYPE>
528/// void MyMatrix<TYPE>::insertColumn(int colIndex) {
529/// for (typename MatrixType::iterator itr = d_matrix.begin();
530/// itr != d_matrix.end();
531/// ++itr) {
532/// itr->insert(itr->begin() + colIndex, TYPE());
533/// }
534/// ++d_numColumns;
535/// }
536///
537/// template <class TYPE>
538/// void MyMatrix<TYPE>::insertRow(int rowIndex)
539/// {
540/// typename MatrixType::iterator itr =
541/// d_matrix.insert(d_matrix.begin() + rowIndex, RowType());
542/// itr->resize(d_numColumns);
543/// }
544///
545/// template <class TYPE>
546/// TYPE& MyMatrix<TYPE>::theModifiableValue(int rowIndex, int columnIndex)
547/// {
548/// BSLS_ASSERT(0 <= rowIndex);
549/// BSLS_ASSERT(rowIndex < d_matrix.size());
550/// BSLS_ASSERT(0 <= columnIndex);
551/// BSLS_ASSERT(columnIndex < d_numColumns);
552///
553/// return d_matrix[rowIndex][columnIndex];
554/// }
555///
556/// // ACCESSORS
557/// template <class TYPE>
558/// int MyMatrix<TYPE>::numRows() const
559/// {
560/// return d_matrix.size();
561/// }
562///
563/// template <class TYPE>
564/// int MyMatrix<TYPE>::numColumns() const
565/// {
566/// return d_numColumns;
567/// }
568///
569/// template <class TYPE>
570/// typename MyMatrix<TYPE>::ConstRowIterator MyMatrix<TYPE>::beginRow() const
571/// {
572/// return d_matrix.begin();
573/// }
574///
575/// template <class TYPE>
576/// typename MyMatrix<TYPE>::ConstRowIterator MyMatrix<TYPE>::endRow() const
577/// {
578/// return d_matrix.end();
579/// }
580///
581/// template <class TYPE>
582/// const TYPE& MyMatrix<TYPE>::theValue(int rowIndex, int columnIndex) const
583/// {
584/// BSLS_ASSERT(0 <= rowIndex);
585/// BSLS_ASSERT(rowIndex < d_matrix.size());
586/// BSLS_ASSERT(0 <= columnIndex);
587/// BSLS_ASSERT(columnIndex < d_numColumns);
588///
589/// return d_matrix[rowIndex][columnIndex];
590/// }
591/// @endcode
592/// Finally, we defines the free operators for `MyMatrix`:
593/// @code
594/// // FREE OPERATORS
595/// template <class TYPE>
596/// MyMatrix<TYPE> operator==(const MyMatrix<TYPE>& lhs,
597/// const MyMatrix<TYPE>& rhs)
598/// {
599/// return lhs.d_numColumns == rhs.d_numColumns &&
600/// lhs.d_matrix == rhs.d_matrix;
601/// }
602///
603/// template <class TYPE>
604/// MyMatrix<TYPE> operator!=(const MyMatrix<TYPE>& lhs,
605/// const MyMatrix<TYPE>& rhs)
606/// {
607/// return !(lhs == rhs);
608/// }
609/// @endcode
610/// @}
611/** @} */
612/** @} */
613
614/** @addtogroup bsl
615 * @{
616 */
617/** @addtogroup bslstl
618 * @{
619 */
620/** @addtogroup bslstl_vector
621 * @{
622 */
623
624#include <bslscm_version.h>
625
626#include <bslstl_algorithm.h>
627#include <bslstl_compare.h>
628#include <bslstl_hash.h>
629#include <bslstl_iterator.h>
630#include <bslstl_iteratorutil.h>
631#include <bslstl_ranges.h>
632#include <bslstl_stdexceptutil.h>
633
636#include <bslalg_containerbase.h>
637#include <bslalg_rangecompare.h>
639#include <bslalg_swaputil.h>
641
642#include <bslh_hash.h>
643
644#include <bslma_allocator.h>
646#include <bslma_allocatorutil.h>
647#include <bslma_autodestructor.h>
648#include <bslma_isstdallocator.h>
649#include <bslma_bslallocator.h>
651
653#include <bslmf_enableif.h>
655#include <bslmf_isconvertible.h>
656#include <bslmf_isfundamental.h>
657#include <bslmf_isintegral.h>
658#include <bslmf_issame.h>
659#include <bslmf_matchanytype.h>
661#include <bslmf_movableref.h>
662#include <bslmf_nil.h>
663#include <bslmf_typeidentity.h>
664#include <bslmf_util.h> // 'forward(V)'
665
666#include <bsls_assert.h>
668#include <bsls_keyword.h>
669#include <bsls_libraryfeatures.h>
670#include <bsls_performancehint.h>
671#include <bsls_platform.h>
672#include <bsls_types.h>
673#include <bsls_util.h> // 'forward<T>(V)'
674
675#include <cstddef>
676
677#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
678
679#include <initializer_list>
680#endif
681
682#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
683
684#include <stdexcept>
685#endif
686
687#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
688# define BSLSTL_VECTOR_REQUIRES_CONTAINER_COMPATIBLE_RANGE(R, T) \
689 requires ::BloombergLP::bslmf::ContainerCompatibleRange<R, T>
690#else
691# define BSLSTL_VECTOR_REQUIRES_CONTAINER_COMPATIBLE_RANGE(R, T)
692#endif
693
694#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
695// clang-format off
696// Include version that can be compiled with C++03
697// Generated on Mon Jan 13 08:31:40 2025
698// Command line: sim_cpp11_features.pl bslstl_vector.h
699
700# define COMPILING_BSLSTL_VECTOR_H
701# include <bslstl_vector_cpp03.h>
702# undef COMPILING_BSLSTL_VECTOR_H
703
704// clang-format on
705#else
706
707namespace bsl {
708
709// Forward declarations
710
711template <class VALUE_TYPE, class ITERATOR>
712class vector_UintPtrConversionIterator;
713
714 // ==================
715 // struct Vector_Util
716 // ==================
717
718/// This `struct` provides a namespace for implementing the `swap` member
719/// function of `vector<VALUE_TYPE, ALLOCATOR>`. `swap` can be implemented
720/// irrespective of the `VALUE_TYPE` or `ALLOCATOR` template parameters, which
721/// is why we implement it in this non-parameterized, non-inlined utility.
722///
723/// See @ref bslstl_vector
725
726 // CLASS METHODS
727
728 /// Return a capacity that is at least the specified `newLength` and at
729 /// least twice the specified `capacity` if this is less than the specified
730 /// `maxSize`, but never more than `maxSize`.
731 ///
732 /// \pre The behavior is undefined unless `capacity < newLength` and `newLength <= maxSize`.
733 static std::size_t computeNewCapacity(std::size_t newLength,
734 std::size_t capacity,
735 std::size_t maxSize);
736
737 /// Exchange the value of the specified `a` vector with that of the
738 /// specified `b` vector.
739 static void swap(void *a, void *b);
740};
741
742
743 // ===================================
744 // class Vector_DeduceIteratorCategory
745 // ===================================
746
747/// This `struct` provides a primitive means to distinguish between iterator
748/// types and fundamental types, in order to dispatch to the correct
749/// implementation of a function template (or constructor template) passed
750/// two arguments of identical type. By default, it is assumed that any
751/// type that is not a fundamental type, as determined by the type trait
752/// `bsl::is_fundamental`, must be an iterator type. `std::iterator_traits`
753/// is updated in C++17 to provide a SFINAE-friendly instantiation of the
754/// primary-template for types that do not provide all of the nested typedef
755/// names, but we cannot portably rely on such a scheme yet.
756///
757/// See @ref bslstl_vector
758template <class BSLSTL_ITERATOR,
759 bool BSLSTL_NOTSPECIALIZED = is_fundamental<BSLSTL_ITERATOR>::value>
761
762 // PUBLIC TYPES
763 typedef typename bsl::iterator_traits<BSLSTL_ITERATOR>::iterator_category
765};
766
767/// This partial specialization of the `struct` template for fundamental
768/// types provides a nested `type` that is not an iterator category, so can
769/// be used to control the internal dispatch of function template overloads
770/// taking two arguments of the same type.
771template <class BSLSTL_ITERATOR>
772struct Vector_DeduceIteratorCategory<BSLSTL_ITERATOR, true> {
773
774 // PUBLIC TYPES
775 typedef BloombergLP::bslmf::Nil type;
776};
777
778
779 // ==================================
780 // class Vector_RangeIteratorCategory
781 // ==================================
782
783/// This `struct` provides a primitive means to determine the iterator category
784/// for an iterator/sentinel pair where there is a preference to treat any
785/// iterator where the `insertDistance` can be computed as a forward iterator,
786/// even if it does not meet the ranges concepts needed to be treated as one.
787///
788/// See @ref bslstl_vector
789template <class t_ITERATOR,
790 class t_SENTINEL,
791 bool t_NOTSPECIALIZED =
795
796 // PUBLIC TYPES
797#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
798 // Treat an iterator like an input iterator if we can compute an insert
799 // distance in a SFINAE-friendly manner, otherwise just treat it like an
800 // input iterator.
801 typedef bsl::conditional_t<
802 BloombergLP::bslstl::IteratorUtil
803 ::canCalculateInsertDistance<t_ITERATOR, t_SENTINEL>(),
804 typename bsl::iterator_traits<t_ITERATOR>::iterator_category,
805 std::input_iterator_tag> type;
806#else
807 typedef typename bsl::iterator_traits<t_ITERATOR>::iterator_category type;
808#endif
809};
810
811/// This partial specialization of the `struct` template for fundamental
812/// types provides a nested `type` that is not an iterator category, so can
813/// be used to control the internal dispatch of function template overloads
814/// taking two arguments of the same type.
815template <class t_ITERATOR, class t_SENTINEL>
816struct Vector_RangeIteratorCategory<t_ITERATOR, t_SENTINEL, true> {
817
818 // PUBLIC TYPES
819 typedef BloombergLP::bslmf::Nil type;
820};
821
822 // ======================================
823 // class vector_UintPtrConversionIterator
824 // ======================================
825
826/// This metafunction provides an appropriate iterator adaptor for the
827/// specified (template parameter) type `ITERATOR` in order to implement
828/// members of the `vector` partial template specialization for vectors of
829/// pointers to the (template parameter) type `TARGET`. The metafunction
830/// will return the original `ITERATOR` type unless it truly is an iterator,
831/// using `is_integral` as a proxy for testing that a type is NOT an
832/// iterator. This is needed to disambiguate only the cases of users
833/// passing `0` as a null-pointer value to functions requesting a number of
834/// identical copies of an element.
835///
836/// See @ref bslstl_vector
837template <class TARGET, class ITERATOR, bool = is_integral<ITERATOR>::value>
839
840 // PUBLIC TYPES
841 typedef ITERATOR type;
842};
843
844/// This metafunction specialization provides an appropriate iterator
845/// adaptor for the specified (template parameter) type `ITERATOR` in order
846/// to implement members of the `vector` partial template specialization for
847/// vectors of pointers to the (template parameter) type `TARGET`.
848template <class TARGET, class ITERATOR>
849struct vector_ForwardIteratorForPtrs<TARGET, ITERATOR, false> {
850
851 // PUBLIC TYPES
853};
854
855#if defined(BSLS_ASSERT_SAFE_IS_USED)
856
857template <class BSLSTL_ITERATOR>
858struct Vector_IsRandomAccessIterator :
859 bsl::is_same<typename Vector_DeduceIteratorCategory<BSLSTL_ITERATOR>::type,
860 bsl::random_access_iterator_tag>::type
861{
862};
863
864
865 // =======================
866 // class Vector_RangeCheck
867 // =======================
868
869/// This utility class provides a test-support facility to diagnose when a
870/// pair of iterators do *not* form a valid range. This support is offered
871/// only for random access iterators, and identifies only the case of two
872/// valid iterators into the same range forming a "reverse" range.
873///
874/// \note Note that the two functions declared using `enable_if` must be defined inline
875/// in the class definition due to a bug in the Microsoft C++ compiler (see
876/// @ref bslmf_enableif ).
877///
878/// See @ref bslstl_vector
879struct Vector_RangeCheck {
880
881 // CLASS METHODS
882
883 /// Return `false`.
884 /// \note Note that we know of no way to identify an input
885 /// iterator range that is guaranteed to be invalid.
886 template <class BSLSTL_ITERATOR, class SENTINEL>
887 static
888 typename bsl::enable_if<
889 !Vector_IsRandomAccessIterator<BSLSTL_ITERATOR>::value, bool>::type
890 isInvalidRange(BSLSTL_ITERATOR, SENTINEL);
891
892 /// Return `true` if `last < first`, and `false` otherwise.
893 ///
894 /// \pre The behavior is undefined unless both `first` and `last` are valid
895 /// iterators that refer to the same range.
896 template <class BSLSTL_ITERATOR>
897 static
898 typename bsl::enable_if<
899 Vector_IsRandomAccessIterator<BSLSTL_ITERATOR>::value, bool>::type
900 isInvalidRange(BSLSTL_ITERATOR first, BSLSTL_ITERATOR last);
901 template <class BSLSTL_ITERATOR, class SENTINEL>
902 static
903 typename bsl::enable_if<
904 Vector_IsRandomAccessIterator<BSLSTL_ITERATOR>::value, bool>::type
905 isInvalidRange(BSLSTL_ITERATOR first, SENTINEL last);
906};
907
908#endif
909
910 // ================
911 // class vectorBase
912 // ================
913
914/// This class describes the basic layout for a vector class, to be included
915/// into the `vector` layout *before* the allocator (provided by
916/// `bslalg::ContainerBase`) to take better advantage of cache prefetching. It
917/// is parameterized by `VALUE_TYPE` only, and implements the portion of
918/// `vector` that does not need to know about its (template parameter) type
919/// `ALLOCATOR` (in order to generate shorter debug strings). This class
920/// intentionally has **no** creators (other than the compiler-generated ones).
921///
922/// See @ref bslstl_vector
923template <class VALUE_TYPE>
925
926 // PRIVATE TYPES
927
928 /// This `typedef` is a convenient alias for the utility associated with
929 /// movable references.
930 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
931
932 protected:
933 // PROTECTED DATA
934 VALUE_TYPE *d_dataBegin_p; // beginning of data storage (owned)
935 VALUE_TYPE *d_dataEnd_p; // one past the end of data storage
936 std::size_t d_capacity; // capacity of data storage in # of elements
937
938 public:
939 // PUBLIC TYPES
940 typedef VALUE_TYPE value_type;
941 typedef VALUE_TYPE& reference;
942 typedef VALUE_TYPE const& const_reference;
943 typedef VALUE_TYPE *iterator;
944 typedef VALUE_TYPE const *const_iterator;
945 typedef std::size_t size_type;
946 typedef std::ptrdiff_t difference_type;
947 typedef bsl::reverse_iterator<iterator> reverse_iterator;
948 typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;
949
950 public:
951 // CREATORS
952
953 /// Create an empty base object with no capacity.
955
956 // MANIPULATORS
957
958 /// Adopt all outstanding memory allocations associated with the specified `base` object.
959 ///
960 /// \pre The behavior is undefined unless this object is in a
961 /// default-constructed state.
962 void adopt(BloombergLP::bslmf::MovableRef<vectorBase> base);
963
964 // *** iterators ***
965
966 /// Return an iterator providing modifiable access to the first element in
967 /// this vector, or the past-the-end iterator if this vector is empty.
969
970 /// Return the past-the-end iterator providing modifiable access to this
971 /// vector.
973
974 /// Return a reverse iterator providing modifiable access to the last
975 /// element in this vector, and the past-the-end reverse iterator if this
976 /// vector is empty.
978
979 /// Return the past-the-end reverse iterator providing modifiable access to
980 /// this vector.
982
983 // *** element access ***
984
985 /// Return a reference providing modifiable access to the element at the specified `position` in this vector.
986 ///
987 /// \pre The behavior is undefined unless
988 /// `position < size()`.
989 reference operator[](size_type position);
990
991 /// Return a reference providing modifiable access to the element at the
992 /// specified `position` in this vector. Throw a `std::out_of_range`
993 /// exception if `position >= size()`.
995
996 /// Return a reference providing modifiable access to the first element in this vector.
997 ///
998 /// \pre The behavior is undefined unless this vector is not
999 /// empty.
1001
1002 /// Return a reference providing modifiable access to the last element in this vector.
1003 ///
1004 /// \pre The behavior is undefined unless this vector is not
1005 /// empty.
1007
1008 /// Return the address of the modifiable first element in this vector, or a
1009 /// valid, but non-dereferenceable pointer value if this vector is empty.
1011
1012 // ACCESSORS
1013
1014 // *** iterators ***
1015
1017
1018 /// Return an iterator providing non-modifiable access to the first element
1019 /// in this vector, and the past-the-end iterator if this vector is empty.
1021
1023
1024 /// Return the past-the-end (forward) iterator providing non-modifiable
1025 /// access to this vector.
1027
1029
1030 /// Return a reverse iterator providing non-modifiable access to the last
1031 /// element in this vector, and the past-the-end reverse iterator if this
1032 /// vector is empty.
1034
1036
1037 /// Return the past-the-end reverse iterator providing non-modifiable
1038 /// access to this vector.
1040
1041 // *** capacity ***
1042
1043 /// Return the number of elements in this vector.
1045
1046 /// Return the capacity of this vector, i.e., the maximum number of
1047 /// elements for which resizing is guaranteed not to trigger a
1048 /// reallocation.
1050
1051 /// Return `true` if this vector has size 0, and `false` otherwise.
1053
1054 // *** element access ***
1055
1056 /// Return a reference providing non-modifiable access to the element at
1057 /// the specified `position` in this vector.
1058 ///
1059 /// \pre The behavior is undefined unless `position < size()`.
1060 const_reference operator[](size_type position) const;
1061
1062 /// Return a reference providing non-modifiable access to the element at
1063 /// the specified `position` in this vector. Throw a
1064 /// `bsl::out_of_range` exception if `position >= size()`.
1066
1067 /// Return a reference providing non-modifiable access to the first element in this vector.
1068 ///
1069 /// \pre The behavior is undefined unless this
1070 /// vector is not empty.
1072
1073 /// Return a reference providing non-modifiable access to the last element in this vector.
1074 ///
1075 /// \pre The behavior is undefined unless this
1076 /// vector is not empty.
1078
1079 /// Return the address of the non-modifiable first element in this
1080 /// vector, or a valid, but non-dereferenceable pointer value if this
1081 /// vector is empty.
1082 const VALUE_TYPE *data() const BSLS_KEYWORD_NOEXCEPT;
1083};
1084
1085 // ============
1086 // class vector
1087 // ============
1088
1089/// This class template provides an STL-compliant `vector` that conforms to
1090/// the `bslma::Allocator` model. For the requirements of a vector class,
1091/// consult the C++11 standard. In particular, this implementation offers
1092/// the general rules that:
1093///
1094/// 1. A call to any method that would result in a vector having a size
1095/// or capacity greater than the value returned by @ref max_size triggers a
1096/// call to `bslstl::StdExceptUtil::throwLengthError`.
1097/// 2. A call to an `at` method that attempts to access a position outside
1098/// of the valid range of a vector triggers a call to
1099/// `bslstl::StdExceptUtil::throwOutOfRange`.
1100///
1101///
1102/// \note Note that portions of the standard methods are implemented in
1103/// `vectorBase`, which is parameterized on only `VALUE_TYPE` in order to
1104/// generate smaller debug strings.
1105///
1106/// This class:
1107/// * supports a complete set of *value-semantic* operations
1108/// - except for `BDEX` serialization
1109/// * is *exception-neutral*
1110/// * is *alias-safe*
1111/// * is `const` *thread-safe*
1112/// For terminology see @ref bsldoc_glossary .
1113///
1114/// In addition, the following members offer a full guarantee of rollback: if
1115/// an exception is thrown during the invocation of `push_back` or `insert`
1116/// with a single element at the end of a pre-existing object, the object is
1117/// left in a valid state and its value is unchanged.
1118template <class VALUE_TYPE, class ALLOCATOR = allocator<VALUE_TYPE> >
1119class vector : public vectorBase<VALUE_TYPE>
1120 , private BloombergLP::bslalg::ContainerBase<ALLOCATOR> {
1121
1122 // PRIVATE TYPES
1123
1124 /// This `typedef` is an alias for a utility class that provides many
1125 /// useful functions that operate on arrays.
1126 typedef BloombergLP::bslalg::ArrayPrimitives ArrayPrimitives;
1127
1128 /// This `typedef` is a convenient alias for the utility associated with
1129 /// movable references.
1130 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
1131
1132 /// This `typedef` is an alias for a utility class that provides many
1133 /// useful functions that operate on allocators.
1134 typedef BloombergLP::bslma::AllocatorUtil AllocatorUtil;
1135
1136 /// This `typedef` is an alias for the allocator traits type associated
1137 /// with this container.
1139
1140 public:
1141 // PUBLIC TYPES
1142 typedef VALUE_TYPE value_type;
1143 typedef ALLOCATOR allocator_type;
1144 typedef VALUE_TYPE& reference;
1145 typedef const VALUE_TYPE& const_reference;
1146
1147 typedef typename AllocatorTraits::size_type size_type;
1151
1152 typedef VALUE_TYPE *iterator;
1153 typedef VALUE_TYPE const *const_iterator;
1154 typedef bsl::reverse_iterator<iterator> reverse_iterator;
1155 typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;
1156
1157 private:
1158 // PRIVATE TYPES
1159
1160 /// Implementation base type, with iterator-related functionality.
1161 typedef vectorBase<VALUE_TYPE> ImpBase;
1162
1163 /// Container base type, containing the allocator and applying the empty
1164 /// base class optimization (EBO) whenever appropriate.
1165 typedef BloombergLP::bslalg::ContainerBase<ALLOCATOR> ContainerBase;
1166
1167 /// This class provides a proctor for deallocating an array of `VALUE_TYPE`
1168 /// objects, to be used in the `vector` constructors.
1169 ///
1170 /// See @ref bslstl_vector
1171 class Proctor {
1172
1173 // DATA
1174 VALUE_TYPE *d_data_p; // array pointer
1175 std::size_t d_capacity; // capacity of the array
1176 ContainerBase *d_container_p; // container base pointer
1177
1178 private:
1179 // NOT IMPLEMENTED
1180 Proctor(const Proctor&);
1181 Proctor& operator=(const Proctor&);
1182
1183 public:
1184 // CREATORS
1185
1186 /// Create a proctor for the specified `data` array of the specified
1187 /// `capacity`, using the `deallocateN` method of the specified
1188 /// `container` to return `data` to its allocator upon destruction,
1189 /// unless this proctor's `release` is called prior.
1190 Proctor(VALUE_TYPE *data,
1191 std::size_t capacity,
1192 ContainerBase *container);
1193
1194 /// Destroy this proctor, deallocating any data under management.
1195 ~Proctor();
1196
1197 // MANIPULATORS
1198
1199 /// Release the data from management by this proctor.
1200 void release();
1201 };
1202
1203 // PRIVATE MANIPULATORS
1204
1205 /// Populate a default-constructed vector with the values held in the
1206 /// specified `range`. This method should be called only from a constructor.
1207 ///
1208 /// \pre The behavior is undefined unless the specified `begin`
1209 /// is the first element in `range`.
1210 template <class t_RANGE, class t_ITERATOR>
1211 void privateConstruct(from_range_t ,
1212 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
1213 t_ITERATOR begin);
1214
1215 /// Populate a default-constructed vector with the values held in the
1216 /// specified `range`. This method should be called only from a constructor.
1217 ///
1218 /// \pre The behavior is undefined unless the specified `begin`
1219 /// is the first element in `range`.
1220 template <class t_RANGE, class t_ITERATOR>
1221 void privateConstruct(from_range_t ,
1222 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
1223 t_ITERATOR begin,
1224 std::forward_iterator_tag);
1225 template <class t_RANGE, class t_ITERATOR>
1226 void privateConstruct(from_range_t ,
1227 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
1228 t_ITERATOR begin,
1229 std::input_iterator_tag);
1230
1231 /// Populate a default-constructed vector with the values held in the
1232 /// specified range `[first, last)`. The additional
1233 /// `std::*iterator__tag` should be a default-constructed tag that
1234 /// corresponds to that found in `std::iterator_traits` for the
1235 /// (template parameter) `*_ITER` type. This method should be called only from a constructor.
1236 ///
1237 /// \pre The behavior is undefined unless
1238 /// `first != last`.
1239 template <class FWD_ITER, class SENTINEL>
1240 void constructFromRange(FWD_ITER first,
1241 SENTINEL last,
1242 std::forward_iterator_tag);
1243 template <class INPUT_ITER, class SENTINEL>
1244 void constructFromRange(INPUT_ITER first,
1245 SENTINEL last,
1246 std::input_iterator_tag);
1247
1248 /// Populate a default-constructed vector with the specified
1249 /// `initialSize` elements, where each such element is a copy of the
1250 /// specified `value`. The `bslmf::Nil` traits value distinguished this
1251 /// overload of two identical (presumed integral) types from the pair of
1252 /// iterator overloads above. This method should be called only from a
1253 /// constructor.
1254 template <class INTEGRAL>
1255 void constructFromRange(INTEGRAL initialSize,
1256 INTEGRAL value,
1257 BloombergLP::bslmf::Nil);
1258
1259
1260 /// Populate a default-constructed vector with the values held in the
1261 /// specified `[first, last)` range. The specified `size` is the number
1262 /// of elements in the range.
1263 template <class t_ITERATOR, class t_SENTINEL>
1264 void constructFromSizedRange(t_ITERATOR first,
1265 t_SENTINEL last,
1266 size_type size);
1267
1268 /// Append the values from the specified `range`.
1269 ///
1270 /// \pre The behavior is undefined unless the specified `begin` is the first element in `range`.
1271 template <class t_RANGE, class t_ITERATOR>
1272 void privateAppendRange(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
1273 t_ITERATOR begin);
1274 template <class t_RANGE, class t_ITERATOR>
1275 void privateAppendRange(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
1276 t_ITERATOR begin,
1277 std::forward_iterator_tag);
1278 template <class t_RANGE, class t_ITERATOR>
1279 void privateAppendRange(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
1280 t_ITERATOR begin,
1281 std::input_iterator_tag);
1282
1283 /// Append the values from the specified `[begin, end)` range. The
1284 /// specified `rangeSize` is the number of elements in the range.
1285 template <class t_ITERATOR, class t_SENTINEL>
1286 void privateAppendSizedRange(t_ITERATOR begin,
1287 t_SENTINEL end,
1288 size_type rangeSize);
1289
1290 /// Append the values from the specified `[begin, end)` range.
1291 template <class t_ITERATOR, class t_SENTINEL>
1292 void privateAppendUnsizedRange(t_ITERATOR begin, t_SENTINEL end);
1293
1294 /// Match integral type for `INPUT_ITER`.
1295 template <class INPUT_ITER>
1296 void privateInsertDispatch(
1297 const_iterator position,
1298 INPUT_ITER count,
1299 INPUT_ITER value,
1300 BloombergLP::bslmf::MatchArithmeticType ,
1301 BloombergLP::bslmf::Nil );
1302
1303 /// Match non-integral type for `INPUT_ITER`.
1304 template <class INPUT_ITER>
1305 void privateInsertDispatch(const_iterator position,
1306 INPUT_ITER first,
1307 INPUT_ITER last,
1308 BloombergLP::bslmf::MatchAnyType ,
1309 BloombergLP::bslmf::MatchAnyType );
1310
1311 /// Range insert implementation function.
1312 template <class t_ITERATOR, class t_SENTINEL>
1313 void privateInsert(const_iterator position,
1314 t_ITERATOR first,
1315 t_SENTINEL last);
1316
1317 /// Specialized insertion for input iterators.
1318 template <class INPUT_ITER, class SENTINEL>
1319 void privateInsert(const_iterator position,
1320 INPUT_ITER first,
1321 SENTINEL last,
1322 const std::input_iterator_tag&);
1323
1324 /// Specialized insertion for forward, bidirectional, and random-access
1325 /// iterators.
1326 template <class FWD_ITER, class SENTINEL>
1327 void privateInsert(const_iterator position,
1328 FWD_ITER first,
1329 SENTINEL last,
1330 const std::forward_iterator_tag&);
1331
1332 /// Destructive move insertion from a temporary vector, to avoid
1333 /// duplicate copies after importing from an input iterator into a
1334 /// temporary vector.
1335 void privateMoveInsert(vector *fromVector,
1336 const_iterator position);
1337
1338 /// Reserve exactly the specified `numElements`.
1339 ///
1340 /// \pre The behavior is undefined unless this vector is empty and has no capacity.
1341 void privateReserveEmpty(size_type numElements);
1342
1343#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1344 /// Change the capacity of this vector and append to its end a newly
1345 /// created `value_type` object, constructed by forwarding
1346 /// `get_allocator()` (if required) and the specified (variable number
1347 /// of) `arguments` to the corresponding constructor of `value_type`.
1348 /// If an exception is thrown (other than by the move constructor of a
1349 /// non-copy-insertable `value_type`), `*this` is unaffected. Throw
1350 /// `std::length_error` if `size() == max_size()`.
1351 template <class... Args>
1352 void privateEmplaceBackWithAllocation(Args&&...arguments);
1353#endif
1354
1355 /// Append a copy of the specified `value` to the end of this vector
1356 /// after changing its capacity. If an exception is thrown, `*this` is
1357 /// unaffected. Throw `std::length_error` if `size() == max_size()`.
1358 void privatePushBackWithAllocation(const VALUE_TYPE& value);
1359
1360 /// Append the specified move-insertable `value` to the end of this
1361 /// vector after changing its capacity. `value` is left in a valid but
1362 /// unspecified state. If an exception is thrown (other than by the
1363 /// move constructor of a non-copy-insertable `value_type`), `*this` is
1364 /// unaffected. Throw `std::length_error` if `size() == max_size()`.
1365 void privatePushBackWithAllocation(
1366 BloombergLP::bslmf::MovableRef<VALUE_TYPE> value);
1367
1368 public:
1369 // CREATORS
1370
1371 // *** construct/copy/destroy ***
1372
1374
1375 /// Create an empty vector. Optionally specify a `basicAllocator` used
1376 /// to supply memory. If `basicAllocator` is not specified, a
1377 /// default-constructed object of the (template parameter) type
1378 /// `ALLOCATOR` is used. If the type `ALLOCATOR` is `bsl::allocator`
1379 /// and `basicAllocator` is not supplied, the currently installed default allocator is used.
1380 ///
1381 /// \note Note that a `bslma::Allocator *` can be
1382 /// supplied for `basicAllocator` if the type `ALLOCATOR` is
1383 /// `bsl::allocator` (the default).
1384 explicit vector(const ALLOCATOR& basicAllocator) BSLS_KEYWORD_NOEXCEPT;
1385
1386 /// Create a vector of the specified `initialSize` whose every element
1387 /// is a default-constructed object of the (template parameter) type
1388 /// `VALUE_TYPE`. Optionally specify a `basicAllocator` used to supply
1389 /// memory. If `basicAllocator` is not specified, a default-constructed
1390 /// object of the (template parameter) type `ALLOCATOR` is used. If the
1391 /// type `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
1392 /// supplied, the currently installed default allocator is used. Throw
1393 /// `std::length_error` if `initialSize > max_size()`. This method
1394 /// requires that the type `VALUE_TYPE` be `default-insertable` into this vector (see {Requirements on `VALUE_TYPE`}).
1395 ///
1396 /// \note Note that a
1397 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
1398 /// type `ALLOCATOR` is `bsl::allocator` (the default).
1399 explicit vector(size_type initialSize,
1400 const ALLOCATOR& basicAllocator = ALLOCATOR());
1401
1402 /// Create a vector of the specified `initialSize` whose every element
1403 /// is a copy of the specified `value`. Optionally specify a
1404 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
1405 /// specified, a default-constructed object of the (template parameter)
1406 /// type `ALLOCATOR` is used. If the type `ALLOCATOR` is
1407 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
1408 /// installed default allocator is used. Throw `std::length_error` if
1409 /// `initialSize > max_size()`. This method requires that the (template
1410 /// parameter) type `VALUE_TYPE` be `copy-insertable` into this vector (see {Requirements on `VALUE_TYPE`}).
1411 ///
1412 /// \note Note that a
1413 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
1414 /// type `ALLOCATOR` is `bsl::allocator` (the default).
1415 vector(size_type initialSize,
1416 const VALUE_TYPE& value,
1417 const ALLOCATOR& basicAllocator = ALLOCATOR());
1418
1419 /// Create a vector, and insert (in order) each `VALUE_TYPE` object in
1420 /// the range starting at the specified `first` element, and ending
1421 /// immediately before the specified `last` element. Optionally specify
1422 /// a `basicAllocator` used to supply memory. If `basicAllocator` is
1423 /// not specified, a default-constructed object of the (template
1424 /// parameter) type `ALLOCATOR` is used. If the type `ALLOCATOR` is
1425 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
1426 /// installed default allocator is used. Throw `std::length_error` if
1427 /// the number of elements in `[first .. last)` exceeds the value
1428 /// returned by the method @ref max_size . The (template parameter) type
1429 /// `INPUT_ITER` shall meet the requirements of an input iterator
1430 /// defined in the C++11 standard [24.2.3] providing access to values of
1431 /// a type convertible to `value_type`, and `value_type` must be
1432 /// `emplace-constructible` from `*i` into this vector, where `i` is a
1433 /// dereferenceable iterator in the range `[first .. last)` (see {Requirements on `VALUE_TYPE`}).
1434 ///
1435 /// \pre The behavior is undefined unless
1436 /// `first` and `last` refer to a range of valid values where `first` is at a position at or before `last`.
1437 ///
1438 /// \note Note that a
1439 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
1440 /// type `ALLOCATOR` is `bsl::allocator` (the default).
1441 template <class INPUT_ITER>
1442 vector(INPUT_ITER first,
1443 INPUT_ITER last,
1444 const ALLOCATOR& basicAllocator = ALLOCATOR());
1445
1446 /// Create a vector from the elements of the specifed `range`. Optionally
1447 /// specify a `basicAllocator` used to supply memory. If `basicAllocator`
1448 /// is not specified, a default-constructed object of the (template parameter) type `ALLOCATOR` is used.
1449 ///
1450 /// \note Note that `range` must meet the
1451 /// requirements of an input range and the values from `range` must have a
1452 /// type matching or convertible to (template parameter) `VALUE_TYPE`.
1453 template <class t_RANGE>
1456 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
1457 const ALLOCATOR& basicAllocator =
1458 ALLOCATOR());
1459
1460 /// Create a vector having the same value as the specified `original`
1461 /// object. Use the allocator returned by
1462 /// 'bsl::allocator_traits<ALLOCATOR>::
1463 /// select_on_container_copy_construction(original.get_allocator())' to
1464 /// allocate memory. This method requires that the (template parameter)
1465 /// type `VALUE_TYPE` be `copy-insertable` into this vector (see
1466 /// {Requirements on `VALUE_TYPE`}).
1467 vector(const vector& original);
1468
1469 /// Create a vector having the same value as the specified `original`
1470 /// object by moving (in constant time) the contents of `original` to
1471 /// the new vector. The allocator associated with `original` is
1472 /// propagated for use in the newly-created vector. `original` is left
1473 /// in a valid but unspecified state.
1474 vector(BloombergLP::bslmf::MovableRef<vector> original)
1475 BSLS_KEYWORD_NOEXCEPT; // IMPLICIT
1476
1477 /// Create a vector having the same value as the specified `original`
1478 /// object that uses the specified `basicAllocator` to supply memory.
1479 /// This method requires that the (template parameter) type `VALUE_TYPE`
1480 /// be `copy-insertable` into this vector (see {Requirements on `VALUE_TYPE`}).
1481 ///
1482 /// \note Note that a `bslma::Allocator *` can be supplied
1483 /// for `basicAllocator` if the (template parameter) type `ALLOCATOR` is
1484 /// `bsl::allocator` (the default).
1485 vector(const vector& original,
1486 const typename type_identity<ALLOCATOR>::type& basicAllocator);
1487
1488 /// Create a vector having the same value as the specified `original`
1489 /// object that uses the specified `basicAllocator` to supply memory.
1490 /// The contents of `original` are moved (in constant time) to the new
1491 /// vector if `basicAllocator == original.get_allocator()`, and are
1492 /// move-inserted (in linear time) using `basicAllocator` otherwise.
1493 /// `original` is left in a valid but unspecified state. This method
1494 /// requires that the (template parameter) type `VALUE_TYPE` be
1495 /// `move-insertable` into this vector (see {Requirements on `VALUE_TYPE`}).
1496 ///
1497 /// \note Note that a `bslma::Allocator *` can be supplied
1498 /// for `basicAllocator` if the (template parameter) type `ALLOCATOR` is
1499 /// `bsl::allocator` (the default).
1500 vector(BloombergLP::bslmf::MovableRef<vector> original,
1501 const typename type_identity<ALLOCATOR>::type& basicAllocator);
1502
1503#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1504 /// Create a vector and insert (in order) each `VALUE_TYPE` object in
1505 /// the specified `values` initializer list. Optionally specify a
1506 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
1507 /// specified, a default-constructed object of the (template parameter)
1508 /// type `ALLOCATOR` is used. If the type `ALLOCATOR` is
1509 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
1510 /// installed default allocator is used. This method requires that the
1511 /// (template parameter) type `VALUE_TYPE` be `copy-insertable` into this vector (see {Requirements on `VALUE_TYPE`}).
1512 ///
1513 /// \note Note that a
1514 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
1515 /// type `ALLOCATOR` is `bsl::allocator` (the default).
1516 vector(std::initializer_list<VALUE_TYPE> values,
1517 const ALLOCATOR& basicAllocator = ALLOCATOR());
1518 // IMPLICIT
1519#endif
1520
1521 /// Destroy this vector.
1523
1524 // MANIPULATORS
1525
1526 /// Assign to this object the value of the specified `rhs` object,
1527 /// propagate to this object the allocator of `rhs` if the `ALLOCATOR`
1528 /// type has trait @ref propagate_on_container_copy_assignment , and return
1529 /// a reference providing modifiable access to this object. If an
1530 /// exception is thrown, `*this` is left in a valid but unspecified
1531 /// state. This method requires that the (template parameter) type
1532 /// `VALUE_TYPE` be `copy-assignable` and `copy-insertable` into this
1533 /// vector (see {Requirements on `VALUE_TYPE`}).
1535
1536 /// Assign to this object the value of the specified `rhs` object,
1537 /// propagate to this object the allocator of `rhs` if the `ALLOCATOR`
1538 /// type has trait @ref propagate_on_container_move_assignment , and return
1539 /// a reference providing modifiable access to this object. The
1540 /// contents of `rhs` are moved (in constant time) to this vector if
1541 /// `get_allocator() == rhs.get_allocator()` (after accounting for the
1542 /// aforementioned trait); otherwise, all elements in this vector are
1543 /// either destroyed or move-assigned to and each additional element in
1544 /// `rhs` is move-inserted into this vector. `rhs` is left in a valid
1545 /// but unspecified state, and if an exception is thrown, `*this` is
1546 /// left in a valid but unspecified state. This method requires that
1547 /// the (template parameter) type `VALUE_TYPE` be `move-assignable` and
1548 /// `move-insertable` into this vector (see {Requirements on `VALUE_TYPE`}).
1549 ///
1550 /// \note Note that the `vector` template arguments must be
1551 /// explicitly spelled out to work around an MSVC 2022 bug, see DRQS
1552 /// 171087946.
1553 vector& operator=(
1554 BloombergLP::bslmf::MovableRef<vector<VALUE_TYPE, ALLOCATOR> > rhs)
1556 AllocatorTraits::propagate_on_container_move_assignment::value ||
1557 AllocatorTraits::is_always_equal::value);
1558
1559#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1560 /// Assign to this object the value resulting from first clearing this
1561 /// vector and then inserting (in order) each `VALUE_TYPE` object in the
1562 /// specified `values` initializer list, and return a reference
1563 /// providing modifiable access to this object. If an exception is
1564 /// thrown, `*this` is left in a valid but unspecified state. This
1565 /// method requires that the (template parameter) type `VALUE_TYPE` be
1566 /// `copy-insertable` into this vector (see {Requirements on
1567 /// `VALUE_TYPE`}).
1568 vector& operator=(std::initializer_list<VALUE_TYPE> values);
1569
1570 /// Assign to this object the value resulting from first clearing this
1571 /// vector and then inserting (in order) each `VALUE_TYPE` object in the
1572 /// specified `values` initializer list. If an exception is thrown,
1573 /// `*this` is left in a valid but unspecified state. This method
1574 /// requires that the (template parameter) type `VALUE_TYPE` be
1575 /// `copy-insertable` into this vector (see {Requirements on
1576 /// `VALUE_TYPE`}).
1577 void assign(std::initializer_list<VALUE_TYPE> values);
1578#endif
1579
1580 /// Assign to this object the value resulting from first clearing this
1581 /// vector and then inserting (in order) each `value_type` object in the
1582 /// range starting at the specified `first` element, and ending
1583 /// immediately before the specified `last` element. If an exception is
1584 /// thrown, `*this` is left in a valid but unspecified state. Throw
1585 /// `std::length_error` if `distance(first,last) > max_size()`. The
1586 /// (template parameter) type `INPUT_ITER` shall meet the requirements
1587 /// of an input iterator defined in the C++11 standard [24.2.3]
1588 /// providing access to values of a type convertible to `value_type`,
1589 /// and `value_type` must be `emplace-constructible` from `*i` into this
1590 /// vector, where `i` is a dereferenceable iterator in the range
1591 /// `[first .. last)` (see {Requirements on `VALUE_TYPE`}).
1592 ///
1593 /// \pre The behavior is undefined unless `first` and `last` refer to a range of
1594 /// valid values where `first` is at a position at or before `last`.
1595 template <class INPUT_ITER>
1596 void assign(INPUT_ITER first, INPUT_ITER last);
1597
1598 /// Assign to this object the value resulting from first clearing this
1599 /// vector and then inserting the specified `numElements` copies of the
1600 /// specified `value`. If an exception is thrown, `*this` is left in a
1601 /// valid but unspecified state. Throw `std::length_error` if
1602 /// `numElements > max_size()`. This method requires that the (template
1603 /// parameter) type `VALUE_TYPE` be `copy-insertable` into this vector
1604 /// (see {Requirements on `VALUE_TYPE`}).
1605 void assign(size_type numElements, const VALUE_TYPE& value);
1606
1607 /// Assign to this object the elements of the specified `range`.
1608 ///
1609 /// \note Note that `range` must meet the requirements of an input range and the values
1610 /// from `range` must have a type matching or convertible to (template
1611 /// parameter) `VALUE_TYPE`.
1612 template <class t_RANGE>
1614 void assign_range(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range);
1615
1616 // *** capacity ***
1617
1618 /// Change the size of this vector to the specified `newSize`. If
1619 /// `newSize < size()`, the elements in the range `[newSize .. size())`
1620 /// are erased, and this function does not throw. If
1621 /// `newSize > size()`, the (newly created) elements in the range
1622 /// `[size() .. newSize)` are default-constructed `value_type` objects,
1623 /// and if an exception is thrown (other than by the move constructor of
1624 /// a non-copy-insertable `value_type`), `*this` is unaffected. Throw
1625 /// `std::length_error` if `newSize > max_size()`. This method requires
1626 /// that the (template parameter) type `VALUE_TYPE` be
1627 /// `default-insertable` and `move-insertable` into this vector (see
1628 /// {Requirements on `VALUE_TYPE`}).
1629 void resize(size_type newSize);
1630
1631 /// Change the size of this vector to the specified `newSize`, inserting
1632 /// `newSize - size()` copies of the specified `value` at the end of
1633 /// this vector if `newSize > size()`. If `newSize < size()`, the
1634 /// elements in the range `[newSize .. size())` are erased, `value` is
1635 /// ignored, and this method does not throw. If `newSize > size()` and
1636 /// an exception is thrown, `*this` is unaffected. Throw
1637 /// `std::length_error` if `newSize > max_size()`. This method requires
1638 /// that the (template parameter) type `VALUE_TYPE` be `copy-insertable`
1639 /// into this vector (see {Requirements on `VALUE_TYPE`}).
1640 void resize(size_type newSize, const VALUE_TYPE& value);
1641
1642 /// Change the capacity of this vector to the specified `newCapacity`.
1643 /// If an exception is thrown (other than by the move constructor of a
1644 /// non-copy-insertable `value_type`), `*this` is unaffected. Throw
1645 /// `bsl::length_error` if `newCapacity > max_size()`. This method
1646 /// requires that the (template parameter) type `VALUE_TYPE` be
1647 /// `move-insertable` into this vector (see {Requirements on `VALUE_TYPE`}).
1648 ///
1649 /// \note Note that the capacity of this vector after this
1650 /// operation has completed may be greater than `newCapacity`.
1651 void reserve(size_type newCapacity);
1652
1653 /// Reduce the capacity of this vector to its size. If an exception is
1654 /// thrown (other than by the move constructor of a non-copy-insertable `value_type`), `*this` is unaffected.
1655 ///
1656 /// \note Note that this method has no
1657 /// effect if the capacity is equivalent to the size.
1658 void shrink_to_fit();
1659
1660 // *** modifiers ***
1661
1662 /// Append to the end of this object the elements of the specified `range`.
1663 ///
1664 /// \note Note that `range` must meet the requirements of an input range and the
1665 /// values from `range` must have a type matching or convertible to
1666 /// (template parameter) `VALUE_TYPE`.
1667 template <class t_RANGE>
1669 void append_range(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range);
1670
1671#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1672 /// Append to the end of this vector a newly created `value_type`
1673 /// object, constructed by forwarding `get_allocator()` (if required)
1674 /// and the specified (variable number of) `arguments` to the
1675 /// corresponding constructor of `value_type`. Return a reference
1676 /// providing modifiable access to the inserted element. If an
1677 /// exception is thrown (other than by the move constructor of a
1678 /// non-copy-insertable `value_type`), `*this` is unaffected. Throw
1679 /// `std::length_error` if `size() == max_size()`. This method requires
1680 /// that the (template parameter) type `VALUE_TYPE` be `move-insertable`
1681 /// into this vector and `emplace-constructible` from `arguments` (see
1682 /// {Requirements on `VALUE_TYPE`}).
1683 template <class... Args>
1684 VALUE_TYPE &emplace_back(Args&&... arguments);
1685#endif
1686
1687 /// Append to the end of this vector a copy of the specified `value`.
1688 /// If an exception is thrown, `*this` is unaffected. Throw
1689 /// `std::length_error` if `size() == max_size()`. This method
1690 /// requires that the (template parameter) type `VALUE_TYPE` be
1691 /// `copy-constructible` (see {Requirements on `VALUE_TYPE`}).
1692 void push_back(const VALUE_TYPE& value);
1693
1694 /// Append to the end of this vector the specified move-insertable
1695 /// `value`. `value` is left in a valid but unspecified state. If an
1696 /// exception is thrown (other than by the move constructor of a
1697 /// non-copy-insertable `value_type`), `*this` is unaffected. Throw
1698 /// `std::length_error` if `size() == max_size()`. This method requires
1699 /// that the (template parameter) type `VALUE_TYPE` be `move-insertable`
1700 /// into this vector (see {Requirements on `VALUE_TYPE`}).
1701 void push_back(BloombergLP::bslmf::MovableRef<VALUE_TYPE> value);
1702
1703 /// Erase the last element from this vector.
1704 ///
1705 /// \pre The behavior is undefined if this vector is empty.
1706 void pop_back();
1707
1708#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1709 /// Insert at the specified `position` in this vector a newly created
1710 /// `value_type` object, constructed by forwarding `get_allocator()` (if
1711 /// required) and the specified (variable number of) `arguments` to the
1712 /// corresponding constructor of `value_type`, and return an iterator
1713 /// referring to the newly created and inserted element. If an
1714 /// exception is thrown (other than by the copy constructor, move
1715 /// constructor, assignment operator, or move assignment operator of
1716 /// `value_type`), `*this` is unaffected. Throw `std::length_error` if `size() == max_size()`.
1717 ///
1718 /// \pre The behavior is undefined unless `position`
1719 /// is an iterator in the range `[begin() .. end()]` (both endpoints
1720 /// included). This method requires that the (template parameter) type
1721 /// `VALUE_TYPE` be `move-insertable` into this vector and
1722 /// `emplace-constructible` from `arguments` (see {Requirements on
1723 /// `VALUE_TYPE`}).
1724 ///
1725 /// NOTE: This function has been implemented inline due to an issue with
1726 /// the Sun compiler.
1727 template <class... Args>
1728 iterator emplace(const_iterator position, Args&&... arguments)
1729 {
1730 BSLS_ASSERT_SAFE(this->begin() <= position);
1731 BSLS_ASSERT_SAFE(position <= this->end());
1732
1733 const size_type index = position - this->begin();
1734
1735 const iterator& pos = const_cast<const iterator&>(position);
1736
1737 const size_type maxSize = max_size();
1739 maxSize - this->size())) {
1741 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
1742 "vector<...>::emplace(pos,arguments): vector too long");
1743 }
1744
1745 const size_type newSize = this->size() + 1;
1746 if (newSize > this->d_capacity) {
1748 newSize, this->d_capacity, maxSize);
1749 vector temp(this->get_allocator());
1750 temp.privateReserveEmpty(newCapacity);
1751
1752 ArrayPrimitives::destructiveMoveAndEmplace(
1753 temp.d_dataBegin_p,
1754 &this->d_dataEnd_p,
1755 this->d_dataBegin_p,
1756 pos,
1757 this->d_dataEnd_p,
1758 this->allocatorRef(),
1759 BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...);
1760
1761 temp.d_dataEnd_p += newSize;
1762 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
1763 }
1764 else {
1765 ArrayPrimitives::emplace(
1766 pos,
1767 this->end(),
1768 this->allocatorRef(),
1769 BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...);
1770 ++this->d_dataEnd_p;
1771 }
1772
1773 return this->begin() + index;
1774 }
1775#endif
1776
1777 /// Insert at the specified `position` in this vector a copy of the
1778 /// specified `value`, and return an iterator referring to the newly
1779 /// inserted element. If an exception is thrown (other than by the copy
1780 /// constructor, move constructor, assignment operator, or move
1781 /// assignment operator of `VALUE_TYPE`), `*this` is unaffected. Throw
1782 /// `std::length_error` if `size() == max_size()`.
1783 ///
1784 /// \pre The behavior is undefined unless `position` is an iterator in the range
1785 /// `[begin() .. end()]` (both endpoints included). This method
1786 /// requires that the (template parameter) type `VALUE_TYPE` be
1787 /// `copy-insertable` into this vector (see {Requirements on
1788 /// `VALUE_TYPE`}).
1789 iterator insert(const_iterator position, const VALUE_TYPE& value);
1790
1791 /// Insert at the specified `position` in this vector the specified
1792 /// move-insertable `value`, and return an iterator referring to the
1793 /// newly inserted element. `value` is left in a valid but unspecified
1794 /// state. If an exception is thrown (other than by the copy
1795 /// constructor, move constructor, assignment operator, or move
1796 /// assignment operator of `VALUE_TYPE`), `this` is unaffected. Throw
1797 /// `std::length_error` if `size() == max_size()`.
1798 ///
1799 /// \pre The behavior is undefined unless `position` is an iterator in the range
1800 /// `[begin() .. end()]` (both endpoints included). This method
1801 /// requires that the (template parameter) type `VALUE_TYPE` be
1802 /// `move-insertable` into this vector (see {Requirements on
1803 /// `VALUE_TYPE`}).
1805 BloombergLP::bslmf::MovableRef<VALUE_TYPE> value);
1806
1807 /// Insert at the specified `position` in this vector the specified
1808 /// `numElements` copies of the specified `value`, and return an
1809 /// iterator referring to the first newly inserted element. If an
1810 /// exception is thrown (other than by the copy constructor, move
1811 /// constructor, assignment operator, or move assignment operator of
1812 /// `VALUE_TYPE`), `*this` is unaffected. Throw `std::length_error` if
1813 /// `size() + numElements > max_size()`.
1814 ///
1815 /// \pre The behavior is undefined unless `position` is an iterator in the range `[begin() .. end()]`
1816 /// (both endpoints included). This method requires that the (template
1817 /// parameter) type `VALUE_TYPE` be `copy-insertable` into this vector
1818 /// (see {Requirements on `VALUE_TYPE`}).
1820 size_type numElements,
1821 const VALUE_TYPE& value);
1822
1823 /// Insert at the specified `position` in this vector the values in the
1824 /// range starting at the specified `first` element, and ending
1825 /// immediately before the specified `last` element. Return an iterator
1826 /// referring to the first newly inserted element. If an exception is
1827 /// thrown (other than by the copy constructor, move constructor,
1828 /// assignment operator, or move assignment operator of `value_type`),
1829 /// `*this` is unaffected. Throw `std::length_error` if
1830 /// `size() + distance(first, last) > max_size()`. The (template
1831 /// parameter) type `INPUT_ITER` shall meet the requirements of an input
1832 /// iterator defined in the C++11 standard [24.2.3] providing access to
1833 /// values of a type convertible to `value_type`, and `value_type` must
1834 /// be `emplace-constructible` from `*i` into this vector, where `i` is
1835 /// a dereferenceable iterator in the range `[first .. last)` (see {Requirements on `VALUE_TYPE`}).
1836 ///
1837 /// \pre The behavior is undefined unless
1838 /// `position` is an iterator in the range `[begin() .. end()]` (both
1839 /// endpoints included), and `first` and `last` refer to a range of
1840 /// valid values where `first` is at a position at or before `last`.
1841 ///
1842 /// NOTE: This function has been implemented inline due to an issue with
1843 /// the Sun compiler.
1844 template <class INPUT_ITER>
1845 iterator insert(const_iterator position, INPUT_ITER first, INPUT_ITER last)
1846 {
1847 BSLS_ASSERT_SAFE(this->begin() <= position);
1848 BSLS_ASSERT_SAFE(position <= this->end());
1849 BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last));
1850
1851 // If 'first' and 'last' are integral, then they are not iterators and
1852 // we should call 'insert(position, first, last)', where 'first' is
1853 // actually a misnamed count, and 'last' is a misnamed value. We can
1854 // assume that any fundamental type passed to this function is integral
1855 // or else compilation errors will result. The extra argument,
1856 // 'bslmf::Nil()', is to avoid an overloading ambiguity: In case
1857 // 'first' is an integral type, it would be convertible both to
1858 // 'bslmf::MatchArithmeticType' and 'bslmf::MatchAnyType'; but the
1859 // 'bslmf::Nil()' will be an exact match to 'bslmf::Nil', so the
1860 // overload with 'bslmf::MatchArithmeticType' will be preferred.
1861
1862 const size_type index = position - this->begin();
1863 privateInsertDispatch(
1864 position, first, last, first, BloombergLP::bslmf::Nil());
1865 return this->begin() + index;
1866 }
1867
1868#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1869 /// Insert at the specified `position` in this vector each `VALUE_TYPE`
1870 /// object in the specified `values` initializer list, and return an
1871 /// iterator referring to the first newly inserted element. If an
1872 /// exception is thrown (other than by the copy constructor, move
1873 /// constructor, assignment operator, and move assignment operator of
1874 /// `VALUE_TYPE`), `*this` is unaffected. Throw `std::length_error` if
1875 /// `size() + values.size() > max_size()`.
1876 ///
1877 /// \pre The behavior is undefined unless `position` is an iterator in the range `[begin() .. end()]`
1878 /// (both endpoints included). This method requires that the (template
1879 /// parameter) type `VALUE_TYPE` be `copy-insertable` into this vector
1880 /// (see {Requirements on `VALUE_TYPE`}).
1881 iterator insert(const_iterator position,
1882 std::initializer_list<VALUE_TYPE> values);
1883#endif
1884
1885 /// Insert at the specified `position` in this object the elements of the specified `range`.
1886 ///
1887 /// \note Note that `range` must meet the requirements of an
1888 /// input range and the values from `range` must have a type matching or
1889 /// convertible to (template parameter) `VALUE_TYPE`.
1890 template <class t_RANGE>
1892 iterator insert_range(const_iterator position,
1893 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range);
1894
1895 /// Remove from this vector the element at the specified `position`, and
1896 /// return an iterator providing modifiable access to the element
1897 /// immediately following the removed element, or the position returned
1898 /// by the method `end` if the removed element was the last in the sequence.
1899 ///
1900 /// \pre The behavior is undefined unless `position` is an
1901 /// iterator in the range `[cbegin() .. cend())`.
1903
1904 /// Remove from this vector the sequence of elements starting at the
1905 /// specified `first` position and ending before the specified `last`
1906 /// position, and return an iterator providing modifiable access to the
1907 /// element immediately following the last removed element, or the
1908 /// position returned by the method `end` if the removed elements were last in the sequence.
1909 ///
1910 /// \pre The behavior is undefined unless `first` is
1911 /// an iterator in the range `[cbegin() .. cend()]` (both endpoints
1912 /// included) and `last` is an iterator in the range
1913 /// `[first .. cend()]` (both endpoints included).
1915
1916 /// Exchange the value of this object with that of the specified `other`
1917 /// object; also exchange the allocator of this object with that of `other`
1918 /// if the (template parameter) type `ALLOCATOR` has the
1919 /// @ref propagate_on_container_swap trait, and do not modify either allocator
1920 /// otherwise. This method provides the no-throw exception-safety
1921 /// guarantee. This operation has `O[1]` complexity if either this object
1922 /// was created with the same allocator as `other` or `ALLOCATOR` has the
1923 /// @ref propagate_on_container_swap trait; otherwise, it has `O[n + m]`
1924 /// complexity, where `n` and `m` are the number of elements in this object and `other`, respectively.
1925 ///
1926 /// \note Note that this method`s support for
1927 /// swapping objects created with different allocators when `ALLOCATOR`
1928 /// does not have the @ref propagate_on_container_swap trait is a departure
1929 /// from the C++ Standard.
1931 AllocatorTraits::propagate_on_container_swap::value ||
1932 AllocatorTraits::is_always_equal::value);
1933
1934 /// Remove all elements from this vector making its size 0.
1935 ///
1936 /// \note Note that although this vector is empty after this method returns, it preserves
1937 /// the same capacity it had before the method was called.
1939
1940 // ACCESSORS
1941
1942 /// Return (a copy of) the allocator used for memory allocation by this
1943 /// vector.
1945
1946 /// Return a theoretical upper bound on the largest number of elements that this vector could possibly hold.
1947 ///
1948 /// \note Note that there is no guarantee that
1949 /// the vector can successfully grow to the returned size, or even close to
1950 /// that size without running out of resources. Also note that requests to
1951 /// create a vector longer than this number of elements are guaranteed to
1952 /// raise a `std::length_error` exception.
1954};
1955
1956// FREE OPERATORS
1957
1958 // *** relational operators ***
1959
1960/// Return `true` if the specified `lhs` and `rhs` objects have the same value,
1961/// and `false` otherwise. Two `vector` objects `lhs` and `rhs` have the same
1962/// value if they have the same number of elements, and each element in the
1963/// ordered sequence of elements of `lhs` has the same value as the
1964/// corresponding element in the ordered sequence of elements of `rhs`. This
1965/// method requires that the (template parameter) type `VALUE_TYPE` be
1966/// `equality-comparable` (see {Requirements on `VALUE_TYPE`}).
1967template <class VALUE_TYPE, class ALLOCATOR>
1968bool operator==(const vector<VALUE_TYPE, ALLOCATOR>& lhs,
1969 const vector<VALUE_TYPE, ALLOCATOR>& rhs);
1970
1971#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1972/// Return `true` if the specified `lhs` and `rhs` objects do not have the same
1973/// value, and `false` otherwise. Two `vector` objects `lhs` and `rhs` do not
1974/// have the same value if they do not have the same number of elements, or
1975/// some element in the ordered sequence of elements of `lhs` does not have the
1976/// same value as the corresponding element in the ordered sequence of elements
1977/// of `rhs`. This method requires that the (template parameter) type
1978/// `VALUE_TYPE` be `equality-comparable` (see {Requirements on `VALUE_TYPE`}).
1979template <class VALUE_TYPE, class ALLOCATOR>
1980bool operator!=(const vector<VALUE_TYPE, ALLOCATOR>& lhs,
1982#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1983
1984#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1985
1986/// Perform a lexicographic three-way comparison of the specified `lhs` and the
1987/// specified `rhs` vectors by using the comparison operators of `VALUE_TYPE`
1988/// on each element; return the result of that comparison.
1989template <class VALUE_TYPE, class ALLOCATOR>
1990BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE_TYPE> operator<=>(
1993
1994#else
1995
1996/// Return `true` if the value of the specified `lhs` vector is
1997/// lexicographically less than that of the specified `rhs` vector, and
1998/// `false` otherwise. Given iterators `i` and `j` over the respective
1999/// sequences `[lhs.begin() .. lhs.end())` and `[rhs.begin() .. rhs.end())`,
2000/// the value of vector `lhs` is lexicographically less than that of vector
2001/// `rhs` if `true == *i < *j` for the first pair of corresponding iterator
2002/// positions where `*i < *j` and `*j < *i` are not both `false`. If no
2003/// such corresponding iterator position exists, the value of `lhs` is
2004/// lexicographically less than that of `rhs` if `lhs.size() < rhs.size()`.
2005/// This method requires that `operator<`, inducing a total order, be
2006/// defined for `value_type`.
2007template <class VALUE_TYPE, class ALLOCATOR>
2008bool operator<(const vector<VALUE_TYPE, ALLOCATOR>& lhs,
2010
2011/// Return `true` if the value of the specified `lhs` vector is
2012/// lexicographically greater than that of the specified `rhs` vector, and
2013/// `false` otherwise. The value of vector `lhs` is lexicographically
2014/// greater than that of vector `rhs` if `rhs` is lexicographically less
2015/// than `lhs` (see `operator<`). This method requires that `operator<`, inducing a total order, be defined for `value_type`.
2016///
2017/// \note Note that this
2018/// operator returns `rhs < lhs`.
2019template <class VALUE_TYPE, class ALLOCATOR>
2020bool operator>(const vector<VALUE_TYPE, ALLOCATOR>& lhs,
2022
2023/// Return `true` if the value of the specified `lhs` vector is
2024/// lexicographically less than or equal to that of the specified `rhs`
2025/// vector, and `false` otherwise. The value of vector `lhs` is
2026/// lexicographically less than or equal to that of vector `rhs` if `rhs` is
2027/// not lexicographically less than `lhs` (see `operator<`). This method
2028/// requires that `operator<`, inducing a total order, be defined for `value_type`.
2029///
2030/// \note Note that this operator returns `!(rhs < lhs)`.
2031template <class VALUE_TYPE, class ALLOCATOR>
2032bool operator<=(const vector<VALUE_TYPE, ALLOCATOR>& lhs,
2034
2035/// Return `true` if the value of the specified `lhs` vector is
2036/// lexicographically greater than or equal to that of the specified `rhs`
2037/// vector, and `false` otherwise. The value of vector `lhs` is
2038/// lexicographically greater than or equal to that of vector `rhs` if `lhs`
2039/// is not lexicographically less than `rhs` (see `operator<`). This method
2040/// requires that `operator<`, inducing a total order, be defined for `value_type`.
2041///
2042/// \note Note that this operator returns `!(lhs < rhs)`.
2043template <class VALUE_TYPE, class ALLOCATOR>
2044bool operator>=(const vector<VALUE_TYPE, ALLOCATOR>& lhs,
2046
2047#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2048
2049// FREE FUNCTIONS
2050
2051/// Erase all the elements in the specified vector `vec` that compare equal
2052/// to the specified `value`. Return the number of elements erased.
2053template <class VALUE_TYPE, class ALLOCATOR, class BDE_OTHER_TYPE>
2055erase(vector<VALUE_TYPE, ALLOCATOR>& vec, const BDE_OTHER_TYPE& value);
2056
2057/// Erase all the elements in the specified vector `vec` that satisfy the
2058/// specified predicate `predicate`. Return the number of elements erased.
2059template <class VALUE_TYPE, class ALLOCATOR, class PREDICATE>
2061erase_if(vector<VALUE_TYPE, ALLOCATOR>& vec, PREDICATE predicate);
2062
2063/// Exchange the value of the specified `a` object with that of the
2064/// specified `b` object; also exchange the allocator of `a` with that of
2065/// `b` if the (template parameter) type `ALLOCATOR` has the
2066/// @ref propagate_on_container_swap trait, and do not modify either allocator
2067/// otherwise. This function provides the no-throw exception-safety
2068/// guarantee. This operation has `O[1]` complexity if either `a` was
2069/// created with the same allocator as `b` or `ALLOCATOR` has the
2070/// @ref propagate_on_container_swap trait; otherwise, it has `O[n + m]`
2071/// complexity, where `n` and `m` are the number of elements in `a` and `b`, respectively.
2072///
2073/// \note Note that this function`s support for swapping objects
2074/// created with different allocators when `ALLOCATOR` does not have the
2075/// @ref propagate_on_container_swap trait is a departure from the C++
2076/// Standard.
2077template <class VALUE_TYPE, class ALLOCATOR>
2081 a.swap(b)));
2082
2083
2084 // =====================================
2085 // class vector<VALUE_TYPE *, ALLOCATOR>
2086 // =====================================
2087
2088/// This partial specialization of `vector` for pointer types to a (template
2089/// parameter) `VALUE_TYPE` type is implemented in terms of
2090/// `vector<UintPtr>` to reduce the amount of code generated.
2091///
2092/// \note Note that this specialization rebinds the (template parameter) `ALLOCATOR` type to
2093/// an allocator of `UintPtr` so as to satisfy the invariant in the `vector` base class.
2094///
2095/// \note Note that the contract for all members is the same as the
2096/// primary template, so documentation is not repeated to avoid accidentally
2097/// introducing inconsistency over time.
2098template <class VALUE_TYPE, class ALLOCATOR>
2099class vector<VALUE_TYPE *, ALLOCATOR>
2100{
2101
2102 // PRIVATE TYPES
2103 typedef BloombergLP::bsls::Types::UintPtr UintPtr;
2104#if defined(BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES)
2105 typedef typename allocator_traits<ALLOCATOR>::
2106 template rebind_alloc<UintPtr> ImplAlloc;
2107#else
2108 typedef typename ALLOCATOR::template rebind<UintPtr>::other ImplAlloc;
2109#endif
2111 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
2112
2113 // PRIVATE DATA
2114 Impl d_impl; // The 'UintPtr' vector used for the implementation.
2115
2116 public:
2117 // PUBLIC TYPES
2118 typedef VALUE_TYPE *value_type;
2121 typedef VALUE_TYPE **iterator;
2122 typedef VALUE_TYPE *const *const_iterator;
2123 typedef std::size_t size_type;
2124 typedef std::ptrdiff_t difference_type;
2125 typedef ALLOCATOR allocator_type;
2130 typedef bsl::reverse_iterator<iterator> reverse_iterator;
2131 typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;
2132
2133 // *** construct/copy/destroy ***
2134
2135 // CREATORS
2137
2138 explicit vector(const ALLOCATOR& basicAllocator) BSLS_KEYWORD_NOEXCEPT;
2139
2140 explicit vector(size_type initialSize,
2141 const ALLOCATOR& basicAllocator = ALLOCATOR());
2142
2143 vector(size_type initialSize,
2144 VALUE_TYPE *value,
2145 const ALLOCATOR& basicAllocator = ALLOCATOR());
2146
2147 template <class INPUT_ITER>
2148 vector(INPUT_ITER first,
2149 INPUT_ITER last,
2150 const ALLOCATOR& basicAllocator = ALLOCATOR());
2151
2152 template <class t_RANGE>
2155 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
2156 const ALLOCATOR& basicAllocator =
2157 ALLOCATOR());
2158
2159 vector(const vector& original);
2160
2161 vector(BloombergLP::bslmf::MovableRef<vector> original)
2162 BSLS_KEYWORD_NOEXCEPT; // IMPLICIT
2163
2164 vector(const vector& original,
2165 const typename type_identity<ALLOCATOR>::type& basicAllocator);
2166
2167 vector(BloombergLP::bslmf::MovableRef<vector> original,
2168 const typename type_identity<ALLOCATOR>::type& basicAllocator);
2169
2170
2171#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2172 vector(std::initializer_list<VALUE_TYPE *> values,
2173 const ALLOCATOR& basicAllocator = ALLOCATOR());
2174#endif
2175
2176 ~vector();
2177
2178 // MANIPULATORS
2179 vector& operator=(const vector& rhs);
2180
2181 /// NOTE: This function has been implemented inline due to an issue with
2182 /// the Sun compiler.
2184 BloombergLP::bslmf::MovableRef<vector<VALUE_TYPE *, ALLOCATOR> > rhs)
2186 d_impl = MoveUtil::move(MoveUtil::access(rhs).d_impl)))
2187 {
2188 d_impl = MoveUtil::move(MoveUtil::access(rhs).d_impl);
2189 return *this;
2190 }
2191
2192#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2193 vector& operator=(std::initializer_list<VALUE_TYPE *> values);
2194
2195 void assign(std::initializer_list<VALUE_TYPE *> values);
2196
2197#endif
2198
2199 template <class INPUT_ITER>
2200 void assign(INPUT_ITER first, INPUT_ITER last);
2201 void assign(size_type numElements, VALUE_TYPE *value);
2202
2203 template <class t_RANGE>
2205 void assign_range(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range);
2206
2207
2208 // *** iterators ***
2209
2212
2215
2216 // *** element access ***
2217
2218 reference operator[](size_type position);
2219 reference at(size_type position);
2220
2221 reference front();
2222 reference back();
2223
2224 VALUE_TYPE **data() BSLS_KEYWORD_NOEXCEPT;
2225
2226 // *** capacity ***
2227
2228 void resize(size_type newLength);
2229 void resize(size_type newLength, VALUE_TYPE *value);
2230
2231 void reserve(size_type newCapacity);
2232 void shrink_to_fit();
2233
2234 // *** modifiers ***
2235
2236 template <class t_RANGE>
2238 void append_range(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range);
2239
2240 value_type &emplace_back();
2241
2242# if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2243 template <class ARG>
2244 value_type &emplace_back(ARG&& arg);
2245# else
2246 value_type &emplace_back(VALUE_TYPE *ptr);
2247# endif
2248
2249 void push_back(VALUE_TYPE *value);
2250
2251 void pop_back();
2252
2253 iterator emplace(const_iterator position);
2254
2255# if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2256 template <class ARG>
2257 iterator emplace(const_iterator position, ARG&& arg);
2258# else
2259 iterator emplace(const_iterator position, VALUE_TYPE *ptr);
2260# endif
2261
2262 iterator insert(const_iterator position, VALUE_TYPE *value);
2263 iterator insert(const_iterator position,
2264 size_type numElements,
2265 VALUE_TYPE *value);
2266
2267 template <class INPUT_ITER>
2269 INPUT_ITER first,
2270 INPUT_ITER last)
2271 {
2272 // NOTE: This function has been implemented inline due to an issue with
2273 // the Sun compiler.
2274
2275 typedef typename vector_ForwardIteratorForPtrs<VALUE_TYPE,
2276 INPUT_ITER>::type Iter;
2277
2278 return (iterator)d_impl.insert(
2279 (const UintPtr *)position, Iter(first), Iter(last));
2280 }
2281
2282#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2283 iterator insert(const_iterator position,
2284 std::initializer_list<VALUE_TYPE *> values);
2285#endif
2286
2287 template <class t_RANGE>
2289 iterator insert_range(const_iterator position,
2290 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range);
2291
2292 iterator erase(const_iterator position);
2294
2295 void swap(vector<VALUE_TYPE *, ALLOCATOR>& other)
2297 d_impl.swap(other.d_impl)));
2298
2299 void clear() BSLS_KEYWORD_NOEXCEPT;
2300
2301 // ACCESSORS
2302 allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT;
2303
2304 size_type max_size() const BSLS_KEYWORD_NOEXCEPT;
2305
2306 // *** iterators ***
2307
2312
2317
2318 // *** capacity ***
2319
2322 bool empty() const BSLS_KEYWORD_NOEXCEPT;
2323
2324 // *** element access ***
2325
2326 const_reference operator[](size_type position) const;
2327
2328 const_reference at(size_type position) const;
2329
2330 const_reference front() const;
2331 const_reference back() const;
2332
2333 VALUE_TYPE *const *data() const BSLS_KEYWORD_NOEXCEPT;
2334
2335 // FRIENDS
2336 friend
2337 bool operator==(const vector& lhs, const vector& rhs)
2338 {
2339 return lhs.d_impl == rhs.d_impl;
2340 }
2341
2342#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2343
2344 friend BloombergLP::bslalg::SynthThreeWayUtil::Result<Impl>
2345 operator<=>(const vector& lhs, const vector& rhs)
2346 {
2347 return BloombergLP::bslalg::SynthThreeWayUtil::compare(lhs.d_impl,
2348 rhs.d_impl);
2349 }
2350
2351#else
2352
2353 friend
2354 bool operator!=(const vector& lhs, const vector& rhs)
2355 {
2356 return lhs.d_impl != rhs.d_impl;
2357 }
2358
2359 friend
2360 bool operator<(const vector& lhs, const vector& rhs)
2361 {
2362 return lhs.d_impl < rhs.d_impl;
2363 }
2364
2365 friend
2366 bool operator>(const vector& lhs, const vector& rhs)
2367 {
2368 return lhs.d_impl > rhs.d_impl;
2369 }
2370
2371 friend
2372 bool operator<=(const vector& lhs, const vector& rhs)
2373 {
2374 return lhs.d_impl <= rhs.d_impl;
2375 }
2376
2377 friend
2378 bool operator>=(const vector& lhs, const vector& rhs)
2379 {
2380 return lhs.d_impl >= rhs.d_impl;
2381 }
2382
2383#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2384
2385 friend
2386 void swap(vector& a, vector& b)
2388 a.d_impl.swap(b.d_impl)))
2389 {
2390 a.d_impl.swap(b.d_impl);
2391 }
2392};
2393
2394#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
2395// CLASS TEMPLATE DEDUCTION GUIDES
2396
2397/// Deduce the template parameter `VALUE` from the corresponding parameter
2398/// supplied to the constructor of `vector`. This deduction guide does not
2399/// participate unless the supplied allocator is convertible to
2400/// `bsl::allocator<VALUE>`.
2401template <
2402 class SIZE_TYPE,
2403 class VALUE,
2404 class ALLOC,
2405 class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
2406 class = bsl::enable_if_t<
2407 bsl::is_convertible_v<
2408 SIZE_TYPE,
2410 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
2411 >
2412vector(SIZE_TYPE, VALUE, ALLOC *) -> vector<VALUE>;
2413
2414/// Deduce the template parameter `VALUE` from the `value_type` of the
2415/// iterators supplied to the constructor of `vector`.
2416template <
2417 class INPUT_ITERATOR,
2418 class VALUE =
2419 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>
2420 >
2421vector(INPUT_ITERATOR, INPUT_ITERATOR) -> vector<VALUE>;
2422
2423/// Deduce the template parameter `VALUE` from the `value_type` of the
2424/// iterators supplied to the constructor of `vector`. This deduction
2425/// guide does not participate unless the supplied allocator meets the
2426/// requirements of a standard allocator.
2427template<
2428 class INPUT_ITERATOR,
2429 class ALLOCATOR,
2430 class VALUE =
2431 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
2432 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
2433 >
2434vector(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR) -> vector<VALUE, ALLOCATOR>;
2435
2436/// Deduce the template parameter `VALUE` from the `value_type` of the
2437/// iterators supplied to the constructor of `vector`. This deduction
2438/// guide does not participate unless the supplied allocator is convertible
2439/// to `bsl::allocator<VALUE>`.
2440template<
2441 class INPUT_ITERATOR,
2442 class ALLOC,
2443 class VALUE =
2444 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
2445 class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
2446 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
2447 >
2448vector(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
2449-> vector<VALUE>;
2450
2451/// Deduce the template parameter `VALUE` from the `value_type` of the
2452/// initializer_list supplied to the constructor of `vector`. This
2453/// deduction guide does not participate unless the supplied allocator is
2454/// convertible to `bsl::allocator<VALUE>`.
2455template<
2456 class VALUE,
2457 class ALLOC,
2458 class DEFAULT_ALLOCATOR = bsl::allocator<VALUE>,
2459 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
2460 >
2461vector(std::initializer_list<VALUE>, ALLOC *)
2462-> vector<VALUE>;
2463
2464#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
2465/// Deduce the template parameters `VALUE_TYPE` and `ALLOCATOR` from the
2466/// parameters supplied to the constructor of `vector`.
2467template <ranges::input_range t_RANGE,
2468 class t_ALLOCATOR =
2469 allocator<ranges::range_value_t<t_RANGE>>>
2470vector(from_range_t, t_RANGE&&, t_ALLOCATOR = t_ALLOCATOR())
2471-> vector<ranges::range_value_t<t_RANGE>, t_ALLOCATOR>;
2472#endif
2473#endif
2474
2475
2476// ============================================================================
2477// TEMPLATE AND INLINE FUNCTION DEFINITIONS
2478// ============================================================================
2479// See IMPLEMENTATION NOTES in the .cpp before modifying anything below.
2480
2481 // ======================================
2482 // class vector_UintPtrConversionIterator
2483 // ======================================
2484
2485/// This class provides a minimal proxy iterator adapter, transforming pointers
2486/// to `uintptr_t` values on the fly, for only the operations needed to
2487/// implement the member functions and constructors of the `vector` partial
2488/// template specialization that take iterator ranges as arguments. While it
2489/// does not provide a standard conforming iterator itself, if provides exactly
2490/// sufficient behavior to implement all the needed members. `VALUE_TYPE`
2491/// shall be a pointer type, and `ITERATOR` shall be a standard conforming
2492/// iterator that dereferences to a type implicitly convertible to `VALUE_TYPE`
2493///
2494/// See @ref bslstl_vector
2495template <class VALUE_TYPE, class ITERATOR>
2497
2498 private:
2499 // DATA
2500 ITERATOR d_iter;
2501
2502 public:
2503 // PUBLIC TYPES
2504 typedef BloombergLP::bsls::Types::UintPtr UintPtr;
2505
2509 typedef typename iterator_traits<ITERATOR>::difference_type
2511 typedef typename iterator_traits<ITERATOR>::iterator_category
2513
2514 // CREATORS
2515
2516 /// Create an uninitialized proxy iterator.
2518
2519 /// Create a proxy iterator adapting the specified `it`.
2520 vector_UintPtrConversionIterator(ITERATOR it); // IMPLICIT
2521
2522 // MANIPULATORS
2523
2524 /// Increment this iterator to refer to the next element in the underlying
2525 /// sequence, and return a reference to this object.
2527
2528 /// Return this object, and increment this iterator to refer to the next
2529 /// element in the underlying sequence.
2530 vector_UintPtrConversionIterator operator++(int);
2531
2532 // ACCESSORS
2533
2534 /// Return the value of the pointer this iterator refers to, converted to
2535 /// an unsigned integer.
2536 UintPtr operator*() const;
2537
2538#ifdef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2539
2540 /// Perform a three-way comparison with the specified `other` object and
2541 /// return the result of that comparison. Where the underlying (wrapped)
2542 /// iterator of type `ITERATOR` supports 3 way comparison, the default
2543 /// spaceship operator will defer to `ITERATOR::operator<=>` and have
2544 /// the same return type as `ITERATOR::operator<=>`; otherwise, this
2545 /// operator will be deleted.
2546 auto
2547 operator<=>(const vector_UintPtrConversionIterator& other) const = default;
2548
2549#else
2550
2551 // FRIENDS
2552
2553 /// Return `true` if the specified `lhs` and `rhs` iterators do not
2554 /// refer to the same element in the same underlying sequence and no
2555 /// more than one refers to the past-the-end element of the sequence, and `false` otherwise.
2556 ///
2557 /// \pre The behavior is undefined if `lhs` and `rhs`
2558 /// do not iterate over the same sequence.
2559 friend
2562 {
2563 return lhs.d_iter != rhs.d_iter;
2564 }
2565
2566#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2567
2568 // FRIENDS
2569
2570 /// Return `true` if the specified `lhs` and `rhs` iterators refer to
2571 /// the same element in the same underlying sequence or both refer to
2572 /// the past-the-end element of the same sequence, and `false` otherwise.
2573 ///
2574 /// \pre The behavior is undefined if `lhs` and `rhs` do not
2575 /// iterate over the same sequence.
2576 friend
2579 {
2580 return lhs.d_iter == rhs.d_iter;
2581 }
2582
2583 /// Return `true` if the specified `lhs` iterator is earlier in the
2584 /// underlying sequence than the specified `rhs` iterator, and `false` otherwise.
2585 ///
2586 /// \pre The behavior is undefined if `lhs` and `rhs` do not
2587 /// iterate over the same sequence, or if the (template parameter) type
2588 /// `ITERATOR` is not a random access iterator.
2589 friend
2592 {
2593 return lhs.d_iter < rhs.d_iter;
2594 }
2595
2596#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
2597 bool operator==(bsl::sentinel_for<ITERATOR> auto rhs) const
2598 {
2599 return d_iter == rhs;
2600 }
2601 friend auto operator-(bsl::sentinel_for<ITERATOR> auto s,
2602 vector_UintPtrConversionIterator i)
2603 requires random_access_iterator<ITERATOR>
2604 {
2605 return s - i.d_iter;
2606 }
2607#endif
2608
2609 /// Return the distance between the specified `lhs` iterator and the specified `rhs` iterator.
2610 ///
2611 /// \pre The behavior is undefined if `lhs` and
2612 /// `rhs` do not iterate over the same sequence, or if the (template
2613 /// parameter) type `ITERATOR` is not a random access iterator.
2614 friend
2617#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2618 requires requires { lhs.d_iter - rhs.d_iter; }
2619#endif
2620 {
2621 return lhs.d_iter - rhs.d_iter;
2622 }
2623};
2624
2625 // --------------------------------------
2626 // class vector_UintPtrConversionIterator
2627 // --------------------------------------
2628
2629// CREATORS
2630template <class VALUE_TYPE, class ITERATOR>
2631inline
2636
2637template <class VALUE_TYPE, class ITERATOR>
2638inline
2644
2645// MANIPULATORS
2646template <class VALUE_TYPE, class ITERATOR>
2647inline
2650{
2651 ++d_iter;
2652 return *this;
2653}
2654
2655template <class VALUE_TYPE, class ITERATOR>
2656inline
2664
2665// ACCESSORS
2666template <class VALUE_TYPE, class ITERATOR>
2667inline
2668BloombergLP::bsls::Types::UintPtr
2670{
2671 VALUE_TYPE const ptr = *d_iter;
2672 return reinterpret_cast<UintPtr>(ptr);
2673}
2674
2675 // =================================
2676 // struct vector_UintPtrRangeAdapter
2677 // =================================
2678
2679/// This class provides a minimal proxy range adapter, transforming pointers
2680/// to `uintptr_t` values on the fly, for only the operations needed to
2681/// implement the member functions and constructors of the `vector` partial
2682/// template specialization that take iterator ranges as arguments. While it
2683/// does not provide a standard conforming iterator itself, if provides exactly
2684/// sufficient behavior to implement all the needed members. `t_VALUE_TYPE`
2685/// shall be a pointer type, and `[d_begin, d_end)` is a range of the input
2686/// values.
2687///
2688/// See @ref bslstl_vector
2689template <class t_VALUE_TYPE, class t_ITERATOR, class t_SENTINEL>
2691 // TYPES
2694
2695 // PUBLIC DATA
2696 t_ITERATOR d_begin;
2697 t_SENTINEL d_end;
2698
2699 // ACCESSORS
2700 iterator begin() const { return iterator(d_begin); }
2701 t_SENTINEL end() const { return d_end; }
2702};
2703
2704/// Factory function for `vector_UintPtrRangeAdapter`.
2705template <class t_VALUE_TYPE, class t_ITERATOR, class t_SENTINEL>
2706inline
2707vector_UintPtrRangeAdapter<t_VALUE_TYPE, t_ITERATOR, t_SENTINEL>
2708vector_makeUintPtrRangeAdapter(t_ITERATOR begin, t_SENTINEL end)
2709{
2711 {begin, end};
2712 return range;
2713}
2714
2715 // ========================
2716 // class Vector_PushProctor
2717 // ========================
2718
2719/// This class template provides a proctor for a newly created object that
2720/// is managed by an allocator. The object will be constructed through a
2721/// call to `allocator_traits<ALLOCATOR>::construct`, and it should be
2722/// destroyed by a call to `allocator_traits<ALLOCATOR>::destroy`.
2723///
2724/// \note Note that this proctor takes no responsibility for the allocated memory that
2725/// the supplied value is constructed in.
2726///
2727/// See @ref bslstl_vector
2728template <class VALUE_TYPE, class ALLOCATOR>
2730
2731 // DATA
2732 VALUE_TYPE *d_target_p; // managed object
2733 ALLOCATOR d_allocator; // allocator to be used to destroy managed object
2734
2735 private:
2736 // NOT IMPLEMENTED
2737 Vector_PushProctor(const Vector_PushProctor&); // = delete;
2738 Vector_PushProctor& operator=(const Vector_PushProctor&); // = delete;
2739
2740 public:
2741 // CREATORS
2742
2743 /// Create a proctor that conditionally manages the specified `target`
2744 /// object (if non-zero) by destroying the managed object with a call to
2745 /// `allocator_traits<ALLOCATOR>::destroy` using the specified
2746 /// `allocator` upon destruction of this proctor, unless the managed
2747 /// objects has been released.
2748 Vector_PushProctor(VALUE_TYPE *target, const ALLOCATOR& allocator);
2749
2750 /// Destroy this proctor, and destroy the object it manages (if any) by
2751 /// a call to `allocator_traits<ALLOCATOR>::destroy` using the allocator
2752 /// supplied at construction. If no object is currently being managed,
2753 /// this method has no effect.
2755
2756 // MANIPULATORS
2757
2758 /// Release from management the object currently managed by this proctor.
2759 /// If no object is currently being managed, this method has no effect.
2760 void release();
2761};
2762
2763 // ------------------------
2764 // class Vector_PushProctor
2765 // ------------------------
2766
2767// CREATORS
2768template <class VALUE_TYPE, class ALLOCATOR>
2769inline
2771 VALUE_TYPE *target,
2772 const ALLOCATOR& allocator)
2773: d_target_p(target)
2774, d_allocator(allocator)
2775{
2776}
2777
2778template <class VALUE_TYPE, class ALLOCATOR>
2779inline
2781{
2782 if (d_target_p) {
2783 bsl::allocator_traits<ALLOCATOR>::destroy(d_allocator, d_target_p);
2784 }
2785}
2786
2787// MANIPULATORS
2788template <class VALUE_TYPE, class ALLOCATOR>
2789inline
2791{
2792 d_target_p = 0;
2793}
2794
2795#if defined(BSLS_ASSERT_SAFE_IS_USED)
2796 // -----------------------
2797 // class Vector_RangeCheck
2798 // -----------------------
2799
2800template <class BSLSTL_ITERATOR, class SENTINEL>
2801inline
2803 bool>::type
2804Vector_RangeCheck::isInvalidRange(BSLSTL_ITERATOR, SENTINEL)
2805{
2806 return false;
2807}
2808
2809template <class BSLSTL_ITERATOR>
2810inline
2811typename enable_if<Vector_IsRandomAccessIterator<BSLSTL_ITERATOR>::value,
2812 bool>::type
2813Vector_RangeCheck::isInvalidRange(BSLSTL_ITERATOR first, BSLSTL_ITERATOR last)
2814{
2815 return last < first;
2816}
2817
2818template <class BSLSTL_ITERATOR, class SENTINEL>
2819inline
2820typename enable_if<Vector_IsRandomAccessIterator<BSLSTL_ITERATOR>::value,
2821 bool>::type
2822Vector_RangeCheck::isInvalidRange(BSLSTL_ITERATOR first, SENTINEL last)
2823{
2824 return last - first < 0;
2825}
2826#endif
2827
2828 // ----------------
2829 // class vectorBase
2830 // ----------------
2831
2832// CREATORS
2833template <class VALUE_TYPE>
2834inline
2836: d_dataBegin_p(0)
2837, d_dataEnd_p(0)
2838, d_capacity(0)
2839{
2840}
2841
2842// MANIPULATORS
2843
2844template <class VALUE_TYPE>
2845inline
2846void
2847vectorBase<VALUE_TYPE>::adopt(BloombergLP::bslmf::MovableRef<vectorBase> base)
2848{
2849 BSLS_ASSERT_SAFE(0 == d_dataBegin_p);
2850 BSLS_ASSERT_SAFE(0 == d_dataEnd_p);
2851 BSLS_ASSERT_SAFE(0 == d_capacity);
2852
2853 vectorBase& lvalue = base;
2854 d_dataBegin_p = lvalue.d_dataBegin_p;
2855 d_dataEnd_p = lvalue.d_dataEnd_p;
2856 d_capacity = lvalue.d_capacity;
2857
2858 lvalue.d_dataBegin_p = 0;
2859 lvalue.d_dataEnd_p = 0;
2860 lvalue.d_capacity = 0;
2861}
2862 // *** iterators ***
2863template <class VALUE_TYPE>
2864inline
2867{
2868 return d_dataBegin_p;
2869}
2870
2871template <class VALUE_TYPE>
2872inline
2875{
2876 return d_dataEnd_p;
2877}
2878
2879template <class VALUE_TYPE>
2880inline
2886
2887template <class VALUE_TYPE>
2888inline
2894
2895 // *** element access ***
2896
2897template <class VALUE_TYPE>
2898inline
2901{
2902 BSLS_ASSERT_SAFE(size() > position);
2903
2904 return d_dataBegin_p[position];
2905}
2906
2907template <class VALUE_TYPE>
2910{
2911 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(position >= size())) {
2913 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
2914 "vector<...>::at(position): invalid position");
2915 }
2916 return d_dataBegin_p[position];
2917}
2918
2919template <class VALUE_TYPE>
2920inline
2923{
2925
2926 return *d_dataBegin_p;
2927}
2928
2929template <class VALUE_TYPE>
2930inline
2933{
2935
2936 return *(d_dataEnd_p - 1);
2937}
2938
2939template <class VALUE_TYPE>
2940inline
2941VALUE_TYPE *
2943{
2944 return d_dataBegin_p;
2945}
2946
2947// ACCESSORS
2948
2949 // *** iterators ***
2950template <class VALUE_TYPE>
2951inline
2954{
2955 return d_dataBegin_p;
2956}
2957
2958template <class VALUE_TYPE>
2959inline
2962{
2963 return d_dataBegin_p;
2964}
2965
2966template <class VALUE_TYPE>
2967inline
2970{
2971 return d_dataEnd_p;
2972}
2973
2974template <class VALUE_TYPE>
2975inline
2978{
2979 return d_dataEnd_p;
2980}
2981
2982template <class VALUE_TYPE>
2983inline
2989
2990template <class VALUE_TYPE>
2991inline
2997
2998template <class VALUE_TYPE>
2999inline
3005
3006template <class VALUE_TYPE>
3007inline
3013
3014 // *** capacity ***
3015
3016template <class VALUE_TYPE>
3017inline
3020{
3021 return d_dataEnd_p - d_dataBegin_p;
3022}
3023
3024template <class VALUE_TYPE>
3025inline
3028{
3029 return d_capacity;
3030}
3031
3032template <class VALUE_TYPE>
3033inline
3035{
3036 return d_dataEnd_p == d_dataBegin_p;
3037}
3038
3039 // *** element access ***
3040template <class VALUE_TYPE>
3041inline
3044{
3045 BSLS_ASSERT_SAFE(size() > position);
3046
3047 return d_dataBegin_p[position];
3048}
3049
3050template <class VALUE_TYPE>
3053{
3054 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(position >= size())) {
3056 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
3057 "const vector<...>::at(position): invalid position");
3058 }
3059 return d_dataBegin_p[position];
3060}
3061
3062template <class VALUE_TYPE>
3063inline
3066{
3068
3069 return *d_dataBegin_p;
3070}
3071
3072template <class VALUE_TYPE>
3073inline
3076{
3078
3079 return *(d_dataEnd_p - 1);
3080}
3081
3082template <class VALUE_TYPE>
3083inline
3084const VALUE_TYPE *
3086{
3087 return d_dataBegin_p;
3088}
3089
3090 // --------------------------------------------
3091 // class vector<VALUE_TYPE, ALLOCATOR>::Proctor
3092 // --------------------------------------------
3093
3094// CREATORS
3095template <class VALUE_TYPE, class ALLOCATOR>
3098 std::size_t capacity,
3099 ContainerBase *container)
3100: d_data_p(data)
3101, d_capacity(capacity)
3102, d_container_p(container)
3103{
3104}
3105
3106template <class VALUE_TYPE, class ALLOCATOR>
3108vector<VALUE_TYPE, ALLOCATOR>::Proctor::~Proctor()
3109{
3110 using BloombergLP::bslma::AllocatorUtil;
3111
3112 if (d_data_p) {
3113 AllocatorUtil::deallocateObject(d_container_p->allocatorRef(),
3114 d_data_p, d_capacity);
3115 }
3116}
3117
3118// MANIPULATORS
3119template <class VALUE_TYPE, class ALLOCATOR>
3121void vector<VALUE_TYPE, ALLOCATOR>::Proctor::release()
3122{
3123 d_data_p = 0;
3124}
3125
3126 // ------------
3127 // class vector
3128 // ------------
3129
3130// PRIVATE MANIPULATORS
3131template <class VALUE_TYPE, class ALLOCATOR>
3132template <class t_RANGE, class t_ITERATOR>
3133inline
3134void vector<VALUE_TYPE, ALLOCATOR>::privateConstruct(
3135 from_range_t ,
3136 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
3137 t_ITERATOR begin)
3138{
3139 BSLS_ASSERT_SAFE(begin == ranges::begin(range));
3140 BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(begin,
3141 ranges::end(range)));
3142
3144
3145 privateConstruct(from_range,
3146 BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range),
3147 begin,
3148 Tag());
3149}
3150
3151template <class VALUE_TYPE, class ALLOCATOR>
3152template <class t_RANGE, class t_ITERATOR>
3153inline
3154void vector<VALUE_TYPE, ALLOCATOR>::privateConstruct(
3155 from_range_t ,
3156 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
3157 t_ITERATOR begin,
3158 std::forward_iterator_tag)
3159{
3160#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
3161 if constexpr (ranges::sized_range<t_RANGE>) {
3162 constructFromSizedRange(begin,
3163 ranges::end(range),
3164 ranges::size(range));
3165 }
3166 else //
3167#endif
3168 constructFromSizedRange(
3169 begin,
3170 ranges::end(range),
3171 BloombergLP::bslstl::IteratorUtil::insertDistance(begin,
3172 ranges::end(range)));
3173}
3174
3175template <class VALUE_TYPE, class ALLOCATOR>
3176template <class t_RANGE, class t_ITERATOR>
3177inline
3178void vector<VALUE_TYPE, ALLOCATOR>::privateConstruct(
3179 from_range_t ,
3180 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
3181 t_ITERATOR begin,
3182 std::input_iterator_tag)
3183{
3184#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
3185 if constexpr (ranges::sized_range<t_RANGE>) {
3186 constructFromSizedRange(begin,
3187 ranges::end(range),
3188 ranges::size(range));
3189 }
3190 else // ...
3191#endif
3192 if (begin != ranges::end(range)) {
3193 constructFromRange(begin,
3194 ranges::end(range),
3195 std::input_iterator_tag());
3196 }
3197}
3198
3199template <class VALUE_TYPE, class ALLOCATOR>
3200template <class FWD_ITER, class SENTINEL>
3201inline
3202void vector<VALUE_TYPE, ALLOCATOR>::constructFromRange(
3203 FWD_ITER first,
3204 SENTINEL last,
3205 std::forward_iterator_tag)
3206{
3207 // Specialization for all iterators except input iterators: 'size' can be
3208 // computed in advance.
3209 BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last));
3210 BSLS_ASSERT_OPT((BloombergLP::bslstl::IteratorUtil
3211 ::canCalculateInsertDistance<FWD_ITER, FWD_ITER>()));
3212
3213 constructFromSizedRange(
3214 first,
3215 last,
3216 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
3217}
3218
3219template <class VALUE_TYPE, class ALLOCATOR>
3220template <class INPUT_ITER, class SENTINEL>
3221void vector<VALUE_TYPE, ALLOCATOR>::constructFromRange(
3222 INPUT_ITER first,
3223 SENTINEL last,
3224 std::input_iterator_tag)
3225{
3226 // IMPLEMENTATION NOTES: construct this vector by iterated 'push_back',
3227 // which may reallocate memory multiple times, but unfortunately is
3228 // required because we can't compute the size in advance (as with
3229 // @ref forward_iterator_tag ) because input iterators can be traversed only
3230 // once. A temporary vector is populated and then swapped to ensure that
3231 // all memory is reclaimed if @ref emplace_back throws, as the destructor will
3232 // not run when this method is called from a constructor.
3233
3234 vector temp(this->get_allocator());
3235 while (first != last) {
3236 temp.emplace_back(*first);
3237 ++first;
3238 }
3239 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
3240}
3241
3242template <class VALUE_TYPE, class ALLOCATOR>
3243template <class INTEGRAL>
3244void vector<VALUE_TYPE, ALLOCATOR>::constructFromRange(
3245 INTEGRAL initialSize,
3246 INTEGRAL value,
3247 BloombergLP::bslmf::Nil)
3248{
3249 // IMPLEMENTATION NOTES: this constructor is trying to construct a range of
3250 // 'initialSize' elements having the specified integral 'value'. Without
3251 // this extra overload, such calls would match an attempt to construct from
3252 // a range specified by two iterators. Note that as 'VALUE_TYPE' must be
3253 // a (trivial) integral type, a proctor is almost certainly not needed.
3254 // The only risk of a throw is for user-defined allocators doing strange
3255 // extra (potentially throwing) work in their 'construct' call.
3256
3258 static_cast<size_type>(initialSize) > max_size())) {
3260 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3261 "vector<...>::(repeated-value constructor): input too long");
3262 }
3263
3264 if (initialSize > 0) {
3265 privateReserveEmpty(initialSize);
3266 Proctor proctor(this->d_dataBegin_p,
3267 this->d_capacity,
3268 static_cast<ContainerBase *>(this));
3269
3270 ArrayPrimitives::uninitializedFillN(this->d_dataBegin_p,
3271 initialSize,
3272 static_cast<VALUE_TYPE>(value),
3273 this->allocatorRef());
3274
3275 proctor.release();
3276 this->d_dataEnd_p += initialSize;
3277 }
3278}
3279
3280template <class VALUE_TYPE, class ALLOCATOR>
3281template <class t_ITERATOR, class t_SENTINEL>
3282void vector<VALUE_TYPE, ALLOCATOR>::constructFromSizedRange(t_ITERATOR first,
3283 t_SENTINEL last,
3284 size_type size)
3285{
3286 if (size == 0) {
3287 return; // RETURN
3288 }
3289
3290 const size_type maxSize = max_size();
3291 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(size > maxSize)) {
3293 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3294 "vector<...>::(range-constructor): input too long");
3295 }
3296
3297 size_type newCapacity = Vector_Util::computeNewCapacity(size, 0, maxSize);
3298 this->privateReserveEmpty(newCapacity);
3299 Proctor proctor(this->d_dataBegin_p,
3300 this->d_capacity,
3301 static_cast<ContainerBase *>(this));
3302
3303 ArrayPrimitives::copyConstruct(this->d_dataEnd_p,
3304 first,
3305 last,
3306 this->allocatorRef());
3307 proctor.release();
3308 this->d_dataEnd_p += size;
3309}
3310
3311template <class VALUE_TYPE, class ALLOCATOR>
3312template <class t_RANGE, class t_ITERATOR>
3313inline
3314void vector<VALUE_TYPE, ALLOCATOR>::privateAppendRange(
3315 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
3316 t_ITERATOR begin)
3317{
3318 BSLS_ASSERT_SAFE(begin == ranges::begin(range));
3319
3321 privateAppendRange(BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range),
3322 begin,
3323 Tag());
3324}
3325
3326template <class VALUE_TYPE, class ALLOCATOR>
3327template <class t_RANGE, class t_ITERATOR>
3328inline
3329void vector<VALUE_TYPE, ALLOCATOR>::privateAppendRange(
3330 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
3331 t_ITERATOR begin,
3332 std::forward_iterator_tag)
3333{
3334#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
3335 if constexpr (ranges::sized_range<t_RANGE>) {
3336 privateAppendSizedRange(begin,
3337 ranges::end(range),
3338 ranges::size(range));
3339 }
3340 else //
3341#endif
3342 privateAppendSizedRange(
3343 begin,
3344 ranges::end(range),
3345 BloombergLP::bslstl::IteratorUtil::insertDistance(begin,
3346 ranges::end(range)));
3347}
3348
3349template <class VALUE_TYPE, class ALLOCATOR>
3350template <class t_RANGE, class t_ITERATOR>
3351inline
3352void vector<VALUE_TYPE, ALLOCATOR>::privateAppendRange(
3353 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
3354 t_ITERATOR begin,
3355 std::input_iterator_tag)
3356{
3357#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
3358 if constexpr (ranges::sized_range<t_RANGE>) {
3359 privateAppendSizedRange(begin,
3360 ranges::end(range),
3361 ranges::size(range));
3362 }
3363 else // ...
3364#endif
3365 {
3366 privateAppendUnsizedRange(begin, ranges::end(range));
3367 }
3368}
3369
3370template <class VALUE_TYPE, class ALLOCATOR>
3371template <class t_ITERATOR, class t_SENTINEL>
3372inline
3373void vector<VALUE_TYPE, ALLOCATOR>::privateAppendSizedRange(
3374 t_ITERATOR begin,
3375 t_SENTINEL end,
3376 size_type rangeSize)
3377{
3378 if (rangeSize == 0) {
3379 return; // RETURN
3380 }
3381
3382 size_type size = this->size();
3383 size_type diff = max_size() - size;
3384 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(rangeSize > diff)) {
3386 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3387 "vector<...>::(range-constructor): input too long");
3388 }
3389
3390 size += rangeSize;
3391 if (size > this->capacity()) {
3392 this->reserve(size);
3393 }
3394 BSLS_ASSERT_SAFE(this->capacity() >= size);
3395 ArrayPrimitives::copyConstruct(this->d_dataEnd_p,
3396 begin,
3397 end,
3398 this->allocatorRef());
3399 this->d_dataEnd_p += rangeSize;
3400}
3401
3402template <class VALUE_TYPE, class ALLOCATOR>
3403template <class t_ITERATOR, class t_SENTINEL>
3404inline
3405void vector<VALUE_TYPE, ALLOCATOR>::privateAppendUnsizedRange(t_ITERATOR begin,
3406 t_SENTINEL end)
3407{
3408 for (; begin != end; ++begin) {
3409 emplace_back(*begin);
3410 }
3411}
3412
3413template <class VALUE_TYPE, class ALLOCATOR>
3414template <class INPUT_ITER>
3415inline
3416void vector<VALUE_TYPE, ALLOCATOR>::privateInsertDispatch(
3417 const_iterator position,
3418 INPUT_ITER count,
3419 INPUT_ITER value,
3420 BloombergLP::bslmf::MatchArithmeticType ,
3421 BloombergLP::bslmf::Nil )
3422{
3423 // 'count' and 'value' are integral types that just happen to be the same.
3424 // They are not iterators, so we call 'insert(position, count, value)'.
3425
3426 this->insert(position,
3427 static_cast<size_type>(count),
3428 static_cast<VALUE_TYPE>(value));
3429}
3430
3431template <class VALUE_TYPE, class ALLOCATOR>
3432template <class INPUT_ITER>
3433inline
3434void vector<VALUE_TYPE, ALLOCATOR>::privateInsertDispatch(
3435 const_iterator position,
3436 INPUT_ITER first,
3437 INPUT_ITER last,
3438 BloombergLP::bslmf::MatchAnyType ,
3439 BloombergLP::bslmf::MatchAnyType )
3440{
3441 // Dispatch based on iterator category.
3442 BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last));
3443
3445 Tag;
3446 this->privateInsert(position, first, last, Tag());
3447}
3448
3449template <class VALUE_TYPE, class ALLOCATOR>
3450template <class t_ITERATOR, class t_SENTINEL>
3451inline
3452void vector<VALUE_TYPE, ALLOCATOR>::privateInsert(const_iterator position,
3453 t_ITERATOR first,
3454 t_SENTINEL last)
3455{
3457 Tag;
3458 this->privateInsert(position, first, last, Tag());
3459}
3460
3461template <class VALUE_TYPE, class ALLOCATOR>
3462template <class INPUT_ITER, class SENTINEL>
3463void vector<VALUE_TYPE, ALLOCATOR>::privateInsert(
3464 const_iterator position,
3465 INPUT_ITER first,
3466 SENTINEL last,
3467 const std::input_iterator_tag&)
3468{
3469 // IMPLEMENTATION NOTES: We can't compute the size in advance. Append onto
3470 // the back of the current vector while capacity remains. This honors the
3471 // idea of not allocating unnecessarily for the temporary vector, and so
3472 // saves important cycles from a sequential allocator. We then need to
3473 // shuffle the data back into the correct position. If capacity must grow,
3474 // then create a new vector and move just the newly inserted elements into
3475 // place, moving the original vector elements only in the event that all
3476 // iterated elements are correctly inserted.
3477
3478 // Short-circuit if there is nothing to do, do not allocate for an empty
3479 // 'vector' as that would invalidate 'begin'.
3480
3481 if (first == last) {
3482 return; // RETURN
3483 }
3484
3485 if (!this->capacity()) {
3486 privateReserveEmpty(size_type(1));
3487 position = this->d_dataBegin_p; // 'position' must have been null
3488 }
3489
3490 size_type insertOffset = position - this->d_dataBegin_p;
3491 size_type initialEnd = this->size();
3492 size_type tailLength = this->end() - position;
3493
3494 VALUE_TYPE *emplaceBegin = this->d_dataEnd_p;
3495 VALUE_TYPE *emplaceEnd = this->d_dataBegin_p + this->d_capacity;
3496 VALUE_TYPE *emplacePosition = emplaceBegin;
3497
3498 allocator_type alloc(this->get_allocator()); // need non-'const' lvalue
3499
3500 // This vector is not used if sufficient capacity can be found in the
3501 // current vector for all the insertions. However, it must have a
3502 // lifetime longer than the destructor guard below, in order to ensure
3503 // that the guarded elements are destroyed before the allocated storage
3504 // that holds them if an exception is thrown.
3505 vector resultState(alloc); // vector that will build the final state
3506
3507 // TBD: We really need an allocator-aware 'AutoDestructor' that will call
3508 // 'allocator_traits<ALLOC>::destroy(allocator, pointer)' rather than
3509 // invoke the destructor directly. 'bslalg::AutoArrayDestructor' is close,
3510 // but lacks 'reset'.
3511 BloombergLP::bslma::AutoDestructor<VALUE_TYPE> insertProctor(
3512 emplacePosition);
3513 while (emplacePosition != emplaceEnd) {
3514 AllocatorTraits::construct(alloc, emplacePosition, *first);
3515 ++insertProctor;
3516 ++emplacePosition;
3517 if (++first == last) {
3518 this->d_dataEnd_p = emplacePosition;
3519 insertProctor.release();
3520
3521 ArrayPrimitives::rotate(this->d_dataBegin_p + insertOffset,
3522 this->d_dataBegin_p + initialEnd,
3523 this->d_dataEnd_p);
3524 return; // RETURN
3525 }
3526 }
3527
3528 // Now we need to grow a buffer and destructive-move only the new elements.
3529 // This needs to be handled in a loop that can allow for multiple growth
3530 // spurts.
3531
3532 resultState.reserve(this->d_capacity*2);
3533 emplacePosition = resultState.d_dataBegin_p + insertOffset;
3534 ArrayPrimitives::destructiveMove(emplacePosition,
3535 emplaceBegin,
3536 emplaceEnd,
3537 alloc);
3538
3539 size_type emplaceOffset = (emplaceEnd - emplaceBegin);
3540 insertProctor.reset(emplacePosition);
3541 emplaceBegin = emplacePosition;
3542 emplaceEnd = resultState.d_dataBegin_p + resultState.d_capacity
3543 - tailLength;
3544 emplacePosition += emplaceOffset;
3545
3546 while (first != last) {
3547 if (emplacePosition == emplaceEnd) {
3548 // need to grow again
3549 vector nextResult(alloc);
3550 nextResult.reserve(resultState.d_capacity*2);
3551 emplacePosition = nextResult.d_dataBegin_p + insertOffset;
3552 ArrayPrimitives::destructiveMove(emplacePosition,
3553 emplaceBegin,
3554 emplaceEnd,
3555 alloc);
3556
3557 insertProctor.reset(emplacePosition);
3558 emplaceOffset = (emplaceEnd - emplaceBegin);
3559 emplaceBegin = emplacePosition;
3560 emplaceEnd = nextResult.d_dataBegin_p + nextResult.d_capacity
3561 - tailLength;
3562 emplacePosition += emplaceOffset;
3563
3564 Vector_Util::swap(&nextResult.d_dataBegin_p,
3565 &resultState.d_dataBegin_p);
3566 }
3567
3568 AllocatorTraits::construct(alloc, emplacePosition, *first);
3569 ++insertProctor;
3570 ++emplacePosition;
3571 ++first;
3572 }
3573
3574 // move tail
3575 ArrayPrimitives::destructiveMove(emplacePosition,
3576 this->d_dataBegin_p + insertOffset,
3577 this->d_dataBegin_p + initialEnd,
3578 alloc);
3579
3580 // reset 'end' in case a throw follows:
3581 this->d_dataEnd_p = this->d_dataBegin_p + insertOffset;
3582 emplacePosition += (initialEnd - insertOffset);
3583 insertProctor.setLength(
3584 insertProctor.length() + static_cast<int>(initialEnd - insertOffset));
3585
3586 // move prefix
3587 ArrayPrimitives::destructiveMove(resultState.d_dataBegin_p,
3588 this->d_dataBegin_p,
3589 this->d_dataBegin_p + insertOffset,
3590 alloc);
3591
3592 // Nothing after this point can throw.
3593
3594 // 'resultState' adopts ownership of all elements
3595 resultState.d_dataEnd_p = emplacePosition;
3596
3597 // We no longer own any data to protect
3598 insertProctor.release();
3599 this->d_dataEnd_p = this->d_dataBegin_p;
3600
3601 // Finally, swap states
3602 Vector_Util::swap(&this->d_dataBegin_p, &resultState.d_dataBegin_p);
3603}
3604
3605template <class VALUE_TYPE, class ALLOCATOR>
3606template <class FWD_ITER, class SENTINEL>
3607void vector<VALUE_TYPE, ALLOCATOR>::privateInsert(
3608 const_iterator position,
3609 FWD_ITER first,
3610 SENTINEL last,
3611 const std::forward_iterator_tag&)
3612{
3613 // Specialization for all iterators except input iterators: 'size' can be
3614 // computed in advance.
3615 BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last));
3616 BSLS_ASSERT_OPT((BloombergLP::bslstl::IteratorUtil
3617 ::canCalculateInsertDistance<FWD_ITER, SENTINEL>()));
3618
3619 const iterator& pos = const_cast<iterator>(position);
3620
3621 const size_type maxSize = max_size();
3622 const size_type n =
3623 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
3624
3625 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(n > maxSize - this->size())) {
3627 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3628 "vector<...>::insert(pos,first,last): vector too long");
3629 }
3630
3631 const size_type newSize = this->size() + n;
3632 if (newSize > this->d_capacity) {
3633 size_type newCapacity = Vector_Util::computeNewCapacity(
3634 newSize,
3635 this->d_capacity,
3636 maxSize);
3637
3638 vector temp(this->get_allocator());
3639 temp.privateReserveEmpty(newCapacity);
3640
3641 ArrayPrimitives::destructiveMoveAndInsert(temp.d_dataBegin_p,
3642 &this->d_dataEnd_p,
3643 this->d_dataBegin_p,
3644 pos,
3645 this->d_dataEnd_p,
3646 first,
3647 last,
3648 n,
3649 this->allocatorRef());
3650 temp.d_dataEnd_p += newSize;
3651 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
3652 }
3653 else {
3654 ArrayPrimitives::insert(pos,
3655 this->end(),
3656 first,
3657 last,
3658 n,
3659 this->allocatorRef());
3660 this->d_dataEnd_p += n;
3661 }
3662}
3663
3664template <class VALUE_TYPE, class ALLOCATOR>
3665void vector<VALUE_TYPE, ALLOCATOR>::privateMoveInsert(
3666 vector *fromVector,
3667 const_iterator position)
3668{
3669 const iterator& pos = const_cast<const iterator&>(position);
3670
3671 const size_type maxSize = max_size();
3672 const size_type n = fromVector->size();
3673 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(n > maxSize - this->size())) {
3675 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3676 "vector<...>::insert(pos,first,last): vector too long");
3677 }
3678
3679 const size_type newSize = this->size() + n;
3680 if (newSize > this->d_capacity) {
3681 const size_type newCapacity = Vector_Util::computeNewCapacity(
3682 newSize,
3683 this->d_capacity,
3684 maxSize);
3685
3686 vector temp(this->get_allocator());
3687 temp.privateReserveEmpty(newCapacity);
3688
3689 ArrayPrimitives::destructiveMoveAndMoveInsert(
3690 temp.d_dataBegin_p,
3691 &this->d_dataEnd_p,
3692 &fromVector->d_dataEnd_p,
3693 this->d_dataBegin_p,
3694 pos,
3695 this->d_dataEnd_p,
3696 fromVector->d_dataBegin_p,
3697 fromVector->d_dataEnd_p,
3698 n,
3699 this->allocatorRef());
3700 temp.d_dataEnd_p += newSize;
3701 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
3702 }
3703 else {
3704 ArrayPrimitives::moveInsert(pos,
3705 this->end(),
3706 &fromVector->d_dataEnd_p,
3707 fromVector->d_dataBegin_p,
3708 fromVector->d_dataEnd_p,
3709 n,
3710 this->allocatorRef());
3711 this->d_dataEnd_p += n;
3712 }
3713}
3714
3715template <class VALUE_TYPE, class ALLOCATOR>
3716inline
3717void vector<VALUE_TYPE, ALLOCATOR>::privateReserveEmpty(size_type numElements)
3718{
3719 BSLS_ASSERT_SAFE(this->empty());
3720 BSLS_ASSERT_SAFE(0 == this->capacity());
3721
3722 this->d_dataBegin_p = this->d_dataEnd_p =
3723 AllocatorUtil::allocateObject<VALUE_TYPE>(this->allocatorRef(),
3724 numElements);
3725
3726 this->d_capacity = numElements;
3727}
3728
3729#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3730template <class VALUE_TYPE, class ALLOCATOR>
3731template <class... Args>
3732void vector<VALUE_TYPE, ALLOCATOR>::privateEmplaceBackWithAllocation(
3733 Args&&...arguments)
3734{
3735 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())) {
3737 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3738 "vector<...>:emplace_back(args...): vector too long");
3739 }
3740
3741 size_type newCapacity = Vector_Util::computeNewCapacity(this->size() + 1,
3742 this->d_capacity,
3743 this->max_size());
3744 vector temp(this->get_allocator());
3745 temp.privateReserveEmpty(newCapacity);
3746
3747 // Construct before we risk invalidating the reference
3748 VALUE_TYPE *pos = temp.d_dataBegin_p + this->size();
3749 AllocatorTraits::construct(
3750 this->allocatorRef(),
3751 pos,
3752 BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...);
3753
3754 // Nothing else should throw, but probably worth guarding the above
3755 // 'construct' call for types with potentially-throwing destructive moves.
3756 Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard(pos, this->allocatorRef());
3757 ArrayPrimitives::destructiveMove(temp.d_dataBegin_p,
3758 this->d_dataBegin_p,
3759 this->d_dataEnd_p,
3760 this->allocatorRef());
3761 guard.release(); // Nothing after this can throw
3762
3763 this->d_dataEnd_p = this->d_dataBegin_p;
3764 temp.d_dataEnd_p = ++pos;
3765 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
3766}
3767#endif
3768
3769template <class VALUE_TYPE, class ALLOCATOR>
3770void vector<VALUE_TYPE, ALLOCATOR>::privatePushBackWithAllocation(
3771 const VALUE_TYPE& value)
3772{
3773 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())) {
3775 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3776 "vector<...>:push_back(lvalue): vector too long");
3777 }
3778
3779 size_type newCapacity = Vector_Util::computeNewCapacity(this->size() + 1,
3780 this->d_capacity,
3781 this->max_size());
3782
3783 vector temp(this->get_allocator());
3784 temp.privateReserveEmpty(newCapacity);
3785
3786 // Construct before we risk invalidating the reference
3787 VALUE_TYPE *pos = temp.d_dataBegin_p + this->size();
3788 AllocatorTraits::construct(this->allocatorRef(), pos, value);
3789
3790 // Nothing else should throw, but probably worth guarding the above
3791 // 'construct' call for types with potentially-throwing destructive moves.
3792 Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard(pos, this->allocatorRef());
3793 ArrayPrimitives::destructiveMove(temp.d_dataBegin_p,
3794 this->d_dataBegin_p,
3795 this->d_dataEnd_p,
3796 this->allocatorRef());
3797 guard.release(); // Nothing after this can throw
3798
3799 this->d_dataEnd_p = this->d_dataBegin_p;
3800 temp.d_dataEnd_p = ++pos;
3801 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
3802}
3803
3804template <class VALUE_TYPE, class ALLOCATOR>
3805void vector<VALUE_TYPE, ALLOCATOR>::privatePushBackWithAllocation(
3806 BloombergLP::bslmf::MovableRef<VALUE_TYPE> value)
3807{
3808 VALUE_TYPE& lvalue = value;
3809 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(max_size() == this->size())) {
3811 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3812 "vector<...>:push_back(rvalue): vector too long");
3813 }
3814
3815 size_type newCapacity = Vector_Util::computeNewCapacity(this->size() + 1,
3816 this->d_capacity,
3817 this->max_size());
3818
3819 vector temp(this->get_allocator());
3820 temp.privateReserveEmpty(newCapacity);
3821
3822 // Construct before we risk invalidating the reference
3823 VALUE_TYPE *pos = temp.d_dataBegin_p + this->size();
3824 AllocatorTraits::construct(this->allocatorRef(),
3825 pos,
3826 MoveUtil::move(lvalue));
3827
3828 // Nothing else should throw, but probably worth guarding the above
3829 // 'construct' call for types with potentially-throwing destructive moves.
3830 Vector_PushProctor<VALUE_TYPE, ALLOCATOR> guard(pos, this->allocatorRef());
3831 ArrayPrimitives::destructiveMove(temp.d_dataBegin_p,
3832 this->d_dataBegin_p,
3833 this->d_dataEnd_p,
3834 this->allocatorRef());
3835 guard.release(); // Nothing after this can throw
3836
3837 this->d_dataEnd_p = this->d_dataBegin_p;
3838 temp.d_dataEnd_p = ++pos;
3839 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
3840}
3841
3842// CREATORS
3843
3844 // *** construct/copy/destroy ***
3845
3846template <class VALUE_TYPE, class ALLOCATOR>
3847inline
3849: vectorBase<VALUE_TYPE>()
3850, ContainerBase(ALLOCATOR())
3851{
3852}
3853
3854template <class VALUE_TYPE, class ALLOCATOR>
3855inline
3856vector<VALUE_TYPE, ALLOCATOR>::vector(const ALLOCATOR& basicAllocator)
3859, ContainerBase(basicAllocator)
3860{
3861}
3862
3863template <class VALUE_TYPE, class ALLOCATOR>
3865 const ALLOCATOR& basicAllocator)
3866: vectorBase<VALUE_TYPE>()
3867, ContainerBase(basicAllocator)
3868{
3869 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(initialSize > max_size())) {
3871 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3872 "vector<...>::vector(n,v): vector too long");
3873 }
3874 if (initialSize > 0) {
3875 privateReserveEmpty(initialSize);
3876 Proctor proctor(this->d_dataBegin_p,
3877 this->d_capacity,
3878 static_cast<ContainerBase *>(this));
3879
3880 ArrayPrimitives::defaultConstruct(this->d_dataBegin_p,
3881 initialSize,
3882 this->allocatorRef());
3883
3884 proctor.release();
3885 this->d_dataEnd_p += initialSize;
3886 }
3887}
3888
3889template <class VALUE_TYPE, class ALLOCATOR>
3891 const VALUE_TYPE& value,
3892 const ALLOCATOR& basicAllocator)
3893: vectorBase<VALUE_TYPE>()
3894, ContainerBase(basicAllocator)
3895{
3896 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(initialSize > max_size())) {
3898 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3899 "vector<...>::vector(n,v): vector too long");
3900 }
3901 if (initialSize > 0) {
3902 privateReserveEmpty(initialSize);
3903 Proctor proctor(this->d_dataBegin_p,
3904 this->d_capacity,
3905 static_cast<ContainerBase *>(this));
3906
3907 ArrayPrimitives::uninitializedFillN(this->d_dataBegin_p,
3908 initialSize,
3909 value,
3910 this->allocatorRef());
3911
3912 proctor.release();
3913 this->d_dataEnd_p += initialSize;
3914 }
3915}
3916
3917template <class VALUE_TYPE, class ALLOCATOR>
3918template <class INPUT_ITER>
3921 INPUT_ITER last,
3922 const ALLOCATOR& basicAllocator)
3923: vectorBase<VALUE_TYPE>()
3924, ContainerBase(basicAllocator)
3925{
3926 BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last));
3927
3929 Tag;
3930
3931 if (is_same<Tag, BloombergLP::bslmf::Nil>::value || first != last) {
3932 // Range-check avoids allocating on an empty sequence.
3933 constructFromRange(first, last, Tag());
3934 }
3935}
3936
3937template <class VALUE_TYPE, class ALLOCATOR>
3939: vectorBase<VALUE_TYPE>()
3940, ContainerBase(AllocatorTraits::select_on_container_copy_construction(
3941 original.get_allocator()))
3942{
3943 if (original.size() > 0) {
3944 privateReserveEmpty(original.size());
3945 Proctor proctor(this->d_dataBegin_p,
3946 this->d_capacity,
3947 static_cast<ContainerBase *>(this));
3948
3949 ArrayPrimitives::copyConstruct(this->d_dataBegin_p,
3950 original.begin(),
3951 original.end(),
3952 this->allocatorRef());
3953
3954 proctor.release();
3955 this->d_dataEnd_p += original.size();
3956 }
3957}
3958
3959template <class VALUE_TYPE, class ALLOCATOR>
3961vector(const vector& original,
3962 const typename type_identity<ALLOCATOR>::type& basicAllocator)
3963: vectorBase<VALUE_TYPE>()
3964, ContainerBase(basicAllocator)
3965{
3966 if (original.size() > 0) {
3967 privateReserveEmpty(original.size());
3968 Proctor proctor(this->d_dataBegin_p,
3969 this->d_capacity,
3970 static_cast<ContainerBase *>(this));
3971
3972 ArrayPrimitives::copyConstruct(this->d_dataBegin_p,
3973 original.begin(),
3974 original.end(),
3975 this->allocatorRef());
3976
3977 proctor.release();
3978 this->d_dataEnd_p += original.size();
3979 }
3980}
3981
3982template <class VALUE_TYPE, class ALLOCATOR>
3984 BloombergLP::bslmf::MovableRef<vector> original)
3987, ContainerBase(MoveUtil::access(original).get_allocator())
3988{
3989 vector& lvalue = original;
3990 ImpBase::adopt(MoveUtil::move(static_cast<ImpBase&>(lvalue)));
3991}
3992
3993template <class VALUE_TYPE, class ALLOCATOR>
3995 BloombergLP::bslmf::MovableRef<vector> original,
3996 const typename type_identity<ALLOCATOR>::type& basicAllocator)
3997: vectorBase<VALUE_TYPE>()
3998, ContainerBase(basicAllocator)
3999{
4000 vector& lvalue = original;
4001
4003 lvalue.get_allocator())) {
4004 ImpBase::adopt(MoveUtil::move(static_cast<ImpBase&>(lvalue)));
4005 }
4006 else {
4007 if (lvalue.size() > 0) {
4008 privateReserveEmpty(lvalue.size());
4009 Proctor proctor(this->d_dataBegin_p,
4010 this->d_capacity,
4011 static_cast<ContainerBase *>(this));
4012
4013 ArrayPrimitives::moveConstruct(this->d_dataBegin_p,
4014 lvalue.begin(),
4015 lvalue.end(),
4016 this->allocatorRef());
4017
4018 proctor.release();
4019 this->d_dataEnd_p += lvalue.size();
4020 }
4021 }
4022}
4023
4024#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4025template <class VALUE_TYPE, class ALLOCATOR>
4026inline
4028 std::initializer_list<VALUE_TYPE> values,
4029 const ALLOCATOR& basicAllocator)
4030: vectorBase<VALUE_TYPE>()
4031, ContainerBase(basicAllocator)
4032{
4033 if (values.begin() != values.end()) {
4034 constructFromRange(values.begin(),
4035 values.end(),
4036 std::random_access_iterator_tag());
4037 }
4038}
4039
4040#endif
4041
4042template <class VALUE_TYPE, class ALLOCATOR>
4043template <class t_RANGE>
4045inline
4047 from_range_t ,
4048 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
4049 const ALLOCATOR& basicAllocator)
4050: vectorBase<VALUE_TYPE>()
4051, ContainerBase(basicAllocator)
4052{
4053 privateConstruct(from_range,
4054 BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range),
4055 ranges::begin(range));
4056}
4057
4058template <class VALUE_TYPE, class ALLOCATOR>
4061{
4062 using BloombergLP::bslalg::ArrayDestructionPrimitives;
4063
4064 // suppress buggy warning in GCC 12 and later (DRQS 174259807)
4065#ifdef BSLS_PLATFORM_CMP_GNU
4066#pragma GCC diagnostic push
4067#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
4068#endif
4069 if (this->d_dataBegin_p) {
4070 ArrayDestructionPrimitives::destroy(this->d_dataBegin_p,
4071 this->d_dataEnd_p,
4072 this->allocatorRef());
4073 AllocatorUtil::deallocateObject(this->allocatorRef(),
4074 this->d_dataBegin_p, this->d_capacity);
4075 }
4076#ifdef BSLS_PLATFORM_CMP_GNU
4077#pragma GCC diagnostic pop
4078#endif
4079}
4080
4081// MANIPULATORS
4082template <class VALUE_TYPE, class ALLOCATOR>
4085{
4086 typedef typename
4088
4090 if (Propagate::value) {
4091 vector other(rhs, rhs.get_allocator());
4092 Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p);
4093 AllocatorUtil::swap(&this->allocatorRef(),
4094 &other.allocatorRef(),
4095 Propagate());
4096 }
4097 else {
4098 clear();
4099 insert(this->begin(), rhs.begin(), rhs.end());
4100 }
4101 }
4102 return *this;
4103}
4104
4105template <class VALUE_TYPE, class ALLOCATOR>
4107 BloombergLP::bslmf::MovableRef<vector<VALUE_TYPE, ALLOCATOR> > rhs)
4109 AllocatorTraits::propagate_on_container_move_assignment::value ||
4110 AllocatorTraits::is_always_equal::value)
4111{
4112 typedef typename
4113 AllocatorTraits::propagate_on_container_move_assignment Propagate;
4114
4115 vector& lvalue = rhs;
4116 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &lvalue)) {
4117 if (get_allocator() == lvalue.get_allocator()) {
4118 vector other(MoveUtil::move(lvalue));
4119 Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p);
4120 }
4121 else if (Propagate::value) {
4122 vector other(MoveUtil::move(lvalue));
4123 AllocatorUtil::swap(&this->allocatorRef(),
4124 &other.allocatorRef(),
4125 Propagate());
4126 Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p);
4127 }
4128 else {
4129 vector other(MoveUtil::move(lvalue), this->allocatorRef());
4130 Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p);
4131 }
4132 }
4133 return *this;
4134}
4135
4136#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4137template <class VALUE_TYPE, class ALLOCATOR>
4138inline
4139vector<VALUE_TYPE, ALLOCATOR>&
4141 std::initializer_list<VALUE_TYPE> values)
4142{
4143 this->assign(values.begin(), values.end());
4144 return *this;
4145}
4146
4147template <class VALUE_TYPE, class ALLOCATOR>
4148inline
4150 std::initializer_list<VALUE_TYPE> values)
4151{
4152 assign(values.begin(), values.end());
4153}
4154#endif
4155
4156template <class VALUE_TYPE, class ALLOCATOR>
4157template <class INPUT_ITER>
4158inline
4159void vector<VALUE_TYPE, ALLOCATOR>::assign(INPUT_ITER first, INPUT_ITER last)
4160{
4161 BSLS_ASSERT_SAFE(!Vector_RangeCheck::isInvalidRange(first, last));
4162
4163 clear();
4164 insert(this->begin(), first, last);
4165}
4166
4167template <class VALUE_TYPE, class ALLOCATOR>
4168inline
4170 const VALUE_TYPE& value)
4171{
4172 clear();
4173 insert(this->begin(), numElements, value);
4174}
4175
4176template <class VALUE_TYPE, class ALLOCATOR>
4177template <class t_RANGE>
4179void vector<VALUE_TYPE, ALLOCATOR>::assign_range(
4180 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
4181{
4182 clear();
4183 append_range(BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range));
4184}
4185
4186 // *** capacity ***
4187
4188template <class VALUE_TYPE, class ALLOCATOR>
4190{
4191 // This function provides the *strong* exception guarantee (except when
4192 // the move constructor of a non-copy-insertable 'value_type' throws).
4193
4194 // Cannot use copy constructor since the only requirements on 'VALUE_TYPE'
4195 // are 'move-insertable' and 'default-constructible'.
4196
4197 if (newSize <= this->size()) {
4198 BloombergLP::bslalg::ArrayDestructionPrimitives::destroy(
4199 this->d_dataBegin_p + newSize,
4200 this->d_dataEnd_p,
4201 this->allocatorRef());
4202 this->d_dataEnd_p = this->d_dataBegin_p + newSize;
4203 }
4204 else if (0 == this->d_capacity) {
4205 // Because of {DRQS 99966534}, we check for zero capacity here and
4206 // handle it separately rather than falling into the case below.
4207 vector temp(newSize, this->get_allocator());
4208 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
4209 }
4210 else if (newSize > this->d_capacity) {
4211 const size_type maxSize = max_size();
4212 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(newSize > maxSize)) {
4214 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
4215 "vector<...>::resize(n): vector too long");
4216 }
4217
4219 newSize, this->d_capacity, maxSize);
4220
4221 vector temp(this->get_allocator());
4222 temp.privateReserveEmpty(newCapacity);
4223
4224 ArrayPrimitives::destructiveMoveAndInsert(temp.d_dataBegin_p,
4225 &this->d_dataEnd_p,
4226 this->d_dataBegin_p,
4227 this->d_dataEnd_p,
4228 this->d_dataEnd_p,
4229 newSize - this->size(),
4230 this->allocatorRef());
4231
4232 temp.d_dataEnd_p += newSize;
4233 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
4234 }
4235 else {
4236 ArrayPrimitives::defaultConstruct(this->d_dataEnd_p,
4237 newSize - this->size(),
4238 this->allocatorRef());
4239 this->d_dataEnd_p = this->d_dataBegin_p + newSize;
4240 }
4241}
4242
4243template <class VALUE_TYPE, class ALLOCATOR>
4245 const VALUE_TYPE& value)
4246{
4247 // This function provides the *strong* exception guarantee (except when
4248 // the move constructor of a non-copy-insertable 'value_type' throws).
4249
4250 if (newSize <= this->size()) {
4251 BloombergLP::bslalg::ArrayDestructionPrimitives::destroy(
4252 this->d_dataBegin_p + newSize,
4253 this->d_dataEnd_p,
4254 this->allocatorRef());
4255 this->d_dataEnd_p = this->d_dataBegin_p + newSize;
4256 }
4257 else {
4258 insert(this->d_dataEnd_p, newSize - this->size(), value);
4259 }
4260}
4261
4262template <class VALUE_TYPE, class ALLOCATOR>
4264{
4265 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(newCapacity > max_size())) {
4267 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
4268 "vector<...>::reserve(newCapacity): vector too long");
4269 }
4270 if (0 == this->d_capacity && 0 != newCapacity) {
4271 privateReserveEmpty(newCapacity);
4272 }
4273 else if (this->d_capacity < newCapacity) {
4274 vector temp(this->get_allocator());
4275 temp.privateReserveEmpty(newCapacity);
4276
4277 ArrayPrimitives::destructiveMove(temp.d_dataBegin_p,
4278 this->d_dataBegin_p,
4279 this->d_dataEnd_p,
4280 this->allocatorRef());
4281
4282 temp.d_dataEnd_p += this->size();
4283 this->d_dataEnd_p = this->d_dataBegin_p;
4284 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
4285 }
4286}
4287
4288template <class VALUE_TYPE, class ALLOCATOR>
4290{
4291 if (this->size() < this->d_capacity) {
4292 vector temp(this->get_allocator());
4293 if (this->size() > 0) {
4294 temp.privateReserveEmpty(this->size());
4295 ArrayPrimitives::destructiveMove(temp.d_dataBegin_p,
4296 this->d_dataBegin_p,
4297 this->d_dataEnd_p,
4298 this->allocatorRef());
4299
4300 temp.d_dataEnd_p += this->size();
4301 this->d_dataEnd_p = this->d_dataBegin_p;
4302 }
4303 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
4304 }
4305}
4306
4307 // *** modifiers ***
4308
4309template <class VALUE_TYPE, class ALLOCATOR>
4310template <class t_RANGE>
4312void vector<VALUE_TYPE, ALLOCATOR>::append_range(
4313 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
4314{
4315 privateAppendRange(BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range),
4316 ranges::begin(range));
4317}
4318
4319#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
4320template <class VALUE_TYPE, class ALLOCATOR>
4321template <class... Args>
4322inline
4323VALUE_TYPE &
4325{
4326 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) {
4327 AllocatorTraits::construct(
4328 this->allocatorRef(),
4329 this->d_dataEnd_p,
4330 BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...);
4331 ++this->d_dataEnd_p;
4332 }
4333 else {
4334 privateEmplaceBackWithAllocation(
4335 BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...);
4336 }
4337 return *(this->d_dataEnd_p - 1);
4338}
4339#endif
4340
4341template <class VALUE_TYPE, class ALLOCATOR>
4342inline
4343void vector<VALUE_TYPE, ALLOCATOR>::push_back(const VALUE_TYPE& value)
4344{
4345 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) {
4346 AllocatorTraits::construct(this->allocatorRef(),
4347 this->d_dataEnd_p,
4348 value);
4349 ++this->d_dataEnd_p;
4350 }
4351 else {
4352 privatePushBackWithAllocation(value);
4353 }
4354}
4355
4356template <class VALUE_TYPE, class ALLOCATOR>
4357inline
4359 BloombergLP::bslmf::MovableRef<VALUE_TYPE> value)
4360{
4361 VALUE_TYPE& lvalue = value;
4362 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this->d_capacity > this->size())) {
4363 AllocatorTraits::construct(this->allocatorRef(),
4364 this->d_dataEnd_p,
4365 MoveUtil::move(lvalue));
4366 ++this->d_dataEnd_p;
4367 }
4368 else {
4369 privatePushBackWithAllocation(MoveUtil::move(lvalue));
4370 }
4371}
4372
4373template <class VALUE_TYPE, class ALLOCATOR>
4374inline
4376{
4377 BSLS_ASSERT_SAFE(!this->empty());
4378
4379 AllocatorTraits::destroy(this->allocatorRef(),
4380 --this->d_dataEnd_p);
4381}
4382
4383template <class VALUE_TYPE, class ALLOCATOR>
4384inline
4387 const VALUE_TYPE& value)
4388{
4389 BSLS_ASSERT_SAFE(this->begin() <= position);
4390 BSLS_ASSERT_SAFE(position <= this->end());
4391
4392 return insert(position, size_type(1), value);
4393}
4394
4395template <class VALUE_TYPE, class ALLOCATOR>
4398 const_iterator position,
4399 BloombergLP::bslmf::MovableRef<VALUE_TYPE> value)
4400{
4401 BSLS_ASSERT_SAFE(this->begin() <= position);
4402 BSLS_ASSERT_SAFE(position <= this->end());
4403
4404 const size_type maxSize = max_size();
4405 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(1 > maxSize - this->size())) {
4407 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
4408 "vector<...>::insert(pos,rv): vector too long");
4409 }
4410
4411 VALUE_TYPE& lvalue = value;
4412
4413 const size_type index = position - this->begin();
4414 const iterator& pos = const_cast<const iterator&>(position);
4415 const size_type newSize = this->size() + 1;
4416
4417 if (newSize > this->d_capacity) {
4419 newSize,
4420 this->d_capacity,
4421 maxSize);
4422
4423 vector temp(this->get_allocator());
4424 temp.privateReserveEmpty(newCapacity);
4425
4426 ArrayPrimitives::destructiveMoveAndEmplace(temp.d_dataBegin_p,
4427 &this->d_dataEnd_p,
4428 this->d_dataBegin_p,
4429 pos,
4430 this->d_dataEnd_p,
4431 this->allocatorRef(),
4432 MoveUtil::move(lvalue));
4433
4434 temp.d_dataEnd_p += newSize;
4435 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
4436 }
4437 else {
4438 ArrayPrimitives::insert(pos,
4439 this->end(),
4440 MoveUtil::move(lvalue),
4441 this->allocatorRef());
4442 ++this->d_dataEnd_p;
4443 }
4444
4445 return this->begin() + index;
4446}
4447
4448template <class VALUE_TYPE, class ALLOCATOR>
4451 size_type numElements,
4452 const VALUE_TYPE& value)
4453{
4454 BSLS_ASSERT_SAFE(this->begin() <= position);
4455 BSLS_ASSERT_SAFE(position <= this->end());
4456
4457 const size_type maxSize = max_size();
4459 numElements > maxSize - this->size())) {
4461 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
4462 "vector<...>::insert(pos,n,v): vector too long");
4463 }
4464
4465 const size_type index = position - this->begin();
4466 const iterator& pos = const_cast<const iterator&>(position);
4467 const size_type newSize = this->size() + numElements;
4468
4469 if (newSize > this->d_capacity) {
4471 newSize,
4472 this->d_capacity,
4473 maxSize);
4474
4475 vector temp(this->get_allocator());
4476 temp.privateReserveEmpty(newCapacity);
4477
4478 ArrayPrimitives::destructiveMoveAndInsert(temp.d_dataBegin_p,
4479 &this->d_dataEnd_p,
4480 this->d_dataBegin_p,
4481 pos,
4482 this->d_dataEnd_p,
4483 value,
4484 numElements,
4485 this->allocatorRef());
4486
4487 temp.d_dataEnd_p += newSize;
4488 Vector_Util::swap(&this->d_dataBegin_p, &temp.d_dataBegin_p);
4489 }
4490 else {
4491 ArrayPrimitives::insert(pos,
4492 this->end(),
4493 value,
4494 numElements,
4495 this->allocatorRef());
4496 this->d_dataEnd_p += numElements;
4497 }
4498 return this->begin() + index;
4499}
4500
4501#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4502template <class VALUE_TYPE, class ALLOCATOR>
4503inline
4506 const_iterator position,
4507 std::initializer_list<VALUE_TYPE> values)
4508{
4509 return insert(position, values.begin(), values.end());
4510}
4511#endif
4512
4513template <class VALUE_TYPE, class ALLOCATOR>
4514template <class t_RANGE>
4518 const_iterator position,
4519 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
4520{
4521 BSLS_ASSERT_SAFE(this->begin() <= position);
4522 BSLS_ASSERT_SAFE(position <= this->end());
4523
4524 if (position == this->cend()) {
4525 const size_type oldSize = this->size();
4526 append_range(BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range));
4527 return this->begin() + oldSize; // RETURN
4528 }
4529
4530 const size_type index = position - this->begin();
4531 this->privateInsert(position, ranges::begin(range), ranges::end(range));
4532 return this->begin() + index;
4533}
4534
4535template <class VALUE_TYPE, class ALLOCATOR>
4536inline
4539{
4540 BSLS_ASSERT_SAFE(this->begin() <= position);
4541 BSLS_ASSERT_SAFE(position < this->end());
4542
4543 return erase(position, position + 1);
4544}
4545
4546// This should not be inlined by default due to an XLC 16 compiler bug whereby
4547// optimized code can spuriously core dump. This has been reported to IBM, see
4548// DRQS 169655225 for details.
4549template <class VALUE_TYPE, class ALLOCATOR>
4553{
4554 BSLS_ASSERT_SAFE(this->begin() <= first);
4555 BSLS_ASSERT_SAFE(first <= this->end());
4556 BSLS_ASSERT_SAFE(first <= last);
4557 BSLS_ASSERT_SAFE(last <= this->end());
4558
4559 const size_type n = last - first;
4560 ArrayPrimitives::erase(const_cast<VALUE_TYPE *>(first),
4561 const_cast<VALUE_TYPE *>(last),
4562 this->d_dataEnd_p,
4563 this->allocatorRef());
4564 this->d_dataEnd_p -= n;
4565 return const_cast<VALUE_TYPE *>(first);
4566}
4567
4568template <class VALUE_TYPE, class ALLOCATOR>
4571 AllocatorTraits::propagate_on_container_swap::value ||
4572 AllocatorTraits::is_always_equal::value)
4573{
4574 typedef typename
4575 AllocatorTraits::propagate_on_container_swap Propagate;
4576
4577 if (Propagate::value) {
4578 Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p);
4579 AllocatorUtil::swap(&this->allocatorRef(),
4580 &other.allocatorRef(),
4581 Propagate());
4582 }
4583 else {
4585 this->get_allocator() == other.get_allocator())) {
4586 Vector_Util::swap(&this->d_dataBegin_p, &other.d_dataBegin_p);
4587 }
4588 else {
4590
4591 vector toOtherCopy(MoveUtil::move(*this),
4592 other.get_allocator());
4593 vector toThisCopy( MoveUtil::move(other),
4594 this->get_allocator());
4595
4596 Vector_Util::swap(&toOtherCopy.d_dataBegin_p,
4597 &other.d_dataBegin_p);
4598 Vector_Util::swap(&toThisCopy. d_dataBegin_p,
4599 &this->d_dataBegin_p);
4600 }
4601 }
4602}
4603
4604template <class VALUE_TYPE, class ALLOCATOR>
4605inline
4607{
4608 if (!this->empty()) {
4609 BloombergLP::bslalg::ArrayDestructionPrimitives::destroy(
4610 this->d_dataBegin_p,
4611 this->d_dataEnd_p,
4612 this->allocatorRef());
4613 this->d_dataEnd_p = this->d_dataBegin_p;
4614 }
4615}
4616
4617// ACCESSORS
4618template <class VALUE_TYPE, class ALLOCATOR>
4619inline
4622{
4623 return this->allocatorRef();
4624}
4625
4626 // *** capacity ***
4627
4628template <class VALUE_TYPE, class ALLOCATOR>
4629inline
4632{
4633 return AllocatorTraits::max_size(this->allocatorRef());
4634}
4635
4636// FREE OPERATORS
4637
4638 // *** relational operators ***
4639
4640template <class VALUE_TYPE, class ALLOCATOR>
4641inline
4642bool operator==(const vector<VALUE_TYPE, ALLOCATOR>& lhs,
4644{
4645 return BloombergLP::bslalg::RangeCompare::equal(lhs.begin(),
4646 lhs.end(),
4647 lhs.size(),
4648 rhs.begin(),
4649 rhs.end(),
4650 rhs.size());
4651}
4652
4653#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
4654template <class VALUE_TYPE, class ALLOCATOR>
4655inline
4656bool operator!=(const vector<VALUE_TYPE, ALLOCATOR>& lhs,
4658{
4659 return ! (lhs == rhs);
4660}
4661#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
4662
4663#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
4664
4665template <class VALUE_TYPE, class ALLOCATOR>
4666inline
4667BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE_TYPE> operator<=>(
4668 const vector<VALUE_TYPE, ALLOCATOR>& lhs,
4669 const vector<VALUE_TYPE, ALLOCATOR>& rhs)
4670{
4671 return lexicographical_compare_three_way(
4672 lhs.begin(),
4673 lhs.end(),
4674 rhs.begin(),
4675 rhs.end(),
4676 BloombergLP::bslalg::SynthThreeWayUtil::compare);
4677}
4678
4679#else
4680
4681template <class VALUE_TYPE, class ALLOCATOR>
4682inline
4683bool operator< (const vector<VALUE_TYPE, ALLOCATOR>& lhs,
4685{
4686 return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.begin(),
4687 lhs.end(),
4688 lhs.size(),
4689 rhs.begin(),
4690 rhs.end(),
4691 rhs.size());
4692}
4693
4694template <class VALUE_TYPE, class ALLOCATOR>
4695inline
4696bool operator> (const vector<VALUE_TYPE, ALLOCATOR>& lhs,
4698{
4699 return rhs < lhs;
4700}
4701
4702template <class VALUE_TYPE, class ALLOCATOR>
4703inline
4704bool operator<=(const vector<VALUE_TYPE, ALLOCATOR>& lhs,
4706{
4707 return !(rhs < lhs);
4708}
4709
4710template <class VALUE_TYPE, class ALLOCATOR>
4711inline
4712bool operator>=(const vector<VALUE_TYPE, ALLOCATOR>& lhs,
4714{
4715 return !(lhs < rhs);
4716}
4717
4718#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
4719
4720// FREE FUNCTIONS
4721
4722 // *** specialized algorithms ***
4723
4724template <class VALUE_TYPE, class ALLOCATOR, class BDE_OTHER_TYPE>
4726erase(vector<VALUE_TYPE, ALLOCATOR>& vec, const BDE_OTHER_TYPE& value)
4727{
4728 typename vector<VALUE_TYPE, ALLOCATOR>::size_type oldSize = vec.size();
4729 vec.erase(bsl::remove(vec.begin(), vec.end(), value), vec.end());
4730 return oldSize - vec.size();
4731}
4732
4733template <class VALUE_TYPE, class ALLOCATOR, class PREDICATE>
4735erase_if(vector<VALUE_TYPE, ALLOCATOR>& vec, PREDICATE predicate)
4736{
4737 typename vector<VALUE_TYPE, ALLOCATOR>::size_type oldSize = vec.size();
4738 vec.erase(bsl::remove_if(vec.begin(), vec.end(), predicate), vec.end());
4739 return oldSize - vec.size();
4740}
4741
4742template <class VALUE_TYPE, class ALLOCATOR>
4743inline
4751
4752// HASH SPECIALIZATIONS
4753template <class HASHALG, class VALUE_TYPE, class ALLOCATOR>
4754inline
4755void hashAppend(HASHALG& hashAlg, const vector<VALUE_TYPE, ALLOCATOR>& input)
4756{
4757 using ::BloombergLP::bslh::hashAppend;
4759 hashAppend(hashAlg, input.size());
4760 for (ci_t b = input.begin(), e = input.end(); b != e; ++b) {
4761 hashAppend(hashAlg, *b);
4762 }
4763}
4764
4765
4766 // -------------------------------------
4767 // class vector<VALUE_TYPE *, ALLOCATOR>
4768 // -------------------------------------
4769
4770 // *** construct/copy/destroy ***
4771
4772// CREATORS
4773template <class VALUE_TYPE, class ALLOCATOR>
4774inline
4779
4780template <class VALUE_TYPE, class ALLOCATOR>
4781inline
4782vector<VALUE_TYPE *, ALLOCATOR>::vector(const ALLOCATOR& basicAllocator)
4784: d_impl(ImplAlloc(basicAllocator))
4785{
4786}
4787
4788template <class VALUE_TYPE, class ALLOCATOR>
4789inline
4791 const ALLOCATOR& basicAllocator)
4792: d_impl(initialSize, ImplAlloc(basicAllocator))
4793{
4794}
4795
4796template <class VALUE_TYPE, class ALLOCATOR>
4797inline
4799 VALUE_TYPE *value,
4800 const ALLOCATOR& basicAllocator)
4801: d_impl(initialSize, (UintPtr) value, ImplAlloc(basicAllocator))
4802{
4803}
4804
4805template <class VALUE_TYPE, class ALLOCATOR>
4806template <class INPUT_ITER>
4807inline
4809 INPUT_ITER last,
4810 const ALLOCATOR& basicAllocator)
4811: d_impl(typename vector_ForwardIteratorForPtrs<VALUE_TYPE, INPUT_ITER>::type(
4812 first),
4813 typename vector_ForwardIteratorForPtrs<VALUE_TYPE, INPUT_ITER>::type(
4814 last),
4815 basicAllocator)
4816{
4817}
4818
4819template <class VALUE_TYPE, class ALLOCATOR>
4820template <class t_RANGE>
4822inline
4824 from_range_t ,
4825 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
4826 const ALLOCATOR& basicAllocator)
4827: d_impl(from_range,
4828 vector_makeUintPtrRangeAdapter<VALUE_TYPE *>(ranges::begin(range),
4829 ranges::end(range)),
4830 basicAllocator)
4831{
4832}
4833
4834template <class VALUE_TYPE, class ALLOCATOR>
4835inline
4837: d_impl(original.d_impl)
4838{
4839}
4840
4841template <class VALUE_TYPE, class ALLOCATOR>
4842inline
4844 BloombergLP::bslmf::MovableRef<vector> original)
4846: d_impl(MoveUtil::move(MoveUtil::access(original).d_impl))
4847{
4848}
4849
4850template <class VALUE_TYPE, class ALLOCATOR>
4851inline
4853 const typename type_identity<ALLOCATOR>::type& basicAllocator)
4854: d_impl(original.d_impl, ImplAlloc(basicAllocator))
4855{
4856}
4857
4858template <class VALUE_TYPE, class ALLOCATOR>
4859inline
4861 BloombergLP::bslmf::MovableRef<vector> original,
4862 const typename type_identity<ALLOCATOR>::type& basicAllocator)
4863: d_impl(MoveUtil::move(MoveUtil::access(original).d_impl),
4864 ImplAlloc(basicAllocator))
4865{
4866}
4867
4868#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4869template <class VALUE_TYPE, class ALLOCATOR>
4870inline
4872 std::initializer_list<VALUE_TYPE *> values,
4873 const ALLOCATOR& basicAllocator)
4874: d_impl(typename vector_ForwardIteratorForPtrs<
4875 VALUE_TYPE,
4876 typename std::initializer_list<VALUE_TYPE *>::const_iterator>::
4877 type(values.begin()),
4879 VALUE_TYPE,
4880 typename std::initializer_list<VALUE_TYPE *>::const_iterator>::
4881 type(values.end()),
4882 basicAllocator)
4883{
4884}
4885#endif
4886
4887template <class VALUE_TYPE, class ALLOCATOR>
4888inline
4892
4893// MANIPULATORS
4894template <class VALUE_TYPE, class ALLOCATOR>
4895inline
4897 const vector& rhs)
4898{
4899 d_impl = rhs.d_impl;
4900 return *this;
4901}
4902
4903#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4904template <class VALUE_TYPE, class ALLOCATOR>
4905inline
4907 std::initializer_list<VALUE_TYPE *> values)
4908{
4909 assign(values);
4910 return *this;
4911}
4912
4913template <class VALUE_TYPE, class ALLOCATOR>
4914inline
4916 std::initializer_list<VALUE_TYPE *> values)
4917{
4918 typedef typename std::initializer_list<VALUE_TYPE *>::const_iterator
4919 InitIter;
4920
4922 Iter;
4923
4924 d_impl.assign(Iter(values.begin()), Iter(values.end()));
4925}
4926#endif
4927
4928template <class VALUE_TYPE, class ALLOCATOR>
4929template <class INPUT_ITER>
4930inline
4931void vector<VALUE_TYPE *, ALLOCATOR>::assign(INPUT_ITER first, INPUT_ITER last)
4932{
4933 typedef typename vector_ForwardIteratorForPtrs<VALUE_TYPE,
4934 INPUT_ITER>::type Iter;
4935
4936 d_impl.assign(Iter(first), Iter(last));
4937}
4938
4939template <class VALUE_TYPE, class ALLOCATOR>
4940inline
4941void vector<VALUE_TYPE *, ALLOCATOR>::assign(size_type numElements,
4942 VALUE_TYPE *value)
4943{
4944 d_impl.assign(numElements, (UintPtr) value);
4945}
4946
4947template <class VALUE_TYPE, class ALLOCATOR>
4948template <class t_RANGE>
4950inline
4952 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
4953{
4954 d_impl.assign_range(
4955 vector_makeUintPtrRangeAdapter<VALUE_TYPE *>(ranges::begin(range),
4956 ranges::end(range)));
4957}
4958
4959 // *** iterators ***
4960
4961template <class VALUE_TYPE, class ALLOCATOR>
4962inline
4968
4969template <class VALUE_TYPE, class ALLOCATOR>
4970inline
4976
4977template <class VALUE_TYPE, class ALLOCATOR>
4978inline
4984
4985template <class VALUE_TYPE, class ALLOCATOR>
4986inline
4992
4993 // *** capacity ***
4994
4995template <class VALUE_TYPE, class ALLOCATOR>
4996inline
4999{
5000 return d_impl.size();
5001}
5002
5003template <class VALUE_TYPE, class ALLOCATOR>
5004inline
5010
5011template <class VALUE_TYPE, class ALLOCATOR>
5012inline
5013bool
5018
5019 // *** element access ***
5020
5021template <class VALUE_TYPE, class ALLOCATOR>
5022inline
5025{
5026 return (reference) d_impl.operator[](position);
5027}
5028
5029template <class VALUE_TYPE, class ALLOCATOR>
5030inline
5033{
5034 return (reference) d_impl.at(position);
5035}
5036
5037template <class VALUE_TYPE, class ALLOCATOR>
5038inline
5041{
5042 return (reference) d_impl.front();
5043}
5044
5045template <class VALUE_TYPE, class ALLOCATOR>
5046inline
5049{
5050 return (reference) d_impl.back();
5051}
5052
5053template <class VALUE_TYPE, class ALLOCATOR>
5054inline
5056{
5057 return (VALUE_TYPE **) d_impl.data();
5058}
5059
5060 // *** capacity ***
5061
5062template <class VALUE_TYPE, class ALLOCATOR>
5063inline
5065{
5066 d_impl.resize(newLength);
5067}
5068
5069template <class VALUE_TYPE, class ALLOCATOR>
5070inline
5072 VALUE_TYPE *value)
5073{
5074 d_impl.resize(newLength, (UintPtr) value);
5075}
5076
5077template <class VALUE_TYPE, class ALLOCATOR>
5078inline
5080{
5081 d_impl.reserve(newCapacity);
5082}
5083
5084template <class VALUE_TYPE, class ALLOCATOR>
5085inline
5090
5091
5092 // *** modifiers ***
5093
5094template <class VALUE_TYPE, class ALLOCATOR>
5095template <class t_RANGE>
5097inline
5099 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
5100{
5101 d_impl.append_range(
5102 vector_makeUintPtrRangeAdapter<VALUE_TYPE *>(ranges::begin(range),
5103 ranges::end(range)));
5104}
5105
5106template <class VALUE_TYPE, class ALLOCATOR>
5107inline
5110{
5111 d_impl.emplace_back();
5112 return back();
5113}
5114
5115# if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
5116template <class VALUE_TYPE, class ALLOCATOR>
5117template <class ARG>
5118inline
5121{
5122 VALUE_TYPE *ptr(arg); // Support explicit conversion operators
5123 d_impl.emplace_back(reinterpret_cast<UintPtr>(ptr));
5124 return back();
5125}
5126# else
5127template <class VALUE_TYPE, class ALLOCATOR>
5128inline
5131{
5132 d_impl.emplace_back(reinterpret_cast<UintPtr>(ptr));
5133 return back();
5134}
5135# endif
5136
5137template <class VALUE_TYPE, class ALLOCATOR>
5138inline
5140{
5141 d_impl.emplace_back(reinterpret_cast<UintPtr>(value));
5142}
5143
5144template <class VALUE_TYPE, class ALLOCATOR>
5145inline
5147{
5148 d_impl.pop_back();
5149}
5150
5151template <class VALUE_TYPE, class ALLOCATOR>
5152inline
5155{
5156 return (iterator) d_impl.emplace((const UintPtr*) position);
5157}
5158
5159# if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
5160template <class VALUE_TYPE, class ALLOCATOR>
5161template <class ARG>
5162inline
5164vector<VALUE_TYPE *, ALLOCATOR>::emplace(const_iterator position, ARG&& arg)
5165{
5166 VALUE_TYPE *ptr(arg); // Support explicit conversion operators
5167 return (iterator) d_impl.emplace((const UintPtr *)position,
5168 reinterpret_cast<UintPtr>(ptr));
5169}
5170# else
5171template <class VALUE_TYPE, class ALLOCATOR>
5172inline
5175 VALUE_TYPE *ptr)
5176{
5177 return (iterator) d_impl.emplace((const UintPtr*) position,
5178 reinterpret_cast<UintPtr>(ptr));
5179}
5180# endif
5181
5182template <class VALUE_TYPE, class ALLOCATOR>
5183inline
5186 VALUE_TYPE *value)
5187{
5188 return (iterator) d_impl.emplace((const UintPtr*) position,
5189 reinterpret_cast<UintPtr>(value));
5190}
5191
5192template <class VALUE_TYPE, class ALLOCATOR>
5193inline
5196 size_type numElements,
5197 VALUE_TYPE *value)
5198{
5199 return (iterator) d_impl.insert(
5200 (const UintPtr *)position, numElements, (UintPtr)value);
5201}
5202
5203#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
5204template <class VALUE_TYPE, class ALLOCATOR>
5205inline
5208 const_iterator position,
5209 std::initializer_list<VALUE_TYPE *> values)
5210{
5211 typedef typename std::initializer_list<VALUE_TYPE *>::const_iterator
5212 InitIter;
5213
5215 Iter;
5216
5217 return (iterator) d_impl.insert(
5218 (const UintPtr *)position, Iter(values.begin()), Iter(values.end()));
5219}
5220#endif
5221
5222template <class VALUE_TYPE, class ALLOCATOR>
5223template <class t_RANGE>
5225inline
5228 const_iterator position,
5229 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
5230{
5231 return (iterator) d_impl.insert_range(
5232 (const UintPtr*) position,
5233 vector_makeUintPtrRangeAdapter<VALUE_TYPE *>(ranges::begin(range),
5234 ranges::end(range)));
5235}
5236
5237template <class VALUE_TYPE, class ALLOCATOR>
5238inline
5241{
5242 return (iterator) d_impl.erase((const UintPtr*) position);
5243}
5244
5245template <class VALUE_TYPE, class ALLOCATOR>
5246inline
5249 const_iterator last)
5250{
5251 return (iterator) d_impl.erase((const UintPtr*) first,
5252 (const UintPtr*) last);
5253}
5254
5255template <class VALUE_TYPE, class ALLOCATOR>
5256inline
5260 d_impl.swap(other.d_impl)))
5261{
5262 d_impl.swap(other.d_impl);
5263}
5264
5265template <class VALUE_TYPE, class ALLOCATOR>
5266inline
5271
5272// ACCESSORS
5273template <class VALUE_TYPE, class ALLOCATOR>
5274inline
5280
5281template <class VALUE_TYPE, class ALLOCATOR>
5282inline
5288
5289
5290 // *** iterators ***
5291
5292template <class VALUE_TYPE, class ALLOCATOR>
5293inline
5299
5300template <class VALUE_TYPE, class ALLOCATOR>
5301inline
5307
5308template <class VALUE_TYPE, class ALLOCATOR>
5309inline
5315
5316template <class VALUE_TYPE, class ALLOCATOR>
5317inline
5323
5324template <class VALUE_TYPE, class ALLOCATOR>
5325inline
5331
5332template <class VALUE_TYPE, class ALLOCATOR>
5333inline
5339
5340template <class VALUE_TYPE, class ALLOCATOR>
5341inline
5347
5348template <class VALUE_TYPE, class ALLOCATOR>
5349inline
5355
5356
5357 // *** element access ***
5358
5359template <class VALUE_TYPE, class ALLOCATOR>
5360inline
5363{
5364 return (const_reference) d_impl.operator[](position);
5365}
5366
5367template <class VALUE_TYPE, class ALLOCATOR>
5368inline
5371{
5372 return (const_reference) d_impl.at(position);
5373}
5374
5375template <class VALUE_TYPE, class ALLOCATOR>
5376inline
5379{
5380 return (const_reference) d_impl.front();
5381}
5382
5383template <class VALUE_TYPE, class ALLOCATOR>
5384inline
5387{
5388 return (const_reference) d_impl.back();
5389}
5390
5391template <class VALUE_TYPE, class ALLOCATOR>
5392inline
5395{
5396 return (VALUE_TYPE *const *) d_impl.data();
5397}
5398
5399
5400} // close namespace bsl
5401
5402// ============================================================================
5403// TYPE TRAITS
5404// ============================================================================
5405
5406// Type traits for STL *sequence* containers:
5407//: o A sequence container defines STL iterators.
5408//: o A sequence container is bitwise movable if the allocator is bitwise
5409//: movable.
5410//: o A sequence container uses 'bslma' allocators if the (template parameter)
5411//: type 'ALLOCATOR' is convertible from 'bslma::Allocator *'.
5412
5413
5414
5415namespace bslalg {
5416
5417template <class VALUE_TYPE, class ALLOCATOR>
5418struct HasStlIterators<bsl::vector<VALUE_TYPE, ALLOCATOR> > : bsl::true_type
5419{};
5420
5421} // close namespace bslalg
5422
5423namespace bslma {
5424
5425template <class VALUE_TYPE, class ALLOCATOR>
5426struct UsesBslmaAllocator<bsl::vector<VALUE_TYPE, ALLOCATOR> >
5427 : bsl::is_convertible<Allocator *, ALLOCATOR>::type
5428{};
5429
5430} // close namespace bslma
5431
5432namespace bslmf {
5433
5434template <class VALUE_TYPE, class ALLOCATOR>
5435struct IsBitwiseMoveable<bsl::vector<VALUE_TYPE, ALLOCATOR> >
5436 : IsBitwiseMoveable<ALLOCATOR>
5437{};
5438
5439} // close namespace bslmf
5440
5441
5442
5443#ifdef BSLS_COMPILERFEATURES_SUPPORT_EXTERN_TEMPLATE
5444extern template class bsl::vectorBase<bool>;
5445extern template class bsl::vectorBase<char>;
5446extern template class bsl::vectorBase<signed char>;
5447extern template class bsl::vectorBase<unsigned char>;
5448extern template class bsl::vectorBase<short>;
5449extern template class bsl::vectorBase<unsigned short>;
5450extern template class bsl::vectorBase<int>;
5451extern template class bsl::vectorBase<unsigned int>;
5452extern template class bsl::vectorBase<long>;
5453extern template class bsl::vectorBase<unsigned long>;
5454extern template class bsl::vectorBase<long long>;
5455extern template class bsl::vectorBase<unsigned long long>;
5456extern template class bsl::vectorBase<float>;
5457extern template class bsl::vectorBase<double>;
5458extern template class bsl::vectorBase<long double>;
5459extern template class bsl::vectorBase<void *>;
5460extern template class bsl::vectorBase<const char *>;
5461
5462extern template class bsl::vector<bool>;
5463extern template class bsl::vector<char>;
5464extern template class bsl::vector<signed char>;
5465extern template class bsl::vector<unsigned char>;
5466extern template class bsl::vector<short>;
5467extern template class bsl::vector<unsigned short>;
5468extern template class bsl::vector<int>;
5469extern template class bsl::vector<unsigned int>;
5470extern template class bsl::vector<long>;
5471extern template class bsl::vector<unsigned long>;
5472extern template class bsl::vector<long long>;
5473extern template class bsl::vector<unsigned long long>;
5474extern template class bsl::vector<float>;
5475extern template class bsl::vector<double>;
5476extern template class bsl::vector<long double>;
5477extern template class bsl::vector<void *>;
5478extern template class bsl::vector<const char *>;
5479#endif
5480
5481#endif // End C++11 code
5482
5483#undef BSLSTL_VECTOR_REQUIRES_CONTAINER_COMPATIBLE_RANGE
5484
5485#endif
5486
5487// ----------------------------------------------------------------------------
5488// Copyright 2018 Bloomberg Finance L.P.
5489//
5490// Licensed under the Apache License, Version 2.0 (the "License");
5491// you may not use this file except in compliance with the License.
5492// You may obtain a copy of the License at
5493//
5494// http://www.apache.org/licenses/LICENSE-2.0
5495//
5496// Unless required by applicable law or agreed to in writing, software
5497// distributed under the License is distributed on an "AS IS" BASIS,
5498// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5499// See the License for the specific language governing permissions and
5500// limitations under the License.
5501// ----------------------------- END-OF-FILE ----------------------------------
5502
5503/** @} */
5504/** @} */
5505/** @} */
Definition bslstl_vector.h:2729
~Vector_PushProctor()
Definition bslstl_vector.h:2780
void release()
Definition bslstl_vector.h:2790
Definition bslma_bslallocator.h:588
Definition bslstl_vector.h:924
VALUE_TYPE const & const_reference
Definition bslstl_vector.h:942
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:3019
std::size_t d_capacity
Definition bslstl_vector.h:936
VALUE_TYPE * d_dataEnd_p
Definition bslstl_vector.h:935
void adopt(BloombergLP::bslmf::MovableRef< vectorBase > base)
Definition bslstl_vector.h:2847
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2866
reference back()
Definition bslstl_vector.h:2932
size_type capacity() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:3027
std::ptrdiff_t difference_type
Definition bslstl_vector.h:946
VALUE_TYPE value_type
Definition bslstl_vector.h:940
const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2977
const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2961
VALUE_TYPE const * const_iterator
Definition bslstl_vector.h:944
std::size_t size_type
Definition bslstl_vector.h:945
const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:3009
reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2882
vectorBase()
Create an empty base object with no capacity.
Definition bslstl_vector.h:2835
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2874
VALUE_TYPE * d_dataBegin_p
Definition bslstl_vector.h:934
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_vector.h:948
reference at(size_type position)
Definition bslstl_vector.h:2909
VALUE_TYPE & reference
Definition bslstl_vector.h:941
bsl::reverse_iterator< iterator > reverse_iterator
Definition bslstl_vector.h:947
bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this vector has size 0, and false otherwise.
Definition bslstl_vector.h:3034
reference front()
Definition bslstl_vector.h:2922
reference operator[](size_type position)
Definition bslstl_vector.h:2900
reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2890
const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2993
VALUE_TYPE * iterator
Definition bslstl_vector.h:943
VALUE_TYPE * data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2942
std::size_t size_type
Definition bslstl_vector.h:2123
allocator_traits< ALLOCATOR >::pointer pointer
Definition bslstl_vector.h:2127
value_type & reference
Definition bslstl_vector.h:2119
ALLOCATOR allocator_type
Definition bslstl_vector.h:2125
const value_type & const_reference
Definition bslstl_vector.h:2120
friend bool operator!=(const vector &lhs, const vector &rhs)
Definition bslstl_vector.h:2354
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_vector.h:2131
bsl::reverse_iterator< iterator > reverse_iterator
Definition bslstl_vector.h:2130
friend void swap(vector &a, vector &b) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR(a.d_impl.swap(b.d_impl)))
Definition bslstl_vector.h:2386
VALUE_TYPE ** iterator
Definition bslstl_vector.h:2121
iterator insert(const_iterator position, INPUT_ITER first, INPUT_ITER last)
Definition bslstl_vector.h:2268
friend bool operator<=(const vector &lhs, const vector &rhs)
Definition bslstl_vector.h:2372
vector & operator=(BloombergLP::bslmf::MovableRef< vector< VALUE_TYPE *, ALLOCATOR > > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR(d_impl
friend bool operator>=(const vector &lhs, const vector &rhs)
Definition bslstl_vector.h:2378
std::ptrdiff_t difference_type
Definition bslstl_vector.h:2124
VALUE_TYPE * value_type
Definition bslstl_vector.h:2118
friend bool operator<(const vector &lhs, const vector &rhs)
Definition bslstl_vector.h:2360
VALUE_TYPE *const * const_iterator
Definition bslstl_vector.h:2122
allocator_traits< ALLOCATOR >::const_pointer const_pointer
Definition bslstl_vector.h:2129
friend bool operator>(const vector &lhs, const vector &rhs)
Definition bslstl_vector.h:2366
Definition bslstl_vector.h:2496
iterator_traits< ITERATOR >::iterator_category iterator_category
Definition bslstl_vector.h:2512
friend bool operator==(const vector_UintPtrConversionIterator &lhs, const vector_UintPtrConversionIterator &rhs)
Definition bslstl_vector.h:2577
BloombergLP::bsls::Types::UintPtr UintPtr
Definition bslstl_vector.h:2504
UintPtr reference
Definition bslstl_vector.h:2508
iterator_traits< ITERATOR >::difference_type difference_type
Definition bslstl_vector.h:2510
friend bool operator<(const vector_UintPtrConversionIterator &lhs, const vector_UintPtrConversionIterator &rhs)
Definition bslstl_vector.h:2590
friend bool operator!=(const vector_UintPtrConversionIterator &lhs, const vector_UintPtrConversionIterator &rhs)
Definition bslstl_vector.h:2560
UintPtr * pointer
Definition bslstl_vector.h:2507
vector_UintPtrConversionIterator & operator++()
Definition bslstl_vector.h:2649
UintPtr operator*() const
Definition bslstl_vector.h:2669
UintPtr value_type
Definition bslstl_vector.h:2506
vector_UintPtrConversionIterator()
Create an uninitialized proxy iterator.
Definition bslstl_vector.h:2633
friend difference_type operator-(const vector_UintPtrConversionIterator &lhs, const vector_UintPtrConversionIterator &rhs)
Definition bslstl_vector.h:2615
Definition bslstl_vector.h:1120
void assign(size_type numElements, const VALUE_TYPE &value)
Definition bslstl_vector.h:4169
VALUE_TYPE & reference
Definition bslstl_vector.h:1144
const VALUE_TYPE & const_reference
Definition bslstl_vector.h:1145
iterator insert_range(const_iterator position, BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
Definition bslstl_vector.h:4517
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:4621
VALUE_TYPE value_type
Definition bslstl_vector.h:1142
void shrink_to_fit()
Definition bslstl_vector.h:4289
iterator insert(const_iterator position, const VALUE_TYPE &value)
Definition bslstl_vector.h:4386
~vector()
Destroy this vector.
Definition bslstl_vector.h:4060
AllocatorTraits::size_type size_type
Definition bslstl_vector.h:1147
ALLOCATOR allocator_type
Definition bslstl_vector.h:1143
VALUE_TYPE & emplace_back(Args &&... arguments)
Definition bslstl_vector.h:4324
void reserve(size_type newCapacity)
Definition bslstl_vector.h:4263
void push_back(const VALUE_TYPE &value)
Definition bslstl_vector.h:4343
VALUE_TYPE * iterator
Definition bslstl_vector.h:1152
AllocatorTraits::difference_type difference_type
Definition bslstl_vector.h:1148
VALUE_TYPE const * const_iterator
Definition bslstl_vector.h:1153
bsl::reverse_iterator< iterator > reverse_iterator
Definition bslstl_vector.h:1154
iterator insert(const_iterator position, size_type numElements, const VALUE_TYPE &value)
Definition bslstl_vector.h:4450
iterator erase(const_iterator position)
Definition bslstl_vector.h:4538
size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:4631
iterator insert(const_iterator position, INPUT_ITER first, INPUT_ITER last)
Definition bslstl_vector.h:1845
void swap(vector &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:1938
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_vector.h:1155
AllocatorTraits::const_pointer const_pointer
Definition bslstl_vector.h:1150
void assign_range(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
Definition bslstl_vector.h:4179
vector & operator=(const vector &rhs)
Definition bslstl_vector.h:4084
void append_range(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
Definition bslstl_vector.h:4312
void resize(size_type newSize)
Definition bslstl_vector.h:4189
vector() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:3848
iterator insert(const_iterator position, BloombergLP::bslmf::MovableRef< VALUE_TYPE > value)
Definition bslstl_vector.h:4397
void pop_back()
Definition bslstl_vector.h:4375
vector &operator=(BloombergLP::bslmf::MovableRef< vector< VALUE_TYPE, ALLOCATOR > > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void assign(INPUT_ITER first, INPUT_ITER last)
iterator emplace(const_iterator position, Args &&... arguments)
Definition bslstl_vector.h:1728
AllocatorTraits::pointer pointer
Definition bslstl_vector.h:1149
void push_back(BloombergLP::bslmf::MovableRef< VALUE_TYPE > value)
Definition bslstl_vector.h:4358
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:2045
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_NOEXCEPT_OPERATOR(...)
Definition bsls_keyword.h:677
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:676
#define BSLS_PERFORMANCEHINT_PREDICT_LIKELY(expr)
Definition bsls_performancehint.h:451
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
#define BSLS_PLATFORM_AGGRESSIVE_INLINE
Definition bsls_platform.h:737
#define BSLSTL_VECTOR_REQUIRES_CONTAINER_COMPATIBLE_RANGE(R, T)
Definition bslstl_vector.h:691
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
int reserve(TYPE *array, int numElements)
int assign(LHS_TYPE *lhs, const RHS_TYPE &rhs)
Definition bdlat_valuetypefunctions.h:939
T::const_iterator cend(const T &container)
Definition bslstl_iterator.h:1709
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const array< TYPE, SIZE > &input)
Pass the specified input to the specified hashAlgorithm
Definition bslstl_array.h:959
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
deque< VALUE_TYPE, ALLOCATOR >::size_type erase(deque< VALUE_TYPE, ALLOCATOR > &deq, const BDE_OTHER_TYPE &value)
Definition bslstl_deque.h:4424
T::iterator begin(T &container)
Definition bslstl_iterator.h:1593
const from_range_t from_range
ALLOCATOR & lhs
Definition bslstl_string.h:3917
T::iterator end(T &container)
Definition bslstl_iterator.h:1621
deque< VALUE_TYPE, ALLOCATOR >::size_type erase_if(deque< VALUE_TYPE, ALLOCATOR > &deq, PREDICATE predicate)
Definition bslstl_deque.h:4433
BSLS_KEYWORD_CONSTEXPR CONTAINER::value_type * data(CONTAINER &container)
Definition bslstl_iterator.h:1325
BSLS_KEYWORD_CONSTEXPR bool empty(const CONTAINER &container)
Definition bslstl_iterator.h:1377
vector_UintPtrRangeAdapter< t_VALUE_TYPE, t_ITERATOR, t_SENTINEL > vector_makeUintPtrRangeAdapter(t_ITERATOR begin, t_SENTINEL end)
Factory function for vector_UintPtrRangeAdapter.
Definition bslstl_vector.h:2708
Definition bdlc_flathashmap.h:2218
Definition baljsn_encoder_testtypes.h:76
Definition bdlbb_blob.h:579
Definition bdldfp_decimal.h:5549
BloombergLP::bslmf::Nil type
Definition bslstl_vector.h:775
Definition bslstl_vector.h:760
bsl::iterator_traits< BSLSTL_ITERATOR >::iterator_category type
Definition bslstl_vector.h:764
BloombergLP::bslmf::Nil type
Definition bslstl_vector.h:819
Definition bslstl_vector.h:794
bsl::iterator_traits< t_ITERATOR >::iterator_category type
Definition bslstl_vector.h:807
Definition bslstl_vector.h:724
static std::size_t computeNewCapacity(std::size_t newLength, std::size_t capacity, std::size_t maxSize)
static void swap(void *a, void *b)
Definition bslma_allocatortraits.h:1089
BloombergLP::bslma::AllocatorTraits_ConstPointerType< ALLOCATOR >::type const_pointer
Definition bslma_allocatortraits.h:1183
BloombergLP::bslma::AllocatorTraits_PropOnCopyAssign< ALLOCATOR >::type propagate_on_container_copy_assignment
Definition bslma_allocatortraits.h:1332
BloombergLP::bslma::AllocatorTraits_SizeType< ALLOCATOR_TYPE >::type size_type
Definition bslma_allocatortraits.h:1196
BloombergLP::bslma::AllocatorTraits_PointerType< ALLOCATOR >::type pointer
Definition bslma_allocatortraits.h:1180
static void destroy(ALLOCATOR_TYPE &basicAllocator, ELEMENT_TYPE *elementAddr)
Definition bslma_allocatortraits.h:1549
BloombergLP::bslma::AllocatorTraits_DifferenceType< ALLOCATOR >::type difference_type
Definition bslma_allocatortraits.h:1193
Definition bslmf_enableif.h:530
Definition bslstl_ranges.h:301
Definition bslmf_isconvertible.h:875
Definition bslmf_isfundamental.h:330
Definition bslmf_issame.h:146
vector_UintPtrConversionIterator< TARGET *, ITERATOR > type
Definition bslstl_vector.h:852
Definition bslstl_vector.h:838
ITERATOR type
Definition bslstl_vector.h:841
Definition bslstl_vector.h:2690
vector_UintPtrConversionIterator< t_VALUE_TYPE, t_ITERATOR > iterator
Definition bslstl_vector.h:2692
t_ITERATOR d_begin
Definition bslstl_vector.h:2696
t_SENTINEL d_end
Definition bslstl_vector.h:2697
t_SENTINEL end() const
Definition bslstl_vector.h:2701
iterator begin() const
Definition bslstl_vector.h:2700
iterator const_iterator
Definition bslstl_vector.h:2693
Definition bslalg_hasstliterators.h:99
Definition bslma_usesbslmaallocator.h:344
Definition bslmf_isbitwisemoveable.h:718