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