1*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric
9*700637cbSDimitry Andric #ifndef _LIBCPP___VECTOR_VECTOR_H
10*700637cbSDimitry Andric #define _LIBCPP___VECTOR_VECTOR_H
11*700637cbSDimitry Andric
12*700637cbSDimitry Andric #include <__algorithm/copy.h>
13*700637cbSDimitry Andric #include <__algorithm/copy_n.h>
14*700637cbSDimitry Andric #include <__algorithm/fill_n.h>
15*700637cbSDimitry Andric #include <__algorithm/max.h>
16*700637cbSDimitry Andric #include <__algorithm/min.h>
17*700637cbSDimitry Andric #include <__algorithm/move.h>
18*700637cbSDimitry Andric #include <__algorithm/move_backward.h>
19*700637cbSDimitry Andric #include <__algorithm/ranges_copy_n.h>
20*700637cbSDimitry Andric #include <__algorithm/rotate.h>
21*700637cbSDimitry Andric #include <__assert>
22*700637cbSDimitry Andric #include <__config>
23*700637cbSDimitry Andric #include <__debug_utils/sanitizers.h>
24*700637cbSDimitry Andric #include <__format/enable_insertable.h>
25*700637cbSDimitry Andric #include <__fwd/vector.h>
26*700637cbSDimitry Andric #include <__iterator/advance.h>
27*700637cbSDimitry Andric #include <__iterator/bounded_iter.h>
28*700637cbSDimitry Andric #include <__iterator/concepts.h>
29*700637cbSDimitry Andric #include <__iterator/distance.h>
30*700637cbSDimitry Andric #include <__iterator/iterator_traits.h>
31*700637cbSDimitry Andric #include <__iterator/move_iterator.h>
32*700637cbSDimitry Andric #include <__iterator/next.h>
33*700637cbSDimitry Andric #include <__iterator/reverse_iterator.h>
34*700637cbSDimitry Andric #include <__iterator/wrap_iter.h>
35*700637cbSDimitry Andric #include <__memory/addressof.h>
36*700637cbSDimitry Andric #include <__memory/allocate_at_least.h>
37*700637cbSDimitry Andric #include <__memory/allocator.h>
38*700637cbSDimitry Andric #include <__memory/allocator_traits.h>
39*700637cbSDimitry Andric #include <__memory/compressed_pair.h>
40*700637cbSDimitry Andric #include <__memory/noexcept_move_assign_container.h>
41*700637cbSDimitry Andric #include <__memory/pointer_traits.h>
42*700637cbSDimitry Andric #include <__memory/swap_allocator.h>
43*700637cbSDimitry Andric #include <__memory/temp_value.h>
44*700637cbSDimitry Andric #include <__memory/uninitialized_algorithms.h>
45*700637cbSDimitry Andric #include <__ranges/access.h>
46*700637cbSDimitry Andric #include <__ranges/concepts.h>
47*700637cbSDimitry Andric #include <__ranges/container_compatible_range.h>
48*700637cbSDimitry Andric #include <__ranges/from_range.h>
49*700637cbSDimitry Andric #include <__split_buffer>
50*700637cbSDimitry Andric #include <__type_traits/conditional.h>
51*700637cbSDimitry Andric #include <__type_traits/enable_if.h>
52*700637cbSDimitry Andric #include <__type_traits/is_allocator.h>
53*700637cbSDimitry Andric #include <__type_traits/is_constant_evaluated.h>
54*700637cbSDimitry Andric #include <__type_traits/is_constructible.h>
55*700637cbSDimitry Andric #include <__type_traits/is_nothrow_assignable.h>
56*700637cbSDimitry Andric #include <__type_traits/is_nothrow_constructible.h>
57*700637cbSDimitry Andric #include <__type_traits/is_pointer.h>
58*700637cbSDimitry Andric #include <__type_traits/is_replaceable.h>
59*700637cbSDimitry Andric #include <__type_traits/is_same.h>
60*700637cbSDimitry Andric #include <__type_traits/is_trivially_relocatable.h>
61*700637cbSDimitry Andric #include <__type_traits/type_identity.h>
62*700637cbSDimitry Andric #include <__utility/declval.h>
63*700637cbSDimitry Andric #include <__utility/exception_guard.h>
64*700637cbSDimitry Andric #include <__utility/forward.h>
65*700637cbSDimitry Andric #include <__utility/is_pointer_in_range.h>
66*700637cbSDimitry Andric #include <__utility/move.h>
67*700637cbSDimitry Andric #include <__utility/pair.h>
68*700637cbSDimitry Andric #include <__utility/swap.h>
69*700637cbSDimitry Andric #include <initializer_list>
70*700637cbSDimitry Andric #include <limits>
71*700637cbSDimitry Andric #include <stdexcept>
72*700637cbSDimitry Andric
73*700637cbSDimitry Andric // These headers define parts of vectors definition, since they define ADL functions or class specializations.
74*700637cbSDimitry Andric #include <__vector/comparison.h>
75*700637cbSDimitry Andric #include <__vector/container_traits.h>
76*700637cbSDimitry Andric #include <__vector/swap.h>
77*700637cbSDimitry Andric
78*700637cbSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
79*700637cbSDimitry Andric # pragma GCC system_header
80*700637cbSDimitry Andric #endif
81*700637cbSDimitry Andric
82*700637cbSDimitry Andric _LIBCPP_PUSH_MACROS
83*700637cbSDimitry Andric #include <__undef_macros>
84*700637cbSDimitry Andric
85*700637cbSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
86*700637cbSDimitry Andric
87*700637cbSDimitry Andric template <class _Tp, class _Allocator /* = allocator<_Tp> */>
88*700637cbSDimitry Andric class vector {
89*700637cbSDimitry Andric public:
90*700637cbSDimitry Andric //
91*700637cbSDimitry Andric // Types
92*700637cbSDimitry Andric //
93*700637cbSDimitry Andric using __self _LIBCPP_NODEBUG = vector;
94*700637cbSDimitry Andric using value_type = _Tp;
95*700637cbSDimitry Andric using allocator_type = _Allocator;
96*700637cbSDimitry Andric using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
97*700637cbSDimitry Andric using reference = value_type&;
98*700637cbSDimitry Andric using const_reference = const value_type&;
99*700637cbSDimitry Andric using size_type = typename __alloc_traits::size_type;
100*700637cbSDimitry Andric using difference_type = typename __alloc_traits::difference_type;
101*700637cbSDimitry Andric using pointer = typename __alloc_traits::pointer;
102*700637cbSDimitry Andric using const_pointer = typename __alloc_traits::const_pointer;
103*700637cbSDimitry Andric #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
104*700637cbSDimitry Andric // Users might provide custom allocators, and prior to C++20 we have no existing way to detect whether the allocator's
105*700637cbSDimitry Andric // pointer type is contiguous (though it has to be by the Standard). Using the wrapper type ensures the iterator is
106*700637cbSDimitry Andric // considered contiguous.
107*700637cbSDimitry Andric using iterator = __bounded_iter<__wrap_iter<pointer> >;
108*700637cbSDimitry Andric using const_iterator = __bounded_iter<__wrap_iter<const_pointer> >;
109*700637cbSDimitry Andric #else
110*700637cbSDimitry Andric using iterator = __wrap_iter<pointer>;
111*700637cbSDimitry Andric using const_iterator = __wrap_iter<const_pointer>;
112*700637cbSDimitry Andric #endif
113*700637cbSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>;
114*700637cbSDimitry Andric using const_reverse_iterator = std::reverse_iterator<const_iterator>;
115*700637cbSDimitry Andric
116*700637cbSDimitry Andric // A vector containers the following members which may be trivially relocatable:
117*700637cbSDimitry Andric // - pointer: may be trivially relocatable, so it's checked
118*700637cbSDimitry Andric // - allocator_type: may be trivially relocatable, so it's checked
119*700637cbSDimitry Andric // vector doesn't contain any self-references, so it's trivially relocatable if its members are.
120*700637cbSDimitry Andric using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<
121*700637cbSDimitry Andric __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
122*700637cbSDimitry Andric vector,
123*700637cbSDimitry Andric void>;
124*700637cbSDimitry Andric using __replaceable _LIBCPP_NODEBUG =
125*700637cbSDimitry Andric __conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value,
126*700637cbSDimitry Andric vector,
127*700637cbSDimitry Andric void>;
128*700637cbSDimitry Andric
129*700637cbSDimitry Andric static_assert(__check_valid_allocator<allocator_type>::value, "");
130*700637cbSDimitry Andric static_assert(is_same<typename allocator_type::value_type, value_type>::value,
131*700637cbSDimitry Andric "Allocator::value_type must be same type as value_type");
132*700637cbSDimitry Andric
133*700637cbSDimitry Andric //
134*700637cbSDimitry Andric // [vector.cons], construct/copy/destroy
135*700637cbSDimitry Andric //
vector()136*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector()
137*700637cbSDimitry Andric _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) {}
vector(const allocator_type & __a)138*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(const allocator_type& __a)
139*700637cbSDimitry Andric #if _LIBCPP_STD_VER <= 14
140*700637cbSDimitry Andric _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
141*700637cbSDimitry Andric #else
142*700637cbSDimitry Andric noexcept
143*700637cbSDimitry Andric #endif
144*700637cbSDimitry Andric : __alloc_(__a) {
145*700637cbSDimitry Andric }
146*700637cbSDimitry Andric
vector(size_type __n)147*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n) {
148*700637cbSDimitry Andric auto __guard = std::__make_exception_guard(__destroy_vector(*this));
149*700637cbSDimitry Andric if (__n > 0) {
150*700637cbSDimitry Andric __vallocate(__n);
151*700637cbSDimitry Andric __construct_at_end(__n);
152*700637cbSDimitry Andric }
153*700637cbSDimitry Andric __guard.__complete();
154*700637cbSDimitry Andric }
155*700637cbSDimitry Andric
156*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 14
vector(size_type __n,const allocator_type & __a)157*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n, const allocator_type& __a)
158*700637cbSDimitry Andric : __alloc_(__a) {
159*700637cbSDimitry Andric auto __guard = std::__make_exception_guard(__destroy_vector(*this));
160*700637cbSDimitry Andric if (__n > 0) {
161*700637cbSDimitry Andric __vallocate(__n);
162*700637cbSDimitry Andric __construct_at_end(__n);
163*700637cbSDimitry Andric }
164*700637cbSDimitry Andric __guard.__complete();
165*700637cbSDimitry Andric }
166*700637cbSDimitry Andric #endif
167*700637cbSDimitry Andric
vector(size_type __n,const value_type & __x)168*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(size_type __n, const value_type& __x) {
169*700637cbSDimitry Andric auto __guard = std::__make_exception_guard(__destroy_vector(*this));
170*700637cbSDimitry Andric if (__n > 0) {
171*700637cbSDimitry Andric __vallocate(__n);
172*700637cbSDimitry Andric __construct_at_end(__n, __x);
173*700637cbSDimitry Andric }
174*700637cbSDimitry Andric __guard.__complete();
175*700637cbSDimitry Andric }
176*700637cbSDimitry Andric
177*700637cbSDimitry Andric template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
178*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
vector(size_type __n,const value_type & __x,const allocator_type & __a)179*700637cbSDimitry Andric vector(size_type __n, const value_type& __x, const allocator_type& __a)
180*700637cbSDimitry Andric : __alloc_(__a) {
181*700637cbSDimitry Andric auto __guard = std::__make_exception_guard(__destroy_vector(*this));
182*700637cbSDimitry Andric if (__n > 0) {
183*700637cbSDimitry Andric __vallocate(__n);
184*700637cbSDimitry Andric __construct_at_end(__n, __x);
185*700637cbSDimitry Andric }
186*700637cbSDimitry Andric __guard.__complete();
187*700637cbSDimitry Andric }
188*700637cbSDimitry Andric
189*700637cbSDimitry Andric template <class _InputIterator,
190*700637cbSDimitry Andric __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
191*700637cbSDimitry Andric is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value,
192*700637cbSDimitry Andric int> = 0>
vector(_InputIterator __first,_InputIterator __last)193*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(_InputIterator __first, _InputIterator __last) {
194*700637cbSDimitry Andric __init_with_sentinel(__first, __last);
195*700637cbSDimitry Andric }
196*700637cbSDimitry Andric
197*700637cbSDimitry Andric template <class _InputIterator,
198*700637cbSDimitry Andric __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
199*700637cbSDimitry Andric is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value,
200*700637cbSDimitry Andric int> = 0>
201*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
vector(_InputIterator __first,_InputIterator __last,const allocator_type & __a)202*700637cbSDimitry Andric vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
203*700637cbSDimitry Andric : __alloc_(__a) {
204*700637cbSDimitry Andric __init_with_sentinel(__first, __last);
205*700637cbSDimitry Andric }
206*700637cbSDimitry Andric
207*700637cbSDimitry Andric template <
208*700637cbSDimitry Andric class _ForwardIterator,
209*700637cbSDimitry Andric __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
210*700637cbSDimitry Andric is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
211*700637cbSDimitry Andric int> = 0>
vector(_ForwardIterator __first,_ForwardIterator __last)212*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(_ForwardIterator __first, _ForwardIterator __last) {
213*700637cbSDimitry Andric size_type __n = static_cast<size_type>(std::distance(__first, __last));
214*700637cbSDimitry Andric __init_with_size(__first, __last, __n);
215*700637cbSDimitry Andric }
216*700637cbSDimitry Andric
217*700637cbSDimitry Andric template <
218*700637cbSDimitry Andric class _ForwardIterator,
219*700637cbSDimitry Andric __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
220*700637cbSDimitry Andric is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
221*700637cbSDimitry Andric int> = 0>
222*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
vector(_ForwardIterator __first,_ForwardIterator __last,const allocator_type & __a)223*700637cbSDimitry Andric vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a)
224*700637cbSDimitry Andric : __alloc_(__a) {
225*700637cbSDimitry Andric size_type __n = static_cast<size_type>(std::distance(__first, __last));
226*700637cbSDimitry Andric __init_with_size(__first, __last, __n);
227*700637cbSDimitry Andric }
228*700637cbSDimitry Andric
229*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 23
230*700637cbSDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range>
231*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr vector(
232*700637cbSDimitry Andric from_range_t, _Range&& __range, const allocator_type& __alloc = allocator_type())
__alloc_(__alloc)233*700637cbSDimitry Andric : __alloc_(__alloc) {
234*700637cbSDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
235*700637cbSDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range));
236*700637cbSDimitry Andric __init_with_size(ranges::begin(__range), ranges::end(__range), __n);
237*700637cbSDimitry Andric
238*700637cbSDimitry Andric } else {
239*700637cbSDimitry Andric __init_with_sentinel(ranges::begin(__range), ranges::end(__range));
240*700637cbSDimitry Andric }
241*700637cbSDimitry Andric }
242*700637cbSDimitry Andric #endif
243*700637cbSDimitry Andric
244*700637cbSDimitry Andric private:
245*700637cbSDimitry Andric class __destroy_vector {
246*700637cbSDimitry Andric public:
__destroy_vector(vector & __vec)247*700637cbSDimitry Andric _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __destroy_vector(vector& __vec) : __vec_(__vec) {}
248*700637cbSDimitry Andric
operator()249*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() {
250*700637cbSDimitry Andric if (__vec_.__begin_ != nullptr) {
251*700637cbSDimitry Andric __vec_.clear();
252*700637cbSDimitry Andric __vec_.__annotate_delete();
253*700637cbSDimitry Andric __alloc_traits::deallocate(__vec_.__alloc_, __vec_.__begin_, __vec_.capacity());
254*700637cbSDimitry Andric }
255*700637cbSDimitry Andric }
256*700637cbSDimitry Andric
257*700637cbSDimitry Andric private:
258*700637cbSDimitry Andric vector& __vec_;
259*700637cbSDimitry Andric };
260*700637cbSDimitry Andric
261*700637cbSDimitry Andric public:
~vector()262*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~vector() { __destroy_vector (*this)(); }
263*700637cbSDimitry Andric
vector(const vector & __x)264*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(const vector& __x)
265*700637cbSDimitry Andric : __alloc_(__alloc_traits::select_on_container_copy_construction(__x.__alloc_)) {
266*700637cbSDimitry Andric __init_with_size(__x.__begin_, __x.__end_, __x.size());
267*700637cbSDimitry Andric }
268*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
vector(const vector & __x,const __type_identity_t<allocator_type> & __a)269*700637cbSDimitry Andric vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
270*700637cbSDimitry Andric : __alloc_(__a) {
271*700637cbSDimitry Andric __init_with_size(__x.__begin_, __x.__end_, __x.size());
272*700637cbSDimitry Andric }
273*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector& operator=(const vector& __x);
274*700637cbSDimitry Andric
275*700637cbSDimitry Andric #ifndef _LIBCPP_CXX03_LANG
vector(initializer_list<value_type> __il)276*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(initializer_list<value_type> __il) {
277*700637cbSDimitry Andric __init_with_size(__il.begin(), __il.end(), __il.size());
278*700637cbSDimitry Andric }
279*700637cbSDimitry Andric
280*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
vector(initializer_list<value_type> __il,const allocator_type & __a)281*700637cbSDimitry Andric vector(initializer_list<value_type> __il, const allocator_type& __a)
282*700637cbSDimitry Andric : __alloc_(__a) {
283*700637cbSDimitry Andric __init_with_size(__il.begin(), __il.end(), __il.size());
284*700637cbSDimitry Andric }
285*700637cbSDimitry Andric
286*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector& operator=(initializer_list<value_type> __il) {
287*700637cbSDimitry Andric assign(__il.begin(), __il.end());
288*700637cbSDimitry Andric return *this;
289*700637cbSDimitry Andric }
290*700637cbSDimitry Andric #endif // !_LIBCPP_CXX03_LANG
291*700637cbSDimitry Andric
292*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(vector&& __x)
293*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 17
294*700637cbSDimitry Andric noexcept;
295*700637cbSDimitry Andric #else
296*700637cbSDimitry Andric _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
297*700637cbSDimitry Andric #endif
298*700637cbSDimitry Andric
299*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
300*700637cbSDimitry Andric vector(vector&& __x, const __type_identity_t<allocator_type>& __a);
301*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector& operator=(vector&& __x)
_NOEXCEPT_(__noexcept_move_assign_container<_Allocator,__alloc_traits>::value)302*700637cbSDimitry Andric _NOEXCEPT_(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value) {
303*700637cbSDimitry Andric __move_assign(__x, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
304*700637cbSDimitry Andric return *this;
305*700637cbSDimitry Andric }
306*700637cbSDimitry Andric
307*700637cbSDimitry Andric template <class _InputIterator,
308*700637cbSDimitry Andric __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
309*700637cbSDimitry Andric is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value,
310*700637cbSDimitry Andric int> = 0>
assign(_InputIterator __first,_InputIterator __last)311*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_InputIterator __first, _InputIterator __last) {
312*700637cbSDimitry Andric __assign_with_sentinel(__first, __last);
313*700637cbSDimitry Andric }
314*700637cbSDimitry Andric template <
315*700637cbSDimitry Andric class _ForwardIterator,
316*700637cbSDimitry Andric __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
317*700637cbSDimitry Andric is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
318*700637cbSDimitry Andric int> = 0>
assign(_ForwardIterator __first,_ForwardIterator __last)319*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_ForwardIterator __first, _ForwardIterator __last) {
320*700637cbSDimitry Andric __assign_with_size(__first, __last, std::distance(__first, __last));
321*700637cbSDimitry Andric }
322*700637cbSDimitry Andric
323*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 23
324*700637cbSDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range>
assign_range(_Range && __range)325*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void assign_range(_Range&& __range) {
326*700637cbSDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
327*700637cbSDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range));
328*700637cbSDimitry Andric __assign_with_size(ranges::begin(__range), ranges::end(__range), __n);
329*700637cbSDimitry Andric
330*700637cbSDimitry Andric } else {
331*700637cbSDimitry Andric __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
332*700637cbSDimitry Andric }
333*700637cbSDimitry Andric }
334*700637cbSDimitry Andric #endif
335*700637cbSDimitry Andric
336*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const_reference __u);
337*700637cbSDimitry Andric
338*700637cbSDimitry Andric #ifndef _LIBCPP_CXX03_LANG
assign(initializer_list<value_type> __il)339*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il) {
340*700637cbSDimitry Andric assign(__il.begin(), __il.end());
341*700637cbSDimitry Andric }
342*700637cbSDimitry Andric #endif
343*700637cbSDimitry Andric
get_allocator()344*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
345*700637cbSDimitry Andric return this->__alloc_;
346*700637cbSDimitry Andric }
347*700637cbSDimitry Andric
348*700637cbSDimitry Andric //
349*700637cbSDimitry Andric // Iterators
350*700637cbSDimitry Andric //
begin()351*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
352*700637cbSDimitry Andric return __make_iter(__add_alignment_assumption(this->__begin_));
353*700637cbSDimitry Andric }
begin()354*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
355*700637cbSDimitry Andric return __make_iter(__add_alignment_assumption(this->__begin_));
356*700637cbSDimitry Andric }
end()357*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
358*700637cbSDimitry Andric return __make_iter(__add_alignment_assumption(this->__end_));
359*700637cbSDimitry Andric }
end()360*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
361*700637cbSDimitry Andric return __make_iter(__add_alignment_assumption(this->__end_));
362*700637cbSDimitry Andric }
363*700637cbSDimitry Andric
rbegin()364*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT {
365*700637cbSDimitry Andric return reverse_iterator(end());
366*700637cbSDimitry Andric }
rbegin()367*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
368*700637cbSDimitry Andric return const_reverse_iterator(end());
369*700637cbSDimitry Andric }
rend()370*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT {
371*700637cbSDimitry Andric return reverse_iterator(begin());
372*700637cbSDimitry Andric }
rend()373*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
374*700637cbSDimitry Andric return const_reverse_iterator(begin());
375*700637cbSDimitry Andric }
376*700637cbSDimitry Andric
cbegin()377*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
cend()378*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
crbegin()379*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {
380*700637cbSDimitry Andric return rbegin();
381*700637cbSDimitry Andric }
crend()382*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
383*700637cbSDimitry Andric
384*700637cbSDimitry Andric //
385*700637cbSDimitry Andric // [vector.capacity], capacity
386*700637cbSDimitry Andric //
size()387*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
388*700637cbSDimitry Andric return static_cast<size_type>(this->__end_ - this->__begin_);
389*700637cbSDimitry Andric }
capacity()390*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
391*700637cbSDimitry Andric return static_cast<size_type>(this->__cap_ - this->__begin_);
392*700637cbSDimitry Andric }
empty()393*700637cbSDimitry Andric [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
394*700637cbSDimitry Andric return this->__begin_ == this->__end_;
395*700637cbSDimitry Andric }
max_size()396*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
397*700637cbSDimitry Andric return std::min<size_type>(__alloc_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max());
398*700637cbSDimitry Andric }
399*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
400*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
401*700637cbSDimitry Andric
402*700637cbSDimitry Andric //
403*700637cbSDimitry Andric // element access
404*700637cbSDimitry Andric //
405*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __n) _NOEXCEPT {
406*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
407*700637cbSDimitry Andric return this->__begin_[__n];
408*700637cbSDimitry Andric }
409*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __n) const _NOEXCEPT {
410*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
411*700637cbSDimitry Andric return this->__begin_[__n];
412*700637cbSDimitry Andric }
at(size_type __n)413*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference at(size_type __n) {
414*700637cbSDimitry Andric if (__n >= size())
415*700637cbSDimitry Andric this->__throw_out_of_range();
416*700637cbSDimitry Andric return this->__begin_[__n];
417*700637cbSDimitry Andric }
at(size_type __n)418*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const {
419*700637cbSDimitry Andric if (__n >= size())
420*700637cbSDimitry Andric this->__throw_out_of_range();
421*700637cbSDimitry Andric return this->__begin_[__n];
422*700637cbSDimitry Andric }
423*700637cbSDimitry Andric
front()424*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT {
425*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
426*700637cbSDimitry Andric return *this->__begin_;
427*700637cbSDimitry Andric }
front()428*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
429*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
430*700637cbSDimitry Andric return *this->__begin_;
431*700637cbSDimitry Andric }
back()432*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
433*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
434*700637cbSDimitry Andric return *(this->__end_ - 1);
435*700637cbSDimitry Andric }
back()436*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
437*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
438*700637cbSDimitry Andric return *(this->__end_ - 1);
439*700637cbSDimitry Andric }
440*700637cbSDimitry Andric
441*700637cbSDimitry Andric //
442*700637cbSDimitry Andric // [vector.data], data access
443*700637cbSDimitry Andric //
data()444*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI value_type* data() _NOEXCEPT {
445*700637cbSDimitry Andric return std::__to_address(this->__begin_);
446*700637cbSDimitry Andric }
447*700637cbSDimitry Andric
data()448*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT {
449*700637cbSDimitry Andric return std::__to_address(this->__begin_);
450*700637cbSDimitry Andric }
451*700637cbSDimitry Andric
452*700637cbSDimitry Andric //
453*700637cbSDimitry Andric // [vector.modifiers], modifiers
454*700637cbSDimitry Andric //
push_back(const_reference __x)455*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x) { emplace_back(__x); }
456*700637cbSDimitry Andric
push_back(value_type && __x)457*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x) { emplace_back(std::move(__x)); }
458*700637cbSDimitry Andric
459*700637cbSDimitry Andric template <class... _Args>
460*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
461*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 17
462*700637cbSDimitry Andric reference
463*700637cbSDimitry Andric emplace_back(_Args&&... __args);
464*700637cbSDimitry Andric #else
465*700637cbSDimitry Andric void
466*700637cbSDimitry Andric emplace_back(_Args&&... __args);
467*700637cbSDimitry Andric #endif
468*700637cbSDimitry Andric
469*700637cbSDimitry Andric template <class... _Args>
__emplace_back_assume_capacity(_Args &&...__args)470*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __emplace_back_assume_capacity(_Args&&... __args) {
471*700637cbSDimitry Andric _LIBCPP_ASSERT_INTERNAL(
472*700637cbSDimitry Andric size() < capacity(), "We assume that we have enough space to insert an element at the end of the vector");
473*700637cbSDimitry Andric _ConstructTransaction __tx(*this, 1);
474*700637cbSDimitry Andric __alloc_traits::construct(this->__alloc_, std::__to_address(__tx.__pos_), std::forward<_Args>(__args)...);
475*700637cbSDimitry Andric ++__tx.__pos_;
476*700637cbSDimitry Andric }
477*700637cbSDimitry Andric
478*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 23
479*700637cbSDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range>
append_range(_Range && __range)480*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void append_range(_Range&& __range) {
481*700637cbSDimitry Andric insert_range(end(), std::forward<_Range>(__range));
482*700637cbSDimitry Andric }
483*700637cbSDimitry Andric #endif
484*700637cbSDimitry Andric
pop_back()485*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() {
486*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector::pop_back called on an empty vector");
487*700637cbSDimitry Andric this->__destruct_at_end(this->__end_ - 1);
488*700637cbSDimitry Andric }
489*700637cbSDimitry Andric
490*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __position, const_reference __x);
491*700637cbSDimitry Andric
492*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __position, value_type&& __x);
493*700637cbSDimitry Andric template <class... _Args>
494*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __position, _Args&&... __args);
495*700637cbSDimitry Andric
496*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
497*700637cbSDimitry Andric insert(const_iterator __position, size_type __n, const_reference __x);
498*700637cbSDimitry Andric
499*700637cbSDimitry Andric template <class _InputIterator,
500*700637cbSDimitry Andric __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
501*700637cbSDimitry Andric is_constructible< value_type, typename iterator_traits<_InputIterator>::reference>::value,
502*700637cbSDimitry Andric int> = 0>
503*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
insert(const_iterator __position,_InputIterator __first,_InputIterator __last)504*700637cbSDimitry Andric insert(const_iterator __position, _InputIterator __first, _InputIterator __last) {
505*700637cbSDimitry Andric return __insert_with_sentinel(__position, __first, __last);
506*700637cbSDimitry Andric }
507*700637cbSDimitry Andric
508*700637cbSDimitry Andric template <
509*700637cbSDimitry Andric class _ForwardIterator,
510*700637cbSDimitry Andric __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
511*700637cbSDimitry Andric is_constructible< value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
512*700637cbSDimitry Andric int> = 0>
513*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
insert(const_iterator __position,_ForwardIterator __first,_ForwardIterator __last)514*700637cbSDimitry Andric insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) {
515*700637cbSDimitry Andric return __insert_with_size(__position, __first, __last, std::distance(__first, __last));
516*700637cbSDimitry Andric }
517*700637cbSDimitry Andric
518*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 23
519*700637cbSDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range>
insert_range(const_iterator __position,_Range && __range)520*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator insert_range(const_iterator __position, _Range&& __range) {
521*700637cbSDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
522*700637cbSDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range));
523*700637cbSDimitry Andric return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n);
524*700637cbSDimitry Andric
525*700637cbSDimitry Andric } else {
526*700637cbSDimitry Andric return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
527*700637cbSDimitry Andric }
528*700637cbSDimitry Andric }
529*700637cbSDimitry Andric #endif
530*700637cbSDimitry Andric
531*700637cbSDimitry Andric #ifndef _LIBCPP_CXX03_LANG
532*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
insert(const_iterator __position,initializer_list<value_type> __il)533*700637cbSDimitry Andric insert(const_iterator __position, initializer_list<value_type> __il) {
534*700637cbSDimitry Andric return insert(__position, __il.begin(), __il.end());
535*700637cbSDimitry Andric }
536*700637cbSDimitry Andric #endif
537*700637cbSDimitry Andric
538*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position);
539*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last);
540*700637cbSDimitry Andric
clear()541*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
542*700637cbSDimitry Andric size_type __old_size = size();
543*700637cbSDimitry Andric __base_destruct_at_end(this->__begin_);
544*700637cbSDimitry Andric __annotate_shrink(__old_size);
545*700637cbSDimitry Andric }
546*700637cbSDimitry Andric
547*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz);
548*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz, const_reference __x);
549*700637cbSDimitry Andric
550*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(vector&)
551*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 14
552*700637cbSDimitry Andric _NOEXCEPT;
553*700637cbSDimitry Andric #else
554*700637cbSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
555*700637cbSDimitry Andric #endif
556*700637cbSDimitry Andric
557*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
558*700637cbSDimitry Andric
559*700637cbSDimitry Andric private:
560*700637cbSDimitry Andric pointer __begin_ = nullptr;
561*700637cbSDimitry Andric pointer __end_ = nullptr;
562*700637cbSDimitry Andric _LIBCPP_COMPRESSED_PAIR(pointer, __cap_ = nullptr, allocator_type, __alloc_);
563*700637cbSDimitry Andric
564*700637cbSDimitry Andric // Allocate space for __n objects
565*700637cbSDimitry Andric // throws length_error if __n > max_size()
566*700637cbSDimitry Andric // throws (probably bad_alloc) if memory run out
567*700637cbSDimitry Andric // Precondition: __begin_ == __end_ == __cap_ == nullptr
568*700637cbSDimitry Andric // Precondition: __n > 0
569*700637cbSDimitry Andric // Postcondition: capacity() >= __n
570*700637cbSDimitry Andric // Postcondition: size() == 0
__vallocate(size_type __n)571*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __vallocate(size_type __n) {
572*700637cbSDimitry Andric if (__n > max_size())
573*700637cbSDimitry Andric this->__throw_length_error();
574*700637cbSDimitry Andric auto __allocation = std::__allocate_at_least(this->__alloc_, __n);
575*700637cbSDimitry Andric __begin_ = __allocation.ptr;
576*700637cbSDimitry Andric __end_ = __allocation.ptr;
577*700637cbSDimitry Andric __cap_ = __begin_ + __allocation.count;
578*700637cbSDimitry Andric __annotate_new(0);
579*700637cbSDimitry Andric }
580*700637cbSDimitry Andric
581*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __vdeallocate() _NOEXCEPT;
582*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __recommend(size_type __new_size) const;
583*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n);
584*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x);
585*700637cbSDimitry Andric
586*700637cbSDimitry Andric template <class _InputIterator, class _Sentinel>
587*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__init_with_size(_InputIterator __first,_Sentinel __last,size_type __n)588*700637cbSDimitry Andric __init_with_size(_InputIterator __first, _Sentinel __last, size_type __n) {
589*700637cbSDimitry Andric auto __guard = std::__make_exception_guard(__destroy_vector(*this));
590*700637cbSDimitry Andric
591*700637cbSDimitry Andric if (__n > 0) {
592*700637cbSDimitry Andric __vallocate(__n);
593*700637cbSDimitry Andric __construct_at_end(std::move(__first), std::move(__last), __n);
594*700637cbSDimitry Andric }
595*700637cbSDimitry Andric
596*700637cbSDimitry Andric __guard.__complete();
597*700637cbSDimitry Andric }
598*700637cbSDimitry Andric
599*700637cbSDimitry Andric template <class _InputIterator, class _Sentinel>
600*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__init_with_sentinel(_InputIterator __first,_Sentinel __last)601*700637cbSDimitry Andric __init_with_sentinel(_InputIterator __first, _Sentinel __last) {
602*700637cbSDimitry Andric auto __guard = std::__make_exception_guard(__destroy_vector(*this));
603*700637cbSDimitry Andric
604*700637cbSDimitry Andric for (; __first != __last; ++__first)
605*700637cbSDimitry Andric emplace_back(*__first);
606*700637cbSDimitry Andric
607*700637cbSDimitry Andric __guard.__complete();
608*700637cbSDimitry Andric }
609*700637cbSDimitry Andric
610*700637cbSDimitry Andric template <class _Iterator, class _Sentinel>
611*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __first, _Sentinel __last);
612*700637cbSDimitry Andric
613*700637cbSDimitry Andric // The `_Iterator` in `*_with_size` functions can be input-only only if called from `*_range` (since C++23).
614*700637cbSDimitry Andric // Otherwise, `_Iterator` is a forward iterator.
615*700637cbSDimitry Andric
616*700637cbSDimitry Andric template <class _Iterator, class _Sentinel>
617*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
618*700637cbSDimitry Andric __assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n);
619*700637cbSDimitry Andric
620*700637cbSDimitry Andric template <class _Iterator,
621*700637cbSDimitry Andric __enable_if_t<!is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0>
622*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__insert_assign_n_unchecked(_Iterator __first,difference_type __n,pointer __position)623*700637cbSDimitry Andric __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
624*700637cbSDimitry Andric for (pointer __end_position = __position + __n; __position != __end_position; ++__position, (void)++__first) {
625*700637cbSDimitry Andric __temp_value<value_type, _Allocator> __tmp(this->__alloc_, *__first);
626*700637cbSDimitry Andric *__position = std::move(__tmp.get());
627*700637cbSDimitry Andric }
628*700637cbSDimitry Andric }
629*700637cbSDimitry Andric
630*700637cbSDimitry Andric template <class _Iterator,
631*700637cbSDimitry Andric __enable_if_t<is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0>
632*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__insert_assign_n_unchecked(_Iterator __first,difference_type __n,pointer __position)633*700637cbSDimitry Andric __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
634*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 23
635*700637cbSDimitry Andric if constexpr (!forward_iterator<_Iterator>) { // Handles input-only sized ranges for insert_range
636*700637cbSDimitry Andric ranges::copy_n(std::move(__first), __n, __position);
637*700637cbSDimitry Andric } else
638*700637cbSDimitry Andric #endif
639*700637cbSDimitry Andric {
640*700637cbSDimitry Andric std::copy_n(__first, __n, __position);
641*700637cbSDimitry Andric }
642*700637cbSDimitry Andric }
643*700637cbSDimitry Andric
644*700637cbSDimitry Andric template <class _InputIterator, class _Sentinel>
645*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
646*700637cbSDimitry Andric __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last);
647*700637cbSDimitry Andric
648*700637cbSDimitry Andric template <class _Iterator, class _Sentinel>
649*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
650*700637cbSDimitry Andric __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n);
651*700637cbSDimitry Andric
652*700637cbSDimitry Andric template <class _InputIterator, class _Sentinel>
653*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
654*700637cbSDimitry Andric __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
655*700637cbSDimitry Andric
656*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
657*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x);
658*700637cbSDimitry Andric
__make_iter(pointer __p)659*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator __make_iter(pointer __p) _NOEXCEPT {
660*700637cbSDimitry Andric #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
661*700637cbSDimitry Andric // Bound the iterator according to the capacity, rather than the size.
662*700637cbSDimitry Andric //
663*700637cbSDimitry Andric // Vector guarantees that iterators stay valid as long as no reallocation occurs even if new elements are inserted
664*700637cbSDimitry Andric // into the container; for these cases, we need to make sure that the newly-inserted elements can be accessed
665*700637cbSDimitry Andric // through the bounded iterator without failing checks. The downside is that the bounded iterator won't catch
666*700637cbSDimitry Andric // access that is logically out-of-bounds, i.e., goes beyond the size, but is still within the capacity. With the
667*700637cbSDimitry Andric // current implementation, there is no connection between a bounded iterator and its associated container, so we
668*700637cbSDimitry Andric // don't have a way to update existing valid iterators when the container is resized and thus have to go with
669*700637cbSDimitry Andric // a laxer approach.
670*700637cbSDimitry Andric return std::__make_bounded_iter(
671*700637cbSDimitry Andric std::__wrap_iter<pointer>(__p),
672*700637cbSDimitry Andric std::__wrap_iter<pointer>(this->__begin_),
673*700637cbSDimitry Andric std::__wrap_iter<pointer>(this->__cap_));
674*700637cbSDimitry Andric #else
675*700637cbSDimitry Andric return iterator(__p);
676*700637cbSDimitry Andric #endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
677*700637cbSDimitry Andric }
678*700637cbSDimitry Andric
__make_iter(const_pointer __p)679*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator __make_iter(const_pointer __p) const _NOEXCEPT {
680*700637cbSDimitry Andric #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
681*700637cbSDimitry Andric // Bound the iterator according to the capacity, rather than the size.
682*700637cbSDimitry Andric return std::__make_bounded_iter(
683*700637cbSDimitry Andric std::__wrap_iter<const_pointer>(__p),
684*700637cbSDimitry Andric std::__wrap_iter<const_pointer>(this->__begin_),
685*700637cbSDimitry Andric std::__wrap_iter<const_pointer>(this->__cap_));
686*700637cbSDimitry Andric #else
687*700637cbSDimitry Andric return const_iterator(__p);
688*700637cbSDimitry Andric #endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
689*700637cbSDimitry Andric }
690*700637cbSDimitry Andric
691*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
692*700637cbSDimitry Andric __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v);
693*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer
694*700637cbSDimitry Andric __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p);
695*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
696*700637cbSDimitry Andric __move_range(pointer __from_s, pointer __from_e, pointer __to);
697*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, true_type)
698*700637cbSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
699*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, false_type)
700*700637cbSDimitry Andric _NOEXCEPT_(__alloc_traits::is_always_equal::value);
__destruct_at_end(pointer __new_last)701*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last) _NOEXCEPT {
702*700637cbSDimitry Andric size_type __old_size = size();
703*700637cbSDimitry Andric __base_destruct_at_end(__new_last);
704*700637cbSDimitry Andric __annotate_shrink(__old_size);
705*700637cbSDimitry Andric }
706*700637cbSDimitry Andric
707*700637cbSDimitry Andric template <class... _Args>
708*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI inline pointer __emplace_back_slow_path(_Args&&... __args);
709*700637cbSDimitry Andric
710*700637cbSDimitry Andric // The following functions are no-ops outside of AddressSanitizer mode.
711*700637cbSDimitry Andric // We call annotations for every allocator, unless explicitly disabled.
712*700637cbSDimitry Andric //
713*700637cbSDimitry Andric // To disable annotations for a particular allocator, change value of
714*700637cbSDimitry Andric // __asan_annotate_container_with_allocator to false.
715*700637cbSDimitry Andric // For more details, see the "Using libc++" documentation page or
716*700637cbSDimitry Andric // the documentation for __sanitizer_annotate_contiguous_container.
717*700637cbSDimitry Andric
718*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__annotate_contiguous_container(const void * __old_mid,const void * __new_mid)719*700637cbSDimitry Andric __annotate_contiguous_container(const void* __old_mid, const void* __new_mid) const {
720*700637cbSDimitry Andric std::__annotate_contiguous_container<_Allocator>(data(), data() + capacity(), __old_mid, __new_mid);
721*700637cbSDimitry Andric }
722*700637cbSDimitry Andric
__annotate_new(size_type __current_size)723*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_new(size_type __current_size) const _NOEXCEPT {
724*700637cbSDimitry Andric __annotate_contiguous_container(data() + capacity(), data() + __current_size);
725*700637cbSDimitry Andric }
726*700637cbSDimitry Andric
__annotate_delete()727*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_delete() const _NOEXCEPT {
728*700637cbSDimitry Andric __annotate_contiguous_container(data() + size(), data() + capacity());
729*700637cbSDimitry Andric }
730*700637cbSDimitry Andric
__annotate_increase(size_type __n)731*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_increase(size_type __n) const _NOEXCEPT {
732*700637cbSDimitry Andric __annotate_contiguous_container(data() + size(), data() + size() + __n);
733*700637cbSDimitry Andric }
734*700637cbSDimitry Andric
__annotate_shrink(size_type __old_size)735*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_shrink(size_type __old_size) const _NOEXCEPT {
736*700637cbSDimitry Andric __annotate_contiguous_container(data() + __old_size, data() + size());
737*700637cbSDimitry Andric }
738*700637cbSDimitry Andric
739*700637cbSDimitry Andric struct _ConstructTransaction {
_ConstructTransaction_ConstructTransaction740*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(vector& __v, size_type __n)
741*700637cbSDimitry Andric : __v_(__v), __pos_(__v.__end_), __new_end_(__v.__end_ + __n) {
742*700637cbSDimitry Andric __v_.__annotate_increase(__n);
743*700637cbSDimitry Andric }
744*700637cbSDimitry Andric
~_ConstructTransaction_ConstructTransaction745*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() {
746*700637cbSDimitry Andric __v_.__end_ = __pos_;
747*700637cbSDimitry Andric if (__pos_ != __new_end_) {
748*700637cbSDimitry Andric __v_.__annotate_shrink(__new_end_ - __v_.__begin_);
749*700637cbSDimitry Andric }
750*700637cbSDimitry Andric }
751*700637cbSDimitry Andric
752*700637cbSDimitry Andric vector& __v_;
753*700637cbSDimitry Andric pointer __pos_;
754*700637cbSDimitry Andric const_pointer const __new_end_;
755*700637cbSDimitry Andric
756*700637cbSDimitry Andric _ConstructTransaction(_ConstructTransaction const&) = delete;
757*700637cbSDimitry Andric _ConstructTransaction& operator=(_ConstructTransaction const&) = delete;
758*700637cbSDimitry Andric };
759*700637cbSDimitry Andric
__base_destruct_at_end(pointer __new_last)760*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __base_destruct_at_end(pointer __new_last) _NOEXCEPT {
761*700637cbSDimitry Andric pointer __soon_to_be_end = this->__end_;
762*700637cbSDimitry Andric while (__new_last != __soon_to_be_end)
763*700637cbSDimitry Andric __alloc_traits::destroy(this->__alloc_, std::__to_address(--__soon_to_be_end));
764*700637cbSDimitry Andric this->__end_ = __new_last;
765*700637cbSDimitry Andric }
766*700637cbSDimitry Andric
__copy_assign_alloc(const vector & __c)767*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector& __c) {
768*700637cbSDimitry Andric __copy_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>());
769*700637cbSDimitry Andric }
770*700637cbSDimitry Andric
__move_assign_alloc(vector & __c)771*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c)
772*700637cbSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
773*700637cbSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) {
774*700637cbSDimitry Andric __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
775*700637cbSDimitry Andric }
776*700637cbSDimitry Andric
__throw_length_error()777*700637cbSDimitry Andric [[__noreturn__]] _LIBCPP_HIDE_FROM_ABI static void __throw_length_error() { std::__throw_length_error("vector"); }
778*700637cbSDimitry Andric
__throw_out_of_range()779*700637cbSDimitry Andric [[__noreturn__]] _LIBCPP_HIDE_FROM_ABI static void __throw_out_of_range() { std::__throw_out_of_range("vector"); }
780*700637cbSDimitry Andric
__copy_assign_alloc(const vector & __c,true_type)781*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector& __c, true_type) {
782*700637cbSDimitry Andric if (this->__alloc_ != __c.__alloc_) {
783*700637cbSDimitry Andric clear();
784*700637cbSDimitry Andric __annotate_delete();
785*700637cbSDimitry Andric __alloc_traits::deallocate(this->__alloc_, this->__begin_, capacity());
786*700637cbSDimitry Andric this->__begin_ = this->__end_ = this->__cap_ = nullptr;
787*700637cbSDimitry Andric }
788*700637cbSDimitry Andric this->__alloc_ = __c.__alloc_;
789*700637cbSDimitry Andric }
790*700637cbSDimitry Andric
__copy_assign_alloc(const vector &,false_type)791*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector&, false_type) {}
792*700637cbSDimitry Andric
__move_assign_alloc(vector & __c,true_type)793*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c, true_type)
794*700637cbSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
795*700637cbSDimitry Andric this->__alloc_ = std::move(__c.__alloc_);
796*700637cbSDimitry Andric }
797*700637cbSDimitry Andric
__move_assign_alloc(vector &,false_type)798*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector&, false_type) _NOEXCEPT {}
799*700637cbSDimitry Andric
800*700637cbSDimitry Andric template <class _Ptr = pointer, __enable_if_t<is_pointer<_Ptr>::value, int> = 0>
801*700637cbSDimitry Andric static _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI pointer
__add_alignment_assumption(_Ptr __p)802*700637cbSDimitry Andric __add_alignment_assumption(_Ptr __p) _NOEXCEPT {
803*700637cbSDimitry Andric if (!__libcpp_is_constant_evaluated()) {
804*700637cbSDimitry Andric return static_cast<pointer>(__builtin_assume_aligned(__p, _LIBCPP_ALIGNOF(decltype(*__p))));
805*700637cbSDimitry Andric }
806*700637cbSDimitry Andric return __p;
807*700637cbSDimitry Andric }
808*700637cbSDimitry Andric
809*700637cbSDimitry Andric template <class _Ptr = pointer, __enable_if_t<!is_pointer<_Ptr>::value, int> = 0>
810*700637cbSDimitry Andric static _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI pointer
__add_alignment_assumption(_Ptr __p)811*700637cbSDimitry Andric __add_alignment_assumption(_Ptr __p) _NOEXCEPT {
812*700637cbSDimitry Andric return __p;
813*700637cbSDimitry Andric }
814*700637cbSDimitry Andric };
815*700637cbSDimitry Andric
816*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 17
817*700637cbSDimitry Andric template <class _InputIterator,
818*700637cbSDimitry Andric class _Alloc = allocator<__iter_value_type<_InputIterator>>,
819*700637cbSDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
820*700637cbSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> >
821*700637cbSDimitry Andric vector(_InputIterator, _InputIterator) -> vector<__iter_value_type<_InputIterator>, _Alloc>;
822*700637cbSDimitry Andric
823*700637cbSDimitry Andric template <class _InputIterator,
824*700637cbSDimitry Andric class _Alloc,
825*700637cbSDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
826*700637cbSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> >
827*700637cbSDimitry Andric vector(_InputIterator, _InputIterator, _Alloc) -> vector<__iter_value_type<_InputIterator>, _Alloc>;
828*700637cbSDimitry Andric #endif
829*700637cbSDimitry Andric
830*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 23
831*700637cbSDimitry Andric template <ranges::input_range _Range,
832*700637cbSDimitry Andric class _Alloc = allocator<ranges::range_value_t<_Range>>,
833*700637cbSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> >
834*700637cbSDimitry Andric vector(from_range_t, _Range&&, _Alloc = _Alloc()) -> vector<ranges::range_value_t<_Range>, _Alloc>;
835*700637cbSDimitry Andric #endif
836*700637cbSDimitry Andric
837*700637cbSDimitry Andric // __swap_out_circular_buffer relocates the objects in [__begin_, __end_) into the front of __v and swaps the buffers of
838*700637cbSDimitry Andric // *this and __v. It is assumed that __v provides space for exactly (__end_ - __begin_) objects in the front. This
839*700637cbSDimitry Andric // function has a strong exception guarantee.
840*700637cbSDimitry Andric template <class _Tp, class _Allocator>
841*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__swap_out_circular_buffer(__split_buffer<value_type,allocator_type &> & __v)842*700637cbSDimitry Andric vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v) {
843*700637cbSDimitry Andric __annotate_delete();
844*700637cbSDimitry Andric auto __new_begin = __v.__begin_ - (__end_ - __begin_);
845*700637cbSDimitry Andric std::__uninitialized_allocator_relocate(
846*700637cbSDimitry Andric this->__alloc_, std::__to_address(__begin_), std::__to_address(__end_), std::__to_address(__new_begin));
847*700637cbSDimitry Andric __v.__begin_ = __new_begin;
848*700637cbSDimitry Andric __end_ = __begin_; // All the objects have been destroyed by relocating them.
849*700637cbSDimitry Andric std::swap(this->__begin_, __v.__begin_);
850*700637cbSDimitry Andric std::swap(this->__end_, __v.__end_);
851*700637cbSDimitry Andric std::swap(this->__cap_, __v.__cap_);
852*700637cbSDimitry Andric __v.__first_ = __v.__begin_;
853*700637cbSDimitry Andric __annotate_new(size());
854*700637cbSDimitry Andric }
855*700637cbSDimitry Andric
856*700637cbSDimitry Andric // __swap_out_circular_buffer relocates the objects in [__begin_, __p) into the front of __v, the objects in
857*700637cbSDimitry Andric // [__p, __end_) into the back of __v and swaps the buffers of *this and __v. It is assumed that __v provides space for
858*700637cbSDimitry Andric // exactly (__p - __begin_) objects in the front and space for at least (__end_ - __p) objects in the back. This
859*700637cbSDimitry Andric // function has a strong exception guarantee if __begin_ == __p || __end_ == __p.
860*700637cbSDimitry Andric template <class _Tp, class _Allocator>
861*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer
__swap_out_circular_buffer(__split_buffer<value_type,allocator_type &> & __v,pointer __p)862*700637cbSDimitry Andric vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p) {
863*700637cbSDimitry Andric __annotate_delete();
864*700637cbSDimitry Andric pointer __ret = __v.__begin_;
865*700637cbSDimitry Andric
866*700637cbSDimitry Andric // Relocate [__p, __end_) first to avoid having a hole in [__begin_, __end_)
867*700637cbSDimitry Andric // in case something in [__begin_, __p) throws.
868*700637cbSDimitry Andric std::__uninitialized_allocator_relocate(
869*700637cbSDimitry Andric this->__alloc_, std::__to_address(__p), std::__to_address(__end_), std::__to_address(__v.__end_));
870*700637cbSDimitry Andric __v.__end_ += (__end_ - __p);
871*700637cbSDimitry Andric __end_ = __p; // The objects in [__p, __end_) have been destroyed by relocating them.
872*700637cbSDimitry Andric auto __new_begin = __v.__begin_ - (__p - __begin_);
873*700637cbSDimitry Andric
874*700637cbSDimitry Andric std::__uninitialized_allocator_relocate(
875*700637cbSDimitry Andric this->__alloc_, std::__to_address(__begin_), std::__to_address(__p), std::__to_address(__new_begin));
876*700637cbSDimitry Andric __v.__begin_ = __new_begin;
877*700637cbSDimitry Andric __end_ = __begin_; // All the objects have been destroyed by relocating them.
878*700637cbSDimitry Andric
879*700637cbSDimitry Andric std::swap(this->__begin_, __v.__begin_);
880*700637cbSDimitry Andric std::swap(this->__end_, __v.__end_);
881*700637cbSDimitry Andric std::swap(this->__cap_, __v.__cap_);
882*700637cbSDimitry Andric __v.__first_ = __v.__begin_;
883*700637cbSDimitry Andric __annotate_new(size());
884*700637cbSDimitry Andric return __ret;
885*700637cbSDimitry Andric }
886*700637cbSDimitry Andric
887*700637cbSDimitry Andric template <class _Tp, class _Allocator>
__vdeallocate()888*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT {
889*700637cbSDimitry Andric if (this->__begin_ != nullptr) {
890*700637cbSDimitry Andric clear();
891*700637cbSDimitry Andric __annotate_delete();
892*700637cbSDimitry Andric __alloc_traits::deallocate(this->__alloc_, this->__begin_, capacity());
893*700637cbSDimitry Andric this->__begin_ = this->__end_ = this->__cap_ = nullptr;
894*700637cbSDimitry Andric }
895*700637cbSDimitry Andric }
896*700637cbSDimitry Andric
897*700637cbSDimitry Andric // Precondition: __new_size > capacity()
898*700637cbSDimitry Andric template <class _Tp, class _Allocator>
899*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::size_type
__recommend(size_type __new_size)900*700637cbSDimitry Andric vector<_Tp, _Allocator>::__recommend(size_type __new_size) const {
901*700637cbSDimitry Andric const size_type __ms = max_size();
902*700637cbSDimitry Andric if (__new_size > __ms)
903*700637cbSDimitry Andric this->__throw_length_error();
904*700637cbSDimitry Andric const size_type __cap = capacity();
905*700637cbSDimitry Andric if (__cap >= __ms / 2)
906*700637cbSDimitry Andric return __ms;
907*700637cbSDimitry Andric return std::max<size_type>(2 * __cap, __new_size);
908*700637cbSDimitry Andric }
909*700637cbSDimitry Andric
910*700637cbSDimitry Andric // Default constructs __n objects starting at __end_
911*700637cbSDimitry Andric // throws if construction throws
912*700637cbSDimitry Andric // Precondition: __n > 0
913*700637cbSDimitry Andric // Precondition: size() + __n <= capacity()
914*700637cbSDimitry Andric // Postcondition: size() == size() + __n
915*700637cbSDimitry Andric template <class _Tp, class _Allocator>
__construct_at_end(size_type __n)916*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(size_type __n) {
917*700637cbSDimitry Andric _ConstructTransaction __tx(*this, __n);
918*700637cbSDimitry Andric const_pointer __new_end = __tx.__new_end_;
919*700637cbSDimitry Andric for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
920*700637cbSDimitry Andric __alloc_traits::construct(this->__alloc_, std::__to_address(__pos));
921*700637cbSDimitry Andric }
922*700637cbSDimitry Andric }
923*700637cbSDimitry Andric
924*700637cbSDimitry Andric // Copy constructs __n objects starting at __end_ from __x
925*700637cbSDimitry Andric // throws if construction throws
926*700637cbSDimitry Andric // Precondition: __n > 0
927*700637cbSDimitry Andric // Precondition: size() + __n <= capacity()
928*700637cbSDimitry Andric // Postcondition: size() == old size() + __n
929*700637cbSDimitry Andric // Postcondition: [i] == __x for all i in [size() - __n, __n)
930*700637cbSDimitry Andric template <class _Tp, class _Allocator>
931*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
__construct_at_end(size_type __n,const_reference __x)932*700637cbSDimitry Andric vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) {
933*700637cbSDimitry Andric _ConstructTransaction __tx(*this, __n);
934*700637cbSDimitry Andric const_pointer __new_end = __tx.__new_end_;
935*700637cbSDimitry Andric for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
936*700637cbSDimitry Andric __alloc_traits::construct(this->__alloc_, std::__to_address(__pos), __x);
937*700637cbSDimitry Andric }
938*700637cbSDimitry Andric }
939*700637cbSDimitry Andric
940*700637cbSDimitry Andric template <class _Tp, class _Allocator>
941*700637cbSDimitry Andric template <class _InputIterator, class _Sentinel>
942*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__construct_at_end(_InputIterator __first,_Sentinel __last,size_type __n)943*700637cbSDimitry Andric vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
944*700637cbSDimitry Andric _ConstructTransaction __tx(*this, __n);
945*700637cbSDimitry Andric __tx.__pos_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __tx.__pos_);
946*700637cbSDimitry Andric }
947*700637cbSDimitry Andric
948*700637cbSDimitry Andric // Default constructs __n objects starting at __end_
949*700637cbSDimitry Andric // throws if construction throws
950*700637cbSDimitry Andric // Postcondition: size() == size() + __n
951*700637cbSDimitry Andric // Exception safety: strong.
952*700637cbSDimitry Andric template <class _Tp, class _Allocator>
__append(size_type __n)953*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__append(size_type __n) {
954*700637cbSDimitry Andric if (static_cast<size_type>(this->__cap_ - this->__end_) >= __n)
955*700637cbSDimitry Andric this->__construct_at_end(__n);
956*700637cbSDimitry Andric else {
957*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), this->__alloc_);
958*700637cbSDimitry Andric __v.__construct_at_end(__n);
959*700637cbSDimitry Andric __swap_out_circular_buffer(__v);
960*700637cbSDimitry Andric }
961*700637cbSDimitry Andric }
962*700637cbSDimitry Andric
963*700637cbSDimitry Andric // Default constructs __n objects starting at __end_
964*700637cbSDimitry Andric // throws if construction throws
965*700637cbSDimitry Andric // Postcondition: size() == size() + __n
966*700637cbSDimitry Andric // Exception safety: strong.
967*700637cbSDimitry Andric template <class _Tp, class _Allocator>
__append(size_type __n,const_reference __x)968*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x) {
969*700637cbSDimitry Andric if (static_cast<size_type>(this->__cap_ - this->__end_) >= __n)
970*700637cbSDimitry Andric this->__construct_at_end(__n, __x);
971*700637cbSDimitry Andric else {
972*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), this->__alloc_);
973*700637cbSDimitry Andric __v.__construct_at_end(__n, __x);
974*700637cbSDimitry Andric __swap_out_circular_buffer(__v);
975*700637cbSDimitry Andric }
976*700637cbSDimitry Andric }
977*700637cbSDimitry Andric
978*700637cbSDimitry Andric template <class _Tp, class _Allocator>
vector(vector && __x)979*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocator>::vector(vector&& __x)
980*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 17
981*700637cbSDimitry Andric noexcept
982*700637cbSDimitry Andric #else
983*700637cbSDimitry Andric _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
984*700637cbSDimitry Andric #endif
985*700637cbSDimitry Andric : __alloc_(std::move(__x.__alloc_)) {
986*700637cbSDimitry Andric this->__begin_ = __x.__begin_;
987*700637cbSDimitry Andric this->__end_ = __x.__end_;
988*700637cbSDimitry Andric this->__cap_ = __x.__cap_;
989*700637cbSDimitry Andric __x.__begin_ = __x.__end_ = __x.__cap_ = nullptr;
990*700637cbSDimitry Andric }
991*700637cbSDimitry Andric
992*700637cbSDimitry Andric template <class _Tp, class _Allocator>
993*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI
vector(vector && __x,const __type_identity_t<allocator_type> & __a)994*700637cbSDimitry Andric vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_type>& __a)
995*700637cbSDimitry Andric : __alloc_(__a) {
996*700637cbSDimitry Andric if (__a == __x.__alloc_) {
997*700637cbSDimitry Andric this->__begin_ = __x.__begin_;
998*700637cbSDimitry Andric this->__end_ = __x.__end_;
999*700637cbSDimitry Andric this->__cap_ = __x.__cap_;
1000*700637cbSDimitry Andric __x.__begin_ = __x.__end_ = __x.__cap_ = nullptr;
1001*700637cbSDimitry Andric } else {
1002*700637cbSDimitry Andric typedef move_iterator<iterator> _Ip;
1003*700637cbSDimitry Andric __init_with_size(_Ip(__x.begin()), _Ip(__x.end()), __x.size());
1004*700637cbSDimitry Andric }
1005*700637cbSDimitry Andric }
1006*700637cbSDimitry Andric
1007*700637cbSDimitry Andric template <class _Tp, class _Allocator>
__move_assign(vector & __c,false_type)1008*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type)
1009*700637cbSDimitry Andric _NOEXCEPT_(__alloc_traits::is_always_equal::value) {
1010*700637cbSDimitry Andric if (this->__alloc_ != __c.__alloc_) {
1011*700637cbSDimitry Andric typedef move_iterator<iterator> _Ip;
1012*700637cbSDimitry Andric assign(_Ip(__c.begin()), _Ip(__c.end()));
1013*700637cbSDimitry Andric } else
1014*700637cbSDimitry Andric __move_assign(__c, true_type());
1015*700637cbSDimitry Andric }
1016*700637cbSDimitry Andric
1017*700637cbSDimitry Andric template <class _Tp, class _Allocator>
__move_assign(vector & __c,true_type)1018*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
1019*700637cbSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
1020*700637cbSDimitry Andric __vdeallocate();
1021*700637cbSDimitry Andric __move_assign_alloc(__c); // this can throw
1022*700637cbSDimitry Andric this->__begin_ = __c.__begin_;
1023*700637cbSDimitry Andric this->__end_ = __c.__end_;
1024*700637cbSDimitry Andric this->__cap_ = __c.__cap_;
1025*700637cbSDimitry Andric __c.__begin_ = __c.__end_ = __c.__cap_ = nullptr;
1026*700637cbSDimitry Andric }
1027*700637cbSDimitry Andric
1028*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1029*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocator>&
1030*700637cbSDimitry Andric vector<_Tp, _Allocator>::operator=(const vector& __x) {
1031*700637cbSDimitry Andric if (this != std::addressof(__x)) {
1032*700637cbSDimitry Andric __copy_assign_alloc(__x);
1033*700637cbSDimitry Andric assign(__x.__begin_, __x.__end_);
1034*700637cbSDimitry Andric }
1035*700637cbSDimitry Andric return *this;
1036*700637cbSDimitry Andric }
1037*700637cbSDimitry Andric
1038*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1039*700637cbSDimitry Andric template <class _Iterator, class _Sentinel>
1040*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__assign_with_sentinel(_Iterator __first,_Sentinel __last)1041*700637cbSDimitry Andric vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) {
1042*700637cbSDimitry Andric pointer __cur = __begin_;
1043*700637cbSDimitry Andric for (; __first != __last && __cur != __end_; ++__first, (void)++__cur)
1044*700637cbSDimitry Andric *__cur = *__first;
1045*700637cbSDimitry Andric if (__cur != __end_) {
1046*700637cbSDimitry Andric __destruct_at_end(__cur);
1047*700637cbSDimitry Andric } else {
1048*700637cbSDimitry Andric for (; __first != __last; ++__first)
1049*700637cbSDimitry Andric emplace_back(*__first);
1050*700637cbSDimitry Andric }
1051*700637cbSDimitry Andric }
1052*700637cbSDimitry Andric
1053*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1054*700637cbSDimitry Andric template <class _Iterator, class _Sentinel>
1055*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__assign_with_size(_Iterator __first,_Sentinel __last,difference_type __n)1056*700637cbSDimitry Andric vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n) {
1057*700637cbSDimitry Andric size_type __new_size = static_cast<size_type>(__n);
1058*700637cbSDimitry Andric if (__new_size <= capacity()) {
1059*700637cbSDimitry Andric if (__new_size > size()) {
1060*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 23
1061*700637cbSDimitry Andric auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in;
1062*700637cbSDimitry Andric __construct_at_end(std::move(__mid), std::move(__last), __new_size - size());
1063*700637cbSDimitry Andric #else
1064*700637cbSDimitry Andric _Iterator __mid = std::next(__first, size());
1065*700637cbSDimitry Andric std::copy(__first, __mid, this->__begin_);
1066*700637cbSDimitry Andric __construct_at_end(__mid, __last, __new_size - size());
1067*700637cbSDimitry Andric #endif
1068*700637cbSDimitry Andric } else {
1069*700637cbSDimitry Andric pointer __m = std::__copy(std::move(__first), __last, this->__begin_).second;
1070*700637cbSDimitry Andric this->__destruct_at_end(__m);
1071*700637cbSDimitry Andric }
1072*700637cbSDimitry Andric } else {
1073*700637cbSDimitry Andric __vdeallocate();
1074*700637cbSDimitry Andric __vallocate(__recommend(__new_size));
1075*700637cbSDimitry Andric __construct_at_end(std::move(__first), std::move(__last), __new_size);
1076*700637cbSDimitry Andric }
1077*700637cbSDimitry Andric }
1078*700637cbSDimitry Andric
1079*700637cbSDimitry Andric template <class _Tp, class _Allocator>
assign(size_type __n,const_reference __u)1080*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u) {
1081*700637cbSDimitry Andric if (__n <= capacity()) {
1082*700637cbSDimitry Andric size_type __s = size();
1083*700637cbSDimitry Andric std::fill_n(this->__begin_, std::min(__n, __s), __u);
1084*700637cbSDimitry Andric if (__n > __s)
1085*700637cbSDimitry Andric __construct_at_end(__n - __s, __u);
1086*700637cbSDimitry Andric else
1087*700637cbSDimitry Andric this->__destruct_at_end(this->__begin_ + __n);
1088*700637cbSDimitry Andric } else {
1089*700637cbSDimitry Andric __vdeallocate();
1090*700637cbSDimitry Andric __vallocate(__recommend(static_cast<size_type>(__n)));
1091*700637cbSDimitry Andric __construct_at_end(__n, __u);
1092*700637cbSDimitry Andric }
1093*700637cbSDimitry Andric }
1094*700637cbSDimitry Andric
1095*700637cbSDimitry Andric template <class _Tp, class _Allocator>
reserve(size_type __n)1096*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::reserve(size_type __n) {
1097*700637cbSDimitry Andric if (__n > capacity()) {
1098*700637cbSDimitry Andric if (__n > max_size())
1099*700637cbSDimitry Andric this->__throw_length_error();
1100*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(__n, size(), this->__alloc_);
1101*700637cbSDimitry Andric __swap_out_circular_buffer(__v);
1102*700637cbSDimitry Andric }
1103*700637cbSDimitry Andric }
1104*700637cbSDimitry Andric
1105*700637cbSDimitry Andric template <class _Tp, class _Allocator>
shrink_to_fit()1106*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT {
1107*700637cbSDimitry Andric if (capacity() > size()) {
1108*700637cbSDimitry Andric #if _LIBCPP_HAS_EXCEPTIONS
1109*700637cbSDimitry Andric try {
1110*700637cbSDimitry Andric #endif // _LIBCPP_HAS_EXCEPTIONS
1111*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(size(), size(), this->__alloc_);
1112*700637cbSDimitry Andric // The Standard mandates shrink_to_fit() does not increase the capacity.
1113*700637cbSDimitry Andric // With equal capacity keep the existing buffer. This avoids extra work
1114*700637cbSDimitry Andric // due to swapping the elements.
1115*700637cbSDimitry Andric if (__v.capacity() < capacity())
1116*700637cbSDimitry Andric __swap_out_circular_buffer(__v);
1117*700637cbSDimitry Andric #if _LIBCPP_HAS_EXCEPTIONS
1118*700637cbSDimitry Andric } catch (...) {
1119*700637cbSDimitry Andric }
1120*700637cbSDimitry Andric #endif // _LIBCPP_HAS_EXCEPTIONS
1121*700637cbSDimitry Andric }
1122*700637cbSDimitry Andric }
1123*700637cbSDimitry Andric
1124*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1125*700637cbSDimitry Andric template <class... _Args>
1126*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer
__emplace_back_slow_path(_Args &&...__args)1127*700637cbSDimitry Andric vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) {
1128*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), size(), this->__alloc_);
1129*700637cbSDimitry Andric // __v.emplace_back(std::forward<_Args>(__args)...);
1130*700637cbSDimitry Andric __alloc_traits::construct(this->__alloc_, std::__to_address(__v.__end_), std::forward<_Args>(__args)...);
1131*700637cbSDimitry Andric __v.__end_++;
1132*700637cbSDimitry Andric __swap_out_circular_buffer(__v);
1133*700637cbSDimitry Andric return this->__end_;
1134*700637cbSDimitry Andric }
1135*700637cbSDimitry Andric
1136*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1137*700637cbSDimitry Andric template <class... _Args>
1138*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 inline
1139*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 17
1140*700637cbSDimitry Andric typename vector<_Tp, _Allocator>::reference
1141*700637cbSDimitry Andric #else
1142*700637cbSDimitry Andric void
1143*700637cbSDimitry Andric #endif
emplace_back(_Args &&...__args)1144*700637cbSDimitry Andric vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) {
1145*700637cbSDimitry Andric pointer __end = this->__end_;
1146*700637cbSDimitry Andric if (__end < this->__cap_) {
1147*700637cbSDimitry Andric __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
1148*700637cbSDimitry Andric ++__end;
1149*700637cbSDimitry Andric } else {
1150*700637cbSDimitry Andric __end = __emplace_back_slow_path(std::forward<_Args>(__args)...);
1151*700637cbSDimitry Andric }
1152*700637cbSDimitry Andric this->__end_ = __end;
1153*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 17
1154*700637cbSDimitry Andric return *(__end - 1);
1155*700637cbSDimitry Andric #endif
1156*700637cbSDimitry Andric }
1157*700637cbSDimitry Andric
1158*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1159*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
erase(const_iterator __position)1160*700637cbSDimitry Andric vector<_Tp, _Allocator>::erase(const_iterator __position) {
1161*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1162*700637cbSDimitry Andric __position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator");
1163*700637cbSDimitry Andric difference_type __ps = __position - cbegin();
1164*700637cbSDimitry Andric pointer __p = this->__begin_ + __ps;
1165*700637cbSDimitry Andric this->__destruct_at_end(std::move(__p + 1, this->__end_, __p));
1166*700637cbSDimitry Andric return __make_iter(__p);
1167*700637cbSDimitry Andric }
1168*700637cbSDimitry Andric
1169*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1170*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
erase(const_iterator __first,const_iterator __last)1171*700637cbSDimitry Andric vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) {
1172*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range");
1173*700637cbSDimitry Andric pointer __p = this->__begin_ + (__first - begin());
1174*700637cbSDimitry Andric if (__first != __last) {
1175*700637cbSDimitry Andric this->__destruct_at_end(std::move(__p + (__last - __first), this->__end_, __p));
1176*700637cbSDimitry Andric }
1177*700637cbSDimitry Andric return __make_iter(__p);
1178*700637cbSDimitry Andric }
1179*700637cbSDimitry Andric
1180*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1181*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__move_range(pointer __from_s,pointer __from_e,pointer __to)1182*700637cbSDimitry Andric vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to) {
1183*700637cbSDimitry Andric pointer __old_last = this->__end_;
1184*700637cbSDimitry Andric difference_type __n = __old_last - __to;
1185*700637cbSDimitry Andric {
1186*700637cbSDimitry Andric pointer __i = __from_s + __n;
1187*700637cbSDimitry Andric _ConstructTransaction __tx(*this, __from_e - __i);
1188*700637cbSDimitry Andric for (pointer __pos = __tx.__pos_; __i < __from_e; ++__i, (void)++__pos, __tx.__pos_ = __pos) {
1189*700637cbSDimitry Andric __alloc_traits::construct(this->__alloc_, std::__to_address(__pos), std::move(*__i));
1190*700637cbSDimitry Andric }
1191*700637cbSDimitry Andric }
1192*700637cbSDimitry Andric std::move_backward(__from_s, __from_s + __n, __old_last);
1193*700637cbSDimitry Andric }
1194*700637cbSDimitry Andric
1195*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1196*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
insert(const_iterator __position,const_reference __x)1197*700637cbSDimitry Andric vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) {
1198*700637cbSDimitry Andric pointer __p = this->__begin_ + (__position - begin());
1199*700637cbSDimitry Andric if (this->__end_ < this->__cap_) {
1200*700637cbSDimitry Andric if (__p == this->__end_) {
1201*700637cbSDimitry Andric __emplace_back_assume_capacity(__x);
1202*700637cbSDimitry Andric } else {
1203*700637cbSDimitry Andric __move_range(__p, this->__end_, __p + 1);
1204*700637cbSDimitry Andric const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
1205*700637cbSDimitry Andric if (std::__is_pointer_in_range(std::__to_address(__p), std::__to_address(__end_), std::addressof(__x)))
1206*700637cbSDimitry Andric ++__xr;
1207*700637cbSDimitry Andric *__p = *__xr;
1208*700637cbSDimitry Andric }
1209*700637cbSDimitry Andric } else {
1210*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
1211*700637cbSDimitry Andric __v.emplace_back(__x);
1212*700637cbSDimitry Andric __p = __swap_out_circular_buffer(__v, __p);
1213*700637cbSDimitry Andric }
1214*700637cbSDimitry Andric return __make_iter(__p);
1215*700637cbSDimitry Andric }
1216*700637cbSDimitry Andric
1217*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1218*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
insert(const_iterator __position,value_type && __x)1219*700637cbSDimitry Andric vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) {
1220*700637cbSDimitry Andric pointer __p = this->__begin_ + (__position - begin());
1221*700637cbSDimitry Andric if (this->__end_ < this->__cap_) {
1222*700637cbSDimitry Andric if (__p == this->__end_) {
1223*700637cbSDimitry Andric __emplace_back_assume_capacity(std::move(__x));
1224*700637cbSDimitry Andric } else {
1225*700637cbSDimitry Andric __move_range(__p, this->__end_, __p + 1);
1226*700637cbSDimitry Andric *__p = std::move(__x);
1227*700637cbSDimitry Andric }
1228*700637cbSDimitry Andric } else {
1229*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
1230*700637cbSDimitry Andric __v.emplace_back(std::move(__x));
1231*700637cbSDimitry Andric __p = __swap_out_circular_buffer(__v, __p);
1232*700637cbSDimitry Andric }
1233*700637cbSDimitry Andric return __make_iter(__p);
1234*700637cbSDimitry Andric }
1235*700637cbSDimitry Andric
1236*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1237*700637cbSDimitry Andric template <class... _Args>
1238*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
emplace(const_iterator __position,_Args &&...__args)1239*700637cbSDimitry Andric vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) {
1240*700637cbSDimitry Andric pointer __p = this->__begin_ + (__position - begin());
1241*700637cbSDimitry Andric if (this->__end_ < this->__cap_) {
1242*700637cbSDimitry Andric if (__p == this->__end_) {
1243*700637cbSDimitry Andric __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
1244*700637cbSDimitry Andric } else {
1245*700637cbSDimitry Andric __temp_value<value_type, _Allocator> __tmp(this->__alloc_, std::forward<_Args>(__args)...);
1246*700637cbSDimitry Andric __move_range(__p, this->__end_, __p + 1);
1247*700637cbSDimitry Andric *__p = std::move(__tmp.get());
1248*700637cbSDimitry Andric }
1249*700637cbSDimitry Andric } else {
1250*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
1251*700637cbSDimitry Andric __v.emplace_back(std::forward<_Args>(__args)...);
1252*700637cbSDimitry Andric __p = __swap_out_circular_buffer(__v, __p);
1253*700637cbSDimitry Andric }
1254*700637cbSDimitry Andric return __make_iter(__p);
1255*700637cbSDimitry Andric }
1256*700637cbSDimitry Andric
1257*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1258*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
insert(const_iterator __position,size_type __n,const_reference __x)1259*700637cbSDimitry Andric vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x) {
1260*700637cbSDimitry Andric pointer __p = this->__begin_ + (__position - begin());
1261*700637cbSDimitry Andric if (__n > 0) {
1262*700637cbSDimitry Andric if (__n <= static_cast<size_type>(this->__cap_ - this->__end_)) {
1263*700637cbSDimitry Andric size_type __old_n = __n;
1264*700637cbSDimitry Andric pointer __old_last = this->__end_;
1265*700637cbSDimitry Andric if (__n > static_cast<size_type>(this->__end_ - __p)) {
1266*700637cbSDimitry Andric size_type __cx = __n - (this->__end_ - __p);
1267*700637cbSDimitry Andric __construct_at_end(__cx, __x);
1268*700637cbSDimitry Andric __n -= __cx;
1269*700637cbSDimitry Andric }
1270*700637cbSDimitry Andric if (__n > 0) {
1271*700637cbSDimitry Andric __move_range(__p, __old_last, __p + __old_n);
1272*700637cbSDimitry Andric const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
1273*700637cbSDimitry Andric if (std::__is_pointer_in_range(std::__to_address(__p), std::__to_address(__end_), std::addressof(__x)))
1274*700637cbSDimitry Andric __xr += __old_n;
1275*700637cbSDimitry Andric std::fill_n(__p, __n, *__xr);
1276*700637cbSDimitry Andric }
1277*700637cbSDimitry Andric } else {
1278*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
1279*700637cbSDimitry Andric __v.__construct_at_end(__n, __x);
1280*700637cbSDimitry Andric __p = __swap_out_circular_buffer(__v, __p);
1281*700637cbSDimitry Andric }
1282*700637cbSDimitry Andric }
1283*700637cbSDimitry Andric return __make_iter(__p);
1284*700637cbSDimitry Andric }
1285*700637cbSDimitry Andric
1286*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1287*700637cbSDimitry Andric template <class _InputIterator, class _Sentinel>
1288*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
__insert_with_sentinel(const_iterator __position,_InputIterator __first,_Sentinel __last)1289*700637cbSDimitry Andric vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) {
1290*700637cbSDimitry Andric difference_type __off = __position - begin();
1291*700637cbSDimitry Andric pointer __p = this->__begin_ + __off;
1292*700637cbSDimitry Andric pointer __old_last = this->__end_;
1293*700637cbSDimitry Andric for (; this->__end_ != this->__cap_ && __first != __last; ++__first)
1294*700637cbSDimitry Andric __emplace_back_assume_capacity(*__first);
1295*700637cbSDimitry Andric
1296*700637cbSDimitry Andric if (__first == __last)
1297*700637cbSDimitry Andric (void)std::rotate(__p, __old_last, this->__end_);
1298*700637cbSDimitry Andric else {
1299*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(__alloc_);
1300*700637cbSDimitry Andric auto __guard = std::__make_exception_guard(
1301*700637cbSDimitry Andric _AllocatorDestroyRangeReverse<allocator_type, pointer>(__alloc_, __old_last, this->__end_));
1302*700637cbSDimitry Andric __v.__construct_at_end_with_sentinel(std::move(__first), std::move(__last));
1303*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __merged(
1304*700637cbSDimitry Andric __recommend(size() + __v.size()), __off, __alloc_); // has `__off` positions available at the front
1305*700637cbSDimitry Andric std::__uninitialized_allocator_relocate(
1306*700637cbSDimitry Andric __alloc_, std::__to_address(__old_last), std::__to_address(this->__end_), std::__to_address(__merged.__end_));
1307*700637cbSDimitry Andric __guard.__complete(); // Release the guard once objects in [__old_last_, __end_) have been successfully relocated.
1308*700637cbSDimitry Andric __merged.__end_ += this->__end_ - __old_last;
1309*700637cbSDimitry Andric this->__end_ = __old_last;
1310*700637cbSDimitry Andric std::__uninitialized_allocator_relocate(
1311*700637cbSDimitry Andric __alloc_, std::__to_address(__v.__begin_), std::__to_address(__v.__end_), std::__to_address(__merged.__end_));
1312*700637cbSDimitry Andric __merged.__end_ += __v.size();
1313*700637cbSDimitry Andric __v.__end_ = __v.__begin_;
1314*700637cbSDimitry Andric __p = __swap_out_circular_buffer(__merged, __p);
1315*700637cbSDimitry Andric }
1316*700637cbSDimitry Andric return __make_iter(__p);
1317*700637cbSDimitry Andric }
1318*700637cbSDimitry Andric
1319*700637cbSDimitry Andric template <class _Tp, class _Allocator>
1320*700637cbSDimitry Andric template <class _Iterator, class _Sentinel>
1321*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
__insert_with_size(const_iterator __position,_Iterator __first,_Sentinel __last,difference_type __n)1322*700637cbSDimitry Andric vector<_Tp, _Allocator>::__insert_with_size(
1323*700637cbSDimitry Andric const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) {
1324*700637cbSDimitry Andric pointer __p = this->__begin_ + (__position - begin());
1325*700637cbSDimitry Andric if (__n > 0) {
1326*700637cbSDimitry Andric if (__n <= this->__cap_ - this->__end_) {
1327*700637cbSDimitry Andric pointer __old_last = this->__end_;
1328*700637cbSDimitry Andric difference_type __dx = this->__end_ - __p;
1329*700637cbSDimitry Andric if (__n > __dx) {
1330*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 23
1331*700637cbSDimitry Andric if constexpr (!forward_iterator<_Iterator>) {
1332*700637cbSDimitry Andric __construct_at_end(std::move(__first), std::move(__last), __n);
1333*700637cbSDimitry Andric std::rotate(__p, __old_last, this->__end_);
1334*700637cbSDimitry Andric } else
1335*700637cbSDimitry Andric #endif
1336*700637cbSDimitry Andric {
1337*700637cbSDimitry Andric _Iterator __m = std::next(__first, __dx);
1338*700637cbSDimitry Andric __construct_at_end(__m, __last, __n - __dx);
1339*700637cbSDimitry Andric if (__dx > 0) {
1340*700637cbSDimitry Andric __move_range(__p, __old_last, __p + __n);
1341*700637cbSDimitry Andric __insert_assign_n_unchecked(__first, __dx, __p);
1342*700637cbSDimitry Andric }
1343*700637cbSDimitry Andric }
1344*700637cbSDimitry Andric } else {
1345*700637cbSDimitry Andric __move_range(__p, __old_last, __p + __n);
1346*700637cbSDimitry Andric __insert_assign_n_unchecked(std::move(__first), __n, __p);
1347*700637cbSDimitry Andric }
1348*700637cbSDimitry Andric } else {
1349*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
1350*700637cbSDimitry Andric __v.__construct_at_end_with_size(std::move(__first), __n);
1351*700637cbSDimitry Andric __p = __swap_out_circular_buffer(__v, __p);
1352*700637cbSDimitry Andric }
1353*700637cbSDimitry Andric }
1354*700637cbSDimitry Andric return __make_iter(__p);
1355*700637cbSDimitry Andric }
1356*700637cbSDimitry Andric
1357*700637cbSDimitry Andric template <class _Tp, class _Allocator>
resize(size_type __sz)1358*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __sz) {
1359*700637cbSDimitry Andric size_type __cs = size();
1360*700637cbSDimitry Andric if (__cs < __sz)
1361*700637cbSDimitry Andric this->__append(__sz - __cs);
1362*700637cbSDimitry Andric else if (__cs > __sz)
1363*700637cbSDimitry Andric this->__destruct_at_end(this->__begin_ + __sz);
1364*700637cbSDimitry Andric }
1365*700637cbSDimitry Andric
1366*700637cbSDimitry Andric template <class _Tp, class _Allocator>
resize(size_type __sz,const_reference __x)1367*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x) {
1368*700637cbSDimitry Andric size_type __cs = size();
1369*700637cbSDimitry Andric if (__cs < __sz)
1370*700637cbSDimitry Andric this->__append(__sz - __cs, __x);
1371*700637cbSDimitry Andric else if (__cs > __sz)
1372*700637cbSDimitry Andric this->__destruct_at_end(this->__begin_ + __sz);
1373*700637cbSDimitry Andric }
1374*700637cbSDimitry Andric
1375*700637cbSDimitry Andric template <class _Tp, class _Allocator>
swap(vector & __x)1376*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::swap(vector& __x)
1377*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 14
1378*700637cbSDimitry Andric _NOEXCEPT
1379*700637cbSDimitry Andric #else
1380*700637cbSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
1381*700637cbSDimitry Andric #endif
1382*700637cbSDimitry Andric {
1383*700637cbSDimitry Andric _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1384*700637cbSDimitry Andric __alloc_traits::propagate_on_container_swap::value || this->__alloc_ == __x.__alloc_,
1385*700637cbSDimitry Andric "vector::swap: Either propagate_on_container_swap must be true"
1386*700637cbSDimitry Andric " or the allocators must compare equal");
1387*700637cbSDimitry Andric std::swap(this->__begin_, __x.__begin_);
1388*700637cbSDimitry Andric std::swap(this->__end_, __x.__end_);
1389*700637cbSDimitry Andric std::swap(this->__cap_, __x.__cap_);
1390*700637cbSDimitry Andric std::__swap_allocator(this->__alloc_, __x.__alloc_);
1391*700637cbSDimitry Andric }
1392*700637cbSDimitry Andric
1393*700637cbSDimitry Andric template <class _Tp, class _Allocator>
__invariants()1394*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 bool vector<_Tp, _Allocator>::__invariants() const {
1395*700637cbSDimitry Andric if (this->__begin_ == nullptr) {
1396*700637cbSDimitry Andric if (this->__end_ != nullptr || this->__cap_ != nullptr)
1397*700637cbSDimitry Andric return false;
1398*700637cbSDimitry Andric } else {
1399*700637cbSDimitry Andric if (this->__begin_ > this->__end_)
1400*700637cbSDimitry Andric return false;
1401*700637cbSDimitry Andric if (this->__begin_ == this->__cap_)
1402*700637cbSDimitry Andric return false;
1403*700637cbSDimitry Andric if (this->__end_ > this->__cap_)
1404*700637cbSDimitry Andric return false;
1405*700637cbSDimitry Andric }
1406*700637cbSDimitry Andric return true;
1407*700637cbSDimitry Andric }
1408*700637cbSDimitry Andric
1409*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 20
1410*700637cbSDimitry Andric template <>
1411*700637cbSDimitry Andric inline constexpr bool __format::__enable_insertable<vector<char>> = true;
1412*700637cbSDimitry Andric # if _LIBCPP_HAS_WIDE_CHARACTERS
1413*700637cbSDimitry Andric template <>
1414*700637cbSDimitry Andric inline constexpr bool __format::__enable_insertable<vector<wchar_t>> = true;
1415*700637cbSDimitry Andric # endif
1416*700637cbSDimitry Andric #endif // _LIBCPP_STD_VER >= 20
1417*700637cbSDimitry Andric
1418*700637cbSDimitry Andric _LIBCPP_END_NAMESPACE_STD
1419*700637cbSDimitry Andric
1420*700637cbSDimitry Andric _LIBCPP_POP_MACROS
1421*700637cbSDimitry Andric
1422*700637cbSDimitry Andric #endif // _LIBCPP___VECTOR_VECTOR_H
1423