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