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