[libcxx-commits] [libcxx] [libcxx] adds a size-based representation for `vector`'s unstable ABI (PR #155330)

Christopher Di Bella via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jan 14 18:25:37 PST 2026


https://github.com/cjdb updated https://github.com/llvm/llvm-project/pull/155330

>From ba94eeba1e22ebee9708c770c3b7da73eaad131e Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Mon, 25 Aug 2025 23:06:45 +0000
Subject: [PATCH 1/8] [libcxx] adds a size-based representation for `vector`'s
 unstable ABI

**tl;dr** We can significantly improve the runtime performance of
`std::vector` by changing its representation from three pointers to one
pointer and two integers. This document explains the details of this
change, along with the justifications for making it. See the [RFC] for
more information.

This commit changes `std::vector`'s representation in a similar manner
to `__split_buffer` in #139632. We introduce a layout type that tracks
implementation details that differ between the pointer-based vector
and size-based vector representations. `vector` does not parameterise
its layout type, unlike `__split_buffer`. `__split_buffer` is used by
both `vector` and `deque`, and being able to take an ABI break on
`vector` doesn't automatically mean that users can also tolerate a break
on `deque`. The most convenient way to work around this problem is to
parameterise the layout type. Users of `std::vector` should not depend
on its layout, and libc++ has no internal reason to toggle it, so we
keep the representation concrete.

To use this feature, you'll need to configure libc++ so that it's built
with `-DLIBCXX_UNSTABLE_ABI=Yes`.

[RFC]: https://discourse.llvm.org/t/adding-a-size-based-vector-to-libc-s-unstable-abi/86306
---
 libcxx/include/__configuration/abi.h          |   1 +
 libcxx/include/__split_buffer                 |   8 +-
 libcxx/include/__vector/vector.h              | 800 ++++++++++++------
 .../alg.swap/ranges.swap_ranges.pass.cpp      |  54 +-
 libcxx/utils/gdb/libcxx/printers.py           |  18 +-
 5 files changed, 597 insertions(+), 284 deletions(-)

diff --git a/libcxx/include/__configuration/abi.h b/libcxx/include/__configuration/abi.h
index 38b85c6ac70de..70aef42b487ac 100644
--- a/libcxx/include/__configuration/abi.h
+++ b/libcxx/include/__configuration/abi.h
@@ -79,6 +79,7 @@
 #  define _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER
 #  define _LIBCPP_ABI_OPTIMIZED_FUNCTION
 #  define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
+#  define _LIBCPP_ABI_SIZE_BASED_VECTOR
 #  define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
 #  define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY
 #  define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW
diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer
index 1e05e4df8ba0f..9a55f855bbfda 100644
--- a/libcxx/include/__split_buffer
+++ b/libcxx/include/__split_buffer
@@ -268,7 +268,6 @@ public:
   __set_valid_range(pointer __new_begin, pointer __new_end) _NOEXCEPT {
     // Size-based __split_buffers track their size directly: we need to explicitly update the size
     // when the front is adjusted.
-    __size_ -= __new_begin - __begin_;
     __begin_ = __new_begin;
     __set_sentinel(__new_end);
   }
@@ -277,7 +276,6 @@ public:
   __set_valid_range(pointer __new_begin, size_type __new_size) _NOEXCEPT {
     // Size-based __split_buffers track their size directly: we need to explicitly update the size
     // when the front is adjusted.
-    __size_ -= __new_begin - __begin_;
     __begin_ = __new_begin;
     __set_sentinel(__new_size);
   }
@@ -316,9 +314,9 @@ public:
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_without_allocator(
-      __split_buffer_pointer_layout<__split_buffer<value_type, __alloc_rr&, __split_buffer_pointer_layout>,
-                                    value_type,
-                                    __alloc_rr&>& __other) _NOEXCEPT {
+      __split_buffer_size_layout<__split_buffer<value_type, __alloc_rr&, __split_buffer_size_layout>,
+                                 value_type,
+                                 __alloc_rr&>& __other) _NOEXCEPT {
     std::swap(__front_cap_, __other.__front_cap_);
     std::swap(__begin_, __other.__begin_);
     std::swap(__cap_, __other.__cap_);
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 7051e044314ea..9e94fe75123eb 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -55,6 +55,7 @@
 #include <__type_traits/is_nothrow_constructible.h>
 #include <__type_traits/is_pointer.h>
 #include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
 #include <__type_traits/is_trivially_relocatable.h>
 #include <__type_traits/type_identity.h>
 #include <__utility/declval.h>
@@ -82,25 +83,334 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+template <class _Vector, class _Tp, class _Allocator>
+class __vector_layout {
+public:
+  using value_type                      = _Tp;
+  using allocator_type                  = _Allocator;
+  using __alloc_traits _LIBCPP_NODEBUG  = allocator_traits<allocator_type>;
+  using reference                       = value_type&;
+  using const_reference                 = const value_type&;
+  using size_type                       = typename __alloc_traits::size_type;
+  using difference_type                 = typename __alloc_traits::difference_type;
+  using pointer                         = typename __alloc_traits::pointer;
+  using const_pointer                   = typename __alloc_traits::const_pointer;
+  using __split_buffer _LIBCPP_NODEBUG  = std::__split_buffer<_Tp, _Allocator&, __split_buffer_size_layout>;
+  using __sentinel_type _LIBCPP_NODEBUG = size_type;
+
+  _LIBCPP_HIDE_FROM_ABI __vector_layout() = default;
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __vector_layout(allocator_type const& __a)
+      _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
+      : __alloc_(__a) {}
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __vector_layout(allocator_type&& __a)
+      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+      : __alloc_(std::move(__a)) {}
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __vector_layout(__vector_layout&& __other)
+      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+      : __begin_(std::move(__other.__begin_)),
+        __size_(std::move(__other.__size_)),
+        __cap_(std::move(__other.__cap_)),
+        __alloc_(std::move(__other.__alloc_)) {
+    __other.__begin_ = nullptr;
+    __other.__size_  = 0;
+    __other.__cap_   = 0;
+  }
+
+  // Capacity
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
+    return __size_;
+  }
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
+    return __cap_;
+  }
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
+    return __size_ == 0;
+  }
+
+  // Access
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
+    return __begin_[__size_ - 1];
+  }
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
+    return __begin_[__size_ - 1];
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type& __allocator_ref() _NOEXCEPT {
+    return __alloc_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type const&
+  __allocator_ref() const _NOEXCEPT {
+    return __alloc_;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__vector_layout& __x)
+      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>) {
+    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
+        __alloc_traits::propagate_on_container_swap::value || __alloc_ == __x.__alloc_,
+        "vector::swap: Either propagate_on_container_swap must be true"
+        " or the allocators must compare equal");
+    std::swap(__begin_, __x.__begin_);
+    std::swap(__size_, __x.__size_);
+    std::swap(__cap_, __x.__cap_);
+    std::__swap_allocator(__alloc_, __x.__alloc_);
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_begin() const _NOEXCEPT {
+    return __begin_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __raw_sentinel() const _NOEXCEPT {
+    return __size_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __raw_capacity() const _NOEXCEPT {
+    return __cap_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_pointer() const _NOEXCEPT {
+    return __begin_ + __size_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type
+  __remaining_capacity() const _NOEXCEPT {
+    return __cap_ - __size_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
+    return __size_ == __cap_;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, pointer __end) _NOEXCEPT {
+    __begin_ = __begin;
+    __size_  = __end - __begin_;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
+  __set_valid_range(pointer __begin, size_type __size) _NOEXCEPT {
+    __begin_ = __begin;
+    __size_  = __size;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __size) _NOEXCEPT {
+    __size_ = __size;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __pos) _NOEXCEPT {
+    __size_ = static_cast<size_type>(__pos - __begin_);
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __cap) _NOEXCEPT { __cap_ = __cap; }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __pos) _NOEXCEPT {
+    __cap_ = static_cast<size_type>(__pos - __begin_);
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
+    if (__begin_ == nullptr) {
+      if (__size_ || __cap_)
+        return false;
+    } else {
+      if (__size_ > __cap_)
+        return false;
+    }
+    return true;
+  }
+
+private:
+  pointer __begin_  = nullptr;
+  size_type __size_ = 0;
+  size_type __cap_  = 0;
+  [[no_unique_address]] allocator_type __alloc_;
+};
+#else
+template <class _Vector, class _Tp, class _Allocator>
+class __vector_layout {
+public:
+  using value_type                      = _Tp;
+  using allocator_type                  = _Allocator;
+  using __alloc_traits _LIBCPP_NODEBUG  = allocator_traits<allocator_type>;
+  using reference                       = value_type&;
+  using const_reference                 = const value_type&;
+  using size_type                       = typename __alloc_traits::size_type;
+  using difference_type                 = typename __alloc_traits::difference_type;
+  using pointer                         = typename __alloc_traits::pointer;
+  using const_pointer                   = typename __alloc_traits::const_pointer;
+  using __split_buffer _LIBCPP_NODEBUG  = std::__split_buffer<_Tp, _Allocator&, __split_buffer_pointer_layout>;
+  using __sentinel_type _LIBCPP_NODEBUG = pointer;
+
+  // Can't be defaulted due to _LIBCPP_COMPRESSED_PAIR not being an aggregate in C++03 and C++11.
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __vector_layout()
+      _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+      : __cap_(nullptr) {}
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __vector_layout(allocator_type const& __a)
+      _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
+      : __cap_(nullptr), __alloc_(__a) {}
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __vector_layout(allocator_type&& __a)
+      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+      : __cap_(nullptr), __alloc_(std::move(__a)) {}
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __vector_layout(__vector_layout&& __other)
+      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+      : __begin_(std::move(__other.__begin_)),
+        __end_(std::move(__other.__end_)),
+        __cap_(std::move(__other.__cap_)),
+        __alloc_(std::move(__other.__alloc_)) {
+    __other.__begin_ = nullptr;
+    __other.__end_   = nullptr;
+    __other.__cap_   = nullptr;
+  }
+
+  // Capacity
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
+    return static_cast<size_type>(__end_ - __begin_);
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
+    return static_cast<size_type>(__cap_ - __begin_);
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
+    return __begin_ == __end_;
+  }
+
+  // Access
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
+    return *(__end_ - 1);
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
+    return *(__end_ - 1);
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type& __allocator_ref() _NOEXCEPT {
+    return __alloc_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type const&
+  __allocator_ref() const _NOEXCEPT {
+    return __alloc_;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__vector_layout& __x)
+      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>) {
+    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
+        __alloc_traits::propagate_on_container_swap::value || __alloc_ == __x.__alloc_,
+        "vector::swap: Either propagate_on_container_swap must be true"
+        " or the allocators must compare equal");
+    std::swap(__begin_, __x.__begin_);
+    std::swap(__end_, __x.__end_);
+    std::swap(__cap_, __x.__cap_);
+    std::__swap_allocator(__alloc_, __x.__alloc_);
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_begin() const _NOEXCEPT {
+    return __begin_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_sentinel() const _NOEXCEPT {
+    return __end_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_capacity() const _NOEXCEPT {
+    return __cap_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_pointer() const _NOEXCEPT {
+    return __end_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type
+  __remaining_capacity() const _NOEXCEPT {
+    return __cap_ - __end_;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
+    return __end_ == __cap_;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, pointer __end) _NOEXCEPT {
+    __begin_ = __begin;
+    __end_   = __end;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
+  __set_valid_range(pointer __begin, size_type __size) _NOEXCEPT {
+    __begin_ = __begin;
+    __end_   = __begin_ + __size;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __end) _NOEXCEPT { __end_ = __end; }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __offset) _NOEXCEPT {
+    __end_ = __begin_ + __offset;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __cap) _NOEXCEPT { __cap_ = __cap; }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __offset) _NOEXCEPT {
+    __cap_ = __begin_ + __offset;
+  }
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
+    if (__begin_ == nullptr) {
+      if (__end_ != nullptr || __cap_ != nullptr)
+        return false;
+    } else {
+      if (__begin_ > __end_)
+        return false;
+      if (__begin_ == __cap_)
+        return false;
+      if (__end_ > __cap_)
+        return false;
+    }
+    return true;
+  }
+
+private:
+  pointer __begin_ = nullptr;
+  pointer __end_   = nullptr;
+  _LIBCPP_COMPRESSED_PAIR(pointer, __cap_, allocator_type, __alloc_);
+};
+#endif // _LIBCPP_ABI_SIZE_BASED_VECTOR
+
 template <class _Tp, class _Allocator /* = allocator<_Tp> */>
-class vector {
-  template <class _Up, class _Alloc>
-  using __split_buffer _LIBCPP_NODEBUG = std::__split_buffer<_Up, _Alloc, __split_buffer_pointer_layout>;
+class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
+  using __base _LIBCPP_NODEBUG = __vector_layout<vector, _Tp, _Allocator>;
+  using __self _LIBCPP_NODEBUG = vector;
+  using __base::__allocator_ref;
+  using __base::__end_pointer;
+  using __base::__is_full;
+  using __base::__raw_begin;
+  using __base::__raw_capacity;
+  using __base::__raw_sentinel;
+  using __base::__remaining_capacity;
+  using __base::__set_capacity;
+  using __base::__set_sentinel;
+  using __base::__set_valid_range;
+  using typename __base::__alloc_traits;
+  using typename __base::__sentinel_type;
+  using typename __base::__split_buffer;
 
 public:
-  //
-  // Types
-  //
-  using __self _LIBCPP_NODEBUG         = vector;
-  using value_type                     = _Tp;
-  using allocator_type                 = _Allocator;
-  using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
-  using reference                      = value_type&;
-  using const_reference                = const value_type&;
-  using size_type                      = typename __alloc_traits::size_type;
-  using difference_type                = typename __alloc_traits::difference_type;
-  using pointer                        = typename __alloc_traits::pointer;
-  using const_pointer                  = typename __alloc_traits::const_pointer;
+  using value_type      = _Tp;
+  using allocator_type  = _Allocator;
+  using reference       = typename __base::reference;
+  using const_reference = typename __base::const_reference;
+  using size_type       = typename __base::size_type;
+  using difference_type = typename __base::difference_type;
+  using pointer         = typename __base::pointer;
+  using const_pointer   = typename __base::const_pointer;
 #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
   // Users might provide custom allocators, and prior to C++20 we have no existing way to detect whether the allocator's
   // pointer type is contiguous (though it has to be by the Standard). Using the wrapper type ensures the iterator is
@@ -114,6 +424,8 @@ class vector {
   using reverse_iterator       = std::reverse_iterator<iterator>;
   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
+  using __base::__invariants;
+
   // A vector containers the following members which may be trivially relocatable:
   // - pointer: may be trivially relocatable, so it's checked
   // - allocator_type: may be trivially relocatable, so it's checked
@@ -138,7 +450,7 @@ class vector {
 #else
       noexcept
 #endif
-      : __alloc_(__a) {
+      : __base(__a) {
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n) {
@@ -152,7 +464,7 @@ class vector {
 
 #if _LIBCPP_STD_VER >= 14
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n, const allocator_type& __a)
-      : __alloc_(__a) {
+      : __base(__a) {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
     if (__n > 0) {
       __vallocate(__n);
@@ -174,7 +486,7 @@ class vector {
   template <__enable_if_t<__is_allocator_v<_Allocator>, int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(size_type __n, const value_type& __x, const allocator_type& __a)
-      : __alloc_(__a) {
+      : __base(__a) {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
     if (__n > 0) {
       __vallocate(__n);
@@ -197,7 +509,7 @@ class vector {
                           int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
-      : __alloc_(__a) {
+      : __base(__a) {
     __init_with_sentinel(__first, __last);
   }
 
@@ -218,7 +530,7 @@ class vector {
                     int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a)
-      : __alloc_(__a) {
+      : __base(__a) {
     size_type __n = static_cast<size_type>(std::distance(__first, __last));
     __init_with_size(__first, __last, __n);
   }
@@ -227,7 +539,7 @@ class vector {
   template <_ContainerCompatibleRange<_Tp> _Range>
   _LIBCPP_HIDE_FROM_ABI constexpr vector(
       from_range_t, _Range&& __range, const allocator_type& __alloc = allocator_type())
-      : __alloc_(__alloc) {
+      : __base(__alloc) {
     if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
       auto __n = static_cast<size_type>(ranges::distance(__range));
       __init_with_size(ranges::begin(__range), ranges::end(__range), __n);
@@ -244,10 +556,10 @@ class vector {
     _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __destroy_vector(vector& __vec) : __vec_(__vec) {}
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() {
-      if (__vec_.__begin_ != nullptr) {
+      if (__vec_.__raw_begin() != nullptr) {
         __vec_.clear();
         __vec_.__annotate_delete();
-        __alloc_traits::deallocate(__vec_.__alloc_, __vec_.__begin_, __vec_.capacity());
+        __alloc_traits::deallocate(__vec_.__allocator_ref(), __vec_.__raw_begin(), __vec_.capacity());
       }
     }
 
@@ -259,13 +571,13 @@ class vector {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~vector() { __destroy_vector (*this)(); }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(const vector& __x)
-      : __alloc_(__alloc_traits::select_on_container_copy_construction(__x.__alloc_)) {
-    __init_with_size(__x.__begin_, __x.__end_, __x.size());
+      : __base(__alloc_traits::select_on_container_copy_construction(__x.__allocator_ref())) {
+    __init_with_size(__x.__raw_begin(), __x.__end_pointer(), __x.size());
   }
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
-      : __alloc_(__a) {
-    __init_with_size(__x.__begin_, __x.__end_, __x.size());
+      : __base(__a) {
+    __init_with_size(__x.__raw_begin(), __x.__end_pointer(), __x.size());
   }
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector& operator=(const vector& __x);
 
@@ -276,7 +588,7 @@ class vector {
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(initializer_list<value_type> __il, const allocator_type& __a)
-      : __alloc_(__a) {
+      : __base(__a) {
     __init_with_size(__il.begin(), __il.end(), __il.size());
   }
 
@@ -339,23 +651,23 @@ class vector {
 #endif
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
-    return this->__alloc_;
+    return __allocator_ref();
   }
 
   //
   // Iterators
   //
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
-    return __make_iter(__add_alignment_assumption(this->__begin_));
+    return __make_iter(__add_alignment_assumption(__raw_begin()));
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
-    return __make_iter(__add_alignment_assumption(this->__begin_));
+    return __make_iter(__add_alignment_assumption(__raw_begin()));
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
-    return __make_iter(__add_alignment_assumption(this->__end_));
+    return __make_iter(__add_alignment_assumption(__end_pointer()));
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
-    return __make_iter(__add_alignment_assumption(this->__end_));
+    return __make_iter(__add_alignment_assumption(__end_pointer()));
   }
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT {
@@ -389,17 +701,19 @@ class vector {
   //
   // [vector.capacity], capacity
   //
+
+  // Capacity
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
-    return static_cast<size_type>(this->__end_ - this->__begin_);
+    return __base::size();
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
-    return static_cast<size_type>(this->__cap_ - this->__begin_);
+    return __base::capacity();
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
-    return this->__begin_ == this->__end_;
+    return __base::empty();
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
-    return std::min<size_type>(__alloc_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max());
+    return std::min<size_type>(__alloc_traits::max_size(__allocator_ref()), numeric_limits<difference_type>::max());
   }
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
@@ -409,50 +723,48 @@ class vector {
   //
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __n) _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
-    return this->__begin_[__n];
+    return __raw_begin()[__n];
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference
   operator[](size_type __n) const _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
-    return this->__begin_[__n];
+    return __raw_begin()[__n];
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference at(size_type __n) {
     if (__n >= size())
       this->__throw_out_of_range();
-    return this->__begin_[__n];
+    return __raw_begin()[__n];
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const {
     if (__n >= size())
       this->__throw_out_of_range();
-    return this->__begin_[__n];
+    return __raw_begin()[__n];
   }
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
-    return *this->__begin_;
+    return *__raw_begin();
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
-    return *this->__begin_;
+    return *__raw_begin();
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
-    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
-    return *(this->__end_ - 1);
+    return __base::back();
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
-    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
-    return *(this->__end_ - 1);
+    return __base::back();
   }
 
   //
   // [vector.data], data access
   //
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI value_type* data() _NOEXCEPT {
-    return std::__to_address(this->__begin_);
+    return std::__to_address(__raw_begin());
   }
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT {
-    return std::__to_address(this->__begin_);
+    return std::__to_address(__raw_begin());
   }
 
   //
@@ -477,7 +789,7 @@ class vector {
     _LIBCPP_ASSERT_INTERNAL(
         size() < capacity(), "We assume that we have enough space to insert an element at the end of the vector");
     _ConstructTransaction __tx(*this, 1);
-    __alloc_traits::construct(this->__alloc_, std::__to_address(__tx.__pos_), std::forward<_Args>(__args)...);
+    __alloc_traits::construct(__allocator_ref(), std::__to_address(__tx.__pos_), std::forward<_Args>(__args)...);
     ++__tx.__pos_;
   }
 
@@ -490,7 +802,7 @@ class vector {
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector::pop_back called on an empty vector");
-    this->__destruct_at_end(this->__end_ - 1);
+    this->__destruct_at_end(__end_pointer() - 1);
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __position, const_reference __x);
@@ -546,41 +858,39 @@ class vector {
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
     size_type __old_size = size();
-    __base_destruct_at_end(this->__begin_);
+    __base_destruct_at_end(__raw_begin());
     __annotate_shrink(__old_size);
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz, const_reference __x);
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(vector&)
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(vector& __other)
 #if _LIBCPP_STD_VER >= 14
-      _NOEXCEPT;
+      _NOEXCEPT
 #else
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
+      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
 #endif
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
+  {
+    __base::swap(__other);
+  }
 
 private:
-  pointer __begin_ = nullptr;
-  pointer __end_   = nullptr;
-  _LIBCPP_COMPRESSED_PAIR(pointer, __cap_ = nullptr, allocator_type, __alloc_);
-
   //  Allocate space for __n objects
   //  throws length_error if __n > max_size()
   //  throws (probably bad_alloc) if memory run out
-  //  Precondition:  __begin_ == __end_ == __cap_ == nullptr
+  //  Precondition:  begin() == nullptr
+  //  Precondition:  size() == 0
+  //  Precondition:  capacity() == 0
   //  Precondition:  __n > 0
   //  Postcondition:  capacity() >= __n
   //  Postcondition:  size() == 0
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __vallocate(size_type __n) {
     if (__n > max_size())
       this->__throw_length_error();
-    auto __allocation = std::__allocate_at_least(this->__alloc_, __n);
-    __begin_          = __allocation.ptr;
-    __end_            = __allocation.ptr;
-    __cap_            = __begin_ + __allocation.count;
+    auto __allocation = std::__allocate_at_least(__allocator_ref(), __n);
+    __set_valid_range(__allocation.ptr, static_cast<size_type>(0));
+    __set_capacity(__allocation.count);
     __annotate_new(0);
   }
 
@@ -628,7 +938,7 @@ class vector {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
   __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
     for (pointer __end_position = __position + __n; __position != __end_position; ++__position, (void)++__first) {
-      __temp_value<value_type, _Allocator> __tmp(this->__alloc_, *__first);
+      __temp_value<value_type, _Allocator> __tmp(__allocator_ref(), *__first);
       *__position = std::move(__tmp.get());
     }
   }
@@ -672,8 +982,8 @@ class vector {
     // a laxer approach.
     return std::__make_bounded_iter(
         std::__wrap_iter<pointer>(__p),
-        std::__wrap_iter<pointer>(this->__begin_),
-        std::__wrap_iter<pointer>(this->__cap_));
+        std::__wrap_iter<pointer>(__raw_begin()),
+        std::__wrap_iter<pointer>(__raw_capacity()));
 #else
     return iterator(__p);
 #endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
@@ -684,17 +994,16 @@ class vector {
     // Bound the iterator according to the capacity, rather than the size.
     return std::__make_bounded_iter(
         std::__wrap_iter<const_pointer>(__p),
-        std::__wrap_iter<const_pointer>(this->__begin_),
-        std::__wrap_iter<const_pointer>(this->__cap_));
+        std::__wrap_iter<const_pointer>(__raw_begin()),
+        std::__wrap_iter<const_pointer>(__raw_capacity()));
 #else
     return const_iterator(__p);
 #endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
   }
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
-  __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_out_circular_buffer(__split_buffer& __v);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer
-  __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p);
+  __swap_out_circular_buffer(__split_buffer& __v, pointer __p);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
   __move_range(pointer __from_s, pointer __from_e, pointer __to);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, true_type)
@@ -708,7 +1017,7 @@ class vector {
   }
 
   template <class... _Args>
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI inline pointer __emplace_back_slow_path(_Args&&... __args);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __sentinel_type __emplace_back_slow_path(_Args&&... __args);
 
   // The following functions are no-ops outside of AddressSanitizer mode.
   // We call annotations for every allocator, unless explicitly disabled.
@@ -741,14 +1050,14 @@ class vector {
 
   struct _ConstructTransaction {
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(vector& __v, size_type __n)
-        : __v_(__v), __pos_(__v.__end_), __new_end_(__v.__end_ + __n) {
+        : __v_(__v), __pos_(__v.__end_pointer()), __new_end_(__pos_ + __n) {
       __v_.__annotate_increase(__n);
     }
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() {
-      __v_.__end_ = __pos_;
+      __v_.__set_sentinel(__pos_);
       if (__pos_ != __new_end_) {
-        __v_.__annotate_shrink(__new_end_ - __v_.__begin_);
+        __v_.__annotate_shrink(__new_end_ - __v_.__raw_begin());
       }
     }
 
@@ -761,10 +1070,10 @@ class vector {
   };
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __base_destruct_at_end(pointer __new_last) _NOEXCEPT {
-    pointer __soon_to_be_end = this->__end_;
+    pointer __soon_to_be_end = __end_pointer();
     while (__new_last != __soon_to_be_end)
-      __alloc_traits::destroy(this->__alloc_, std::__to_address(--__soon_to_be_end));
-    this->__end_ = __new_last;
+      __alloc_traits::destroy(__allocator_ref(), std::__to_address(--__soon_to_be_end));
+    __set_sentinel(__new_last);
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector& __c) {
@@ -782,20 +1091,21 @@ class vector {
   [[__noreturn__]] _LIBCPP_HIDE_FROM_ABI static void __throw_out_of_range() { std::__throw_out_of_range("vector"); }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector& __c, true_type) {
-    if (this->__alloc_ != __c.__alloc_) {
+    if (__allocator_ref() != __c.__allocator_ref()) {
       clear();
       __annotate_delete();
-      __alloc_traits::deallocate(this->__alloc_, this->__begin_, capacity());
-      this->__begin_ = this->__end_ = this->__cap_ = nullptr;
+      __alloc_traits::deallocate(__allocator_ref(), __raw_begin(), capacity());
+      __set_valid_range(nullptr, static_cast<size_type>(0));
+      __set_capacity(static_cast<__sentinel_type>(0));
     }
-    this->__alloc_ = __c.__alloc_;
+    __allocator_ref() = __c.__allocator_ref();
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector&, false_type) {}
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c, true_type)
       _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
-    this->__alloc_ = std::move(__c.__alloc_);
+    __allocator_ref() = std::move(__c.__allocator_ref());
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector&, false_type) _NOEXCEPT {}
@@ -815,19 +1125,17 @@ class vector {
     return __p;
   }
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_layouts(__split_buffer<_Tp, allocator_type&>& __sb) {
-    auto __vector_begin    = __begin_;
-    auto __vector_sentinel = __end_;
-    auto __vector_cap      = __cap_;
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_layouts(__split_buffer& __sb) {
+    auto __vector_begin    = __raw_begin();
+    auto __vector_sentinel = __raw_sentinel();
+    auto __vector_cap      = __raw_capacity();
 
     auto __sb_begin    = __sb.begin();
     auto __sb_sentinel = __sb.__raw_sentinel();
     auto __sb_cap      = __sb.__raw_capacity();
 
-    // TODO: replace with __set_valid_range and __set_capacity when vector supports it.
-    __begin_ = __sb_begin;
-    __end_   = __sb_sentinel;
-    __cap_   = __sb_cap;
+    __set_valid_range(__sb_begin, __sb_sentinel);
+    __set_capacity(__sb_cap);
 
     __sb.__set_valid_range(__vector_begin, __vector_sentinel);
     __sb.__set_capacity(__vector_cap);
@@ -855,47 +1163,53 @@ template <ranges::input_range _Range,
 vector(from_range_t, _Range&&, _Alloc = _Alloc()) -> vector<ranges::range_value_t<_Range>, _Alloc>;
 #endif
 
-// __swap_out_circular_buffer relocates the objects in [__begin_, __end_) into the front of __v and swaps the buffers of
-// *this and __v. It is assumed that __v provides space for exactly (__end_ - __begin_) objects in the front. This
+// __swap_out_circular_buffer relocates the objects in [__raw_begin(), size()) into the front of __v and swaps the
+// buffers of *this and __v. It is assumed that __v provides space for exactly size() objects in the front. This
 // function has a strong exception guarantee.
 template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void
-vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v) {
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v) {
   __annotate_delete();
   auto __new_begin = __v.begin() - size();
   std::__uninitialized_allocator_relocate(
-      this->__alloc_, std::__to_address(__begin_), std::__to_address(__end_), std::__to_address(__new_begin));
+      __allocator_ref(),
+      std::__to_address(__raw_begin()),
+      std::__to_address(__end_pointer()),
+      std::__to_address(__new_begin));
   __v.__set_valid_range(__new_begin, __v.end());
-  __end_       = __begin_; // All the objects have been destroyed by relocating them.
+  __set_sentinel(static_cast<size_type>(0)); // All the objects have been destroyed by relocating them.
+  // __v.__size_ += __size_;
 
   __swap_layouts(__v);
   __v.__set_data(__v.begin());
   __annotate_new(size());
 }
 
-// __swap_out_circular_buffer relocates the objects in [__begin_, __p) into the front of __v, the objects in
-// [__p, __end_) into the back of __v and swaps the buffers of *this and __v. It is assumed that __v provides space for
-// exactly (__p - __begin_) objects in the front and space for at least (__end_ - __p) objects in the back. This
-// function has a strong exception guarantee if __begin_ == __p || __end_ == __p.
+// __swap_out_circular_buffer relocates the objects in [__raw_begin(), __p) into the front of __v, the objects in
+// [__p, end()) into the back of __v and swaps the buffers of *this and __v. It is assumed that __v provides space for
+// exactly (__p - __raw_begin()) objects in the front and space for at least (size() - __p) objects in the back. This
+// function has a strong exception guarantee if __raw_begin() == __p || size() == __p.
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer
-vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p) {
+vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v, pointer __p) {
   __annotate_delete();
   pointer __ret = __v.begin();
 
-  // Relocate [__p, __end_) first to avoid having a hole in [__begin_, __end_)
-  // in case something in [__begin_, __p) throws.
+  pointer __end = __end_pointer();
+  // Relocate [__p, __end) first to avoid having a hole in [__raw_begin(), __end)
+  // in case something in [__raw_begin(), __p) throws.
   std::__uninitialized_allocator_relocate(
-      this->__alloc_, std::__to_address(__p), std::__to_address(__end_), std::__to_address(__v.end()));
-  auto __relocated_so_far = __end_ - __p;
+      __allocator_ref(), std::__to_address(__p), std::__to_address(__end), std::__to_address(__v.end()));
+  auto __relocated_so_far = __end - __p;
   __v.__set_sentinel(__v.end() + __relocated_so_far);
-  __end_           = __p; // The objects in [__p, __end_) have been destroyed by relocating them.
-  auto __new_begin = __v.begin() - (__p - __begin_);
+  __set_sentinel(
+      __raw_sentinel() - __relocated_so_far); // The objects in [__p, __end_) have been destroyed by relocating them.
+  auto __new_begin = __v.begin() - (__p - __raw_begin());
 
   std::__uninitialized_allocator_relocate(
-      this->__alloc_, std::__to_address(__begin_), std::__to_address(__p), std::__to_address(__new_begin));
-  __v.__set_valid_range(__new_begin, __v.end());
-  __end_ = __begin_; // All the objects have been destroyed by relocating them.
+      __allocator_ref(), std::__to_address(__raw_begin()), std::__to_address(__p), std::__to_address(__new_begin));
+  __v.__set_valid_range(__new_begin, __v.size() + size());
+  __set_sentinel(static_cast<size_type>(0)); // All the objects have been destroyed by relocating them.
+
   __swap_layouts(__v);
   __v.__set_data(__v.begin());
   __annotate_new(size());
@@ -904,11 +1218,12 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
 
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT {
-  if (this->__begin_ != nullptr) {
+  if (__raw_begin() != nullptr) {
     clear();
     __annotate_delete();
-    __alloc_traits::deallocate(this->__alloc_, this->__begin_, capacity());
-    this->__begin_ = this->__end_ = this->__cap_ = nullptr;
+    __alloc_traits::deallocate(__allocator_ref(), __raw_begin(), capacity());
+    __set_valid_range(nullptr, static_cast<size_type>(0));
+    __set_capacity(static_cast<size_type>(0));
   }
 }
 
@@ -925,7 +1240,7 @@ vector<_Tp, _Allocator>::__recommend(size_type __new_size) const {
   return std::max<size_type>(2 * __cap, __new_size);
 }
 
-//  Default constructs __n objects starting at __end_
+//  Default constructs __n objects starting at __end_pointer()
 //  throws if construction throws
 //  Precondition:  __n > 0
 //  Precondition:  size() + __n <= capacity()
@@ -935,11 +1250,11 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(s
   _ConstructTransaction __tx(*this, __n);
   const_pointer __new_end = __tx.__new_end_;
   for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
-    __alloc_traits::construct(this->__alloc_, std::__to_address(__pos));
+    __alloc_traits::construct(__allocator_ref(), std::__to_address(__pos));
   }
 }
 
-//  Copy constructs __n objects starting at __end_ from __x
+//  Copy constructs __n objects starting at __end_pointer() from __x
 //  throws if construction throws
 //  Precondition:  __n > 0
 //  Precondition:  size() + __n <= capacity()
@@ -951,7 +1266,7 @@ vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
   _ConstructTransaction __tx(*this, __n);
   const_pointer __new_end = __tx.__new_end_;
   for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
-    __alloc_traits::construct(this->__alloc_, std::__to_address(__pos), __x);
+    __alloc_traits::construct(__allocator_ref(), std::__to_address(__pos), __x);
   }
 }
 
@@ -960,7 +1275,8 @@ template <class _InputIterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
   _ConstructTransaction __tx(*this, __n);
-  __tx.__pos_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __tx.__pos_);
+  __tx.__pos_ =
+      std::__uninitialized_allocator_copy(__allocator_ref(), std::move(__first), std::move(__last), __tx.__pos_);
 }
 
 template <class _Tp, class _Allocator>
@@ -970,22 +1286,22 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocato
 #else
     _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
 #endif
-    : __alloc_(std::move(__x.__alloc_)) {
-  this->__begin_ = __x.__begin_;
-  this->__end_   = __x.__end_;
-  this->__cap_   = __x.__cap_;
-  __x.__begin_ = __x.__end_ = __x.__cap_ = nullptr;
+    : __base(std::move(__x.__allocator_ref())) {
+  __set_valid_range(__x.__raw_begin(), __x.__raw_sentinel());
+  __set_capacity(__x.__raw_capacity());
+  __x.__set_valid_range(nullptr, static_cast<size_type>(0));
+  __x.__set_capacity(static_cast<size_type>(0));
 }
 
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI
 vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_type>& __a)
-    : __alloc_(__a) {
-  if (__a == __x.__alloc_) {
-    this->__begin_ = __x.__begin_;
-    this->__end_   = __x.__end_;
-    this->__cap_   = __x.__cap_;
-    __x.__begin_ = __x.__end_ = __x.__cap_ = nullptr;
+    : __base(__a) {
+  if (__a == __x.__allocator_ref()) {
+    __set_valid_range(__x.__raw_begin(), __x.__raw_sentinel());
+    __set_capacity(__x.__raw_capacity());
+    __x.__set_valid_range(nullptr, static_cast<size_type>(0));
+    __x.__set_capacity(static_cast<size_type>(0));
   } else {
     typedef move_iterator<iterator> _Ip;
     __init_with_size(_Ip(__x.begin()), _Ip(__x.end()), __x.size());
@@ -995,7 +1311,7 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type)
     _NOEXCEPT_(__alloc_traits::is_always_equal::value) {
-  if (this->__alloc_ != __c.__alloc_) {
+  if (__allocator_ref() != __c.__allocator_ref()) {
     typedef move_iterator<iterator> _Ip;
     assign(_Ip(__c.begin()), _Ip(__c.end()));
   } else
@@ -1007,10 +1323,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector
     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
   __vdeallocate();
   __move_assign_alloc(__c); // this can throw
-  this->__begin_ = __c.__begin_;
-  this->__end_   = __c.__end_;
-  this->__cap_   = __c.__cap_;
-  __c.__begin_ = __c.__end_ = __c.__cap_ = nullptr;
+  __set_valid_range(__c.__raw_begin(), __c.__raw_sentinel());
+  __set_capacity(__c.__raw_capacity());
+  __c.__set_valid_range(nullptr, static_cast<size_type>(0));
+  __c.__set_capacity(static_cast<size_type>(0));
 }
 
 template <class _Tp, class _Allocator>
@@ -1018,7 +1334,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocato
 vector<_Tp, _Allocator>::operator=(const vector& __x) {
   if (this != std::addressof(__x)) {
     __copy_assign_alloc(__x);
-    assign(__x.__begin_, __x.__end_);
+    assign(__x.__raw_begin(), __x.__end_pointer());
   }
   return *this;
 }
@@ -1027,10 +1343,11 @@ template <class _Tp, class _Allocator>
 template <class _Iterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
 vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) {
-  pointer __cur = __begin_;
-  for (; __first != __last && __cur != __end_; ++__first, (void)++__cur)
+  pointer __cur = __raw_begin();
+  pointer __end = __end_pointer();
+  for (; __first != __last && __cur != __end; ++__first, (void)++__cur)
     *__cur = *__first;
-  if (__cur != __end_) {
+  if (__cur != __end) {
     __destruct_at_end(__cur);
   } else {
     for (; __first != __last; ++__first)
@@ -1046,15 +1363,15 @@ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last,
   if (__new_size <= capacity()) {
     if (__new_size > size()) {
 #if _LIBCPP_STD_VER >= 23
-      auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in;
+      auto __mid = ranges::copy_n(std::move(__first), size(), __raw_begin()).in;
       __construct_at_end(std::move(__mid), std::move(__last), __new_size - size());
 #else
       _Iterator __mid = std::next(__first, size());
-      std::copy(__first, __mid, this->__begin_);
+      std::copy(__first, __mid, __raw_begin());
       __construct_at_end(__mid, __last, __new_size - size());
 #endif
     } else {
-      pointer __m = std::__copy(std::move(__first), __last, this->__begin_).second;
+      pointer __m = std::__copy(std::move(__first), __last, __raw_begin()).second;
       this->__destruct_at_end(__m);
     }
   } else {
@@ -1068,11 +1385,11 @@ template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u) {
   if (__n <= capacity()) {
     size_type __s = size();
-    std::fill_n(this->__begin_, std::min(__n, __s), __u);
+    std::fill_n(__raw_begin(), std::min(__n, __s), __u);
     if (__n > __s)
       __construct_at_end(__n - __s, __u);
     else
-      this->__destruct_at_end(this->__begin_ + __n);
+      this->__destruct_at_end(__raw_begin() + __n);
   } else {
     __vdeallocate();
     __vallocate(__recommend(static_cast<size_type>(__n)));
@@ -1085,7 +1402,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::reserve(size_type __
   if (__n > capacity()) {
     if (__n > max_size())
       this->__throw_length_error();
-    __split_buffer<value_type, allocator_type&> __v(__n, size(), this->__alloc_);
+    __split_buffer __v(__n, size(), __allocator_ref());
     __swap_out_circular_buffer(__v);
   }
 }
@@ -1096,7 +1413,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::shrink_to_fit() _NOE
 #if _LIBCPP_HAS_EXCEPTIONS
     try {
 #endif // _LIBCPP_HAS_EXCEPTIONS
-      __split_buffer<value_type, allocator_type&> __v(size(), size(), this->__alloc_);
+      __split_buffer __v(size(), size(), __allocator_ref());
       // The Standard mandates shrink_to_fit() does not increase the capacity.
       // With equal capacity keep the existing buffer. This avoids extra work
       // due to swapping the elements.
@@ -1111,15 +1428,15 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::shrink_to_fit() _NOE
 
 template <class _Tp, class _Allocator>
 template <class... _Args>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::__sentinel_type
 vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) {
-  __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), size(), this->__alloc_);
+  __split_buffer __v(__recommend(size() + 1), size(), __allocator_ref());
   //    __v.emplace_back(std::forward<_Args>(__args)...);
   pointer __end = __v.end();
-  __alloc_traits::construct(this->__alloc_, std::__to_address(__end), std::forward<_Args>(__args)...);
+  __alloc_traits::construct(__allocator_ref(), std::__to_address(__end), std::forward<_Args>(__args)...);
   __v.__set_sentinel(++__end);
   __swap_out_circular_buffer(__v);
-  return this->__end_;
+  return __raw_sentinel();
 }
 
 // This makes the compiler inline `__else()` if `__cond` is known to be false. Currently LLVM doesn't do that without
@@ -1149,18 +1466,18 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline
     void
 #endif
     vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) {
-  pointer __end = this->__end_;
+  auto __current_sentinel = __raw_sentinel();
   std::__if_likely_else(
-      __end < this->__cap_,
+      __current_sentinel < __raw_capacity(),
       [&] {
         __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
-        ++__end;
+        ++__current_sentinel;
       },
-      [&] { __end = __emplace_back_slow_path(std::forward<_Args>(__args)...); });
+      [&] { __current_sentinel = __emplace_back_slow_path(std::forward<_Args>(__args)...); });
 
-  this->__end_ = __end;
+  __set_sentinel(__current_sentinel);
 #if _LIBCPP_STD_VER >= 17
-  return *(__end - 1);
+  return back();
 #endif
 }
 
@@ -1170,8 +1487,8 @@ vector<_Tp, _Allocator>::erase(const_iterator __position) {
   _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
       __position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator");
   difference_type __ps = __position - cbegin();
-  pointer __p          = this->__begin_ + __ps;
-  this->__destruct_at_end(std::move(__p + 1, this->__end_, __p));
+  pointer __p          = __raw_begin() + __ps;
+  this->__destruct_at_end(std::move(__p + 1, __end_pointer(), __p));
   return __make_iter(__p);
 }
 
@@ -1179,9 +1496,9 @@ template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) {
   _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range");
-  pointer __p = this->__begin_ + (__first - begin());
+  pointer __p = __raw_begin() + (__first - begin());
   if (__first != __last) {
-    this->__destruct_at_end(std::move(__p + (__last - __first), this->__end_, __p));
+    this->__destruct_at_end(std::move(__p + (__last - __first), __end_pointer(), __p));
   }
   return __make_iter(__p);
 }
@@ -1189,13 +1506,13 @@ vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) {
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to) {
-  pointer __old_last  = this->__end_;
+  pointer __old_last  = __end_pointer();
   difference_type __n = __old_last - __to;
   {
     pointer __i = __from_s + __n;
     _ConstructTransaction __tx(*this, __from_e - __i);
     for (pointer __pos = __tx.__pos_; __i < __from_e; ++__i, (void)++__pos, __tx.__pos_ = __pos) {
-      __alloc_traits::construct(this->__alloc_, std::__to_address(__pos), std::move(*__i));
+      __alloc_traits::construct(__allocator_ref(), std::__to_address(__pos), std::move(*__i));
     }
   }
   std::move_backward(__from_s, __from_s + __n, __old_last);
@@ -1204,19 +1521,20 @@ vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointe
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) {
-  pointer __p = this->__begin_ + (__position - begin());
-  if (this->__end_ < this->__cap_) {
-    if (__p == this->__end_) {
+  pointer __p = __raw_begin() + (__position - begin());
+  if (!__is_full()) {
+    pointer __end = __end_pointer();
+    if (__p == __end) {
       __emplace_back_assume_capacity(__x);
     } else {
-      __move_range(__p, this->__end_, __p + 1);
+      __move_range(__p, __end, __p + 1);
       const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
-      if (std::__is_pointer_in_range(std::__to_address(__p), std::__to_address(__end_), std::addressof(__x)))
+      if (std::__is_pointer_in_range(std::__to_address(__p), std::__to_address(__end), std::addressof(__x)))
         ++__xr;
       *__p = *__xr;
     }
   } else {
-    __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
+    __split_buffer __v(__recommend(size() + 1), __p - __raw_begin(), __allocator_ref());
     __v.emplace_back(__x);
     __p = __swap_out_circular_buffer(__v, __p);
   }
@@ -1226,16 +1544,17 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) {
-  pointer __p = this->__begin_ + (__position - begin());
-  if (this->__end_ < this->__cap_) {
-    if (__p == this->__end_) {
+  pointer __p = __raw_begin() + (__position - begin());
+  if (!__is_full()) {
+    pointer __end = __end_pointer();
+    if (__p == __end) {
       __emplace_back_assume_capacity(std::move(__x));
     } else {
-      __move_range(__p, this->__end_, __p + 1);
+      __move_range(__p, __end, __p + 1);
       *__p = std::move(__x);
     }
   } else {
-    __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
+    __split_buffer __v(__recommend(size() + 1), __p - __raw_begin(), __allocator_ref());
     __v.emplace_back(std::move(__x));
     __p = __swap_out_circular_buffer(__v, __p);
   }
@@ -1246,17 +1565,18 @@ template <class _Tp, class _Allocator>
 template <class... _Args>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) {
-  pointer __p = this->__begin_ + (__position - begin());
-  if (this->__end_ < this->__cap_) {
-    if (__p == this->__end_) {
+  pointer __p = __raw_begin() + (__position - begin());
+  if (!__is_full()) {
+    pointer __end = __end_pointer();
+    if (__p == __end) {
       __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
     } else {
-      __temp_value<value_type, _Allocator> __tmp(this->__alloc_, std::forward<_Args>(__args)...);
-      __move_range(__p, this->__end_, __p + 1);
+      __temp_value<value_type, _Allocator> __tmp(__allocator_ref(), std::forward<_Args>(__args)...);
+      __move_range(__p, __end, __p + 1);
       *__p = std::move(__tmp.get());
     }
   } else {
-    __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
+    __split_buffer __v(__recommend(size() + 1), __p - __raw_begin(), __allocator_ref());
     __v.emplace_back(std::forward<_Args>(__args)...);
     __p = __swap_out_circular_buffer(__v, __p);
   }
@@ -1266,25 +1586,26 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) {
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x) {
-  pointer __p = this->__begin_ + (__position - begin());
+  pointer __p = __raw_begin() + (__position - begin());
   if (__n > 0) {
-    if (__n <= static_cast<size_type>(this->__cap_ - this->__end_)) {
+    if (__n <= __remaining_capacity()) {
       size_type __old_n  = __n;
-      pointer __old_last = this->__end_;
-      if (__n > static_cast<size_type>(this->__end_ - __p)) {
-        size_type __cx = __n - (this->__end_ - __p);
+      pointer __end      = __end_pointer();
+      pointer __old_last = __end;
+      if (__n > static_cast<size_type>(__end - __p)) {
+        size_type __cx = __n - (__end - __p);
         __construct_at_end(__cx, __x);
         __n -= __cx;
       }
       if (__n > 0) {
         __move_range(__p, __old_last, __p + __old_n);
         const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
-        if (std::__is_pointer_in_range(std::__to_address(__p), std::__to_address(__end_), std::addressof(__x)))
+        if (std::__is_pointer_in_range(std::__to_address(__p), std::__to_address(__end), std::addressof(__x)))
           __xr += __old_n;
         std::fill_n(__p, __n, *__xr);
       }
     } else {
-      __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
+      __split_buffer __v(__recommend(size() + __n), __p - __raw_begin(), __allocator_ref());
       __v.__construct_at_end(__n, __x);
       __p = __swap_out_circular_buffer(__v, __p);
     }
@@ -1297,27 +1618,35 @@ template <class _InputIterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) {
   difference_type __off = __position - begin();
-  pointer __p           = this->__begin_ + __off;
-  pointer __old_last    = this->__end_;
-  for (; this->__end_ != this->__cap_ && __first != __last; ++__first)
+  pointer __p           = __raw_begin() + __off;
+  pointer __old_last    = __end_pointer();
+  for (; !__is_full() && __first != __last; ++__first)
     __emplace_back_assume_capacity(*__first);
 
   if (__first == __last)
-    (void)std::rotate(__p, __old_last, this->__end_);
+    (void)std::rotate(__p, __old_last, __end_pointer());
   else {
-    __split_buffer<value_type, allocator_type&> __v(__alloc_);
-    auto __guard = std::__make_exception_guard(
-        _AllocatorDestroyRangeReverse<allocator_type, pointer>(__alloc_, __old_last, this->__end_));
+    __split_buffer __v(__allocator_ref());
+    pointer __end = __end_pointer();
+    auto __guard  = std::__make_exception_guard(
+        _AllocatorDestroyRangeReverse<allocator_type, pointer>(__allocator_ref(), __old_last, __end));
     __v.__construct_at_end_with_sentinel(std::move(__first), std::move(__last));
-    __split_buffer<value_type, allocator_type&> __merged(
-        __recommend(size() + __v.size()), __off, __alloc_); // has `__off` positions available at the front
+    __split_buffer __merged(
+        __recommend(size() + __v.size()), __off, __allocator_ref()); // has `__off` positions available at the front
     std::__uninitialized_allocator_relocate(
-        __alloc_, std::__to_address(__old_last), std::__to_address(this->__end_), std::__to_address(__merged.end()));
-    __guard.__complete(); // Release the guard once objects in [__old_last_, __end_) have been successfully relocated.
-    __merged.__set_sentinel(__merged.end() + (this->__end_ - __old_last));
-    this->__end_ = __old_last;
+        __allocator_ref(),
+        std::__to_address(__old_last),
+        std::__to_address(__end_pointer()),
+        std::__to_address(__merged.end()));
+    __guard.__complete(); // Release the guard once objects in [__old_last_, __end_pointer()) have been successfully
+                          // relocated.
+    __merged.__set_sentinel(__merged.end() + (__end_pointer() - __old_last));
+    __set_sentinel(__old_last);
     std::__uninitialized_allocator_relocate(
-        __alloc_, std::__to_address(__v.begin()), std::__to_address(__v.end()), std::__to_address(__merged.end()));
+        __allocator_ref(),
+        std::__to_address(__v.begin()),
+        std::__to_address(__v.end()),
+        std::__to_address(__merged.end()));
     __merged.__set_sentinel(__merged.size() + __v.size());
     __v.__set_sentinel(__v.begin());
     __p        = __swap_out_circular_buffer(__merged, __p);
@@ -1330,16 +1659,17 @@ template <class _Iterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::__insert_with_size(
     const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) {
-  pointer __p = this->__begin_ + (__position - begin());
+  pointer __p = __raw_begin() + (__position - begin());
   if (__n > 0) {
-    if (__n <= this->__cap_ - this->__end_) {
-      pointer __old_last   = this->__end_;
-      difference_type __dx = this->__end_ - __p;
+    if (__n <= static_cast<difference_type>(__remaining_capacity())) {
+      pointer __end        = __end_pointer();
+      pointer __old_last   = __end;
+      difference_type __dx = __end - __p;
       if (__n > __dx) {
 #if _LIBCPP_STD_VER >= 23
         if constexpr (!forward_iterator<_Iterator>) {
           __construct_at_end(std::move(__first), std::move(__last), __n);
-          std::rotate(__p, __old_last, this->__end_);
+          std::rotate(__p, __old_last, __end);
         } else
 #endif
         {
@@ -1355,7 +1685,7 @@ vector<_Tp, _Allocator>::__insert_with_size(
         __insert_assign_n_unchecked(std::move(__first), __n, __p);
       }
     } else {
-      __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
+      __split_buffer __v(__recommend(size() + __n), __p - __raw_begin(), __allocator_ref());
       __v.__construct_at_end_with_size(std::move(__first), __n);
       __p = __swap_out_circular_buffer(__v, __p);
     }
@@ -1370,12 +1700,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __n
     if (__new_size <= capacity()) {
       __construct_at_end(__new_size - __current_size);
     } else {
-      __split_buffer<value_type, allocator_type&> __v(__recommend(__new_size), __current_size, __alloc_);
+      __split_buffer __v(__recommend(__new_size), __current_size, __allocator_ref());
       __v.__construct_at_end(__new_size - __current_size);
       __swap_out_circular_buffer(__v);
     }
   } else if (__current_size > __new_size) {
-    this->__destruct_at_end(this->__begin_ + __new_size);
+    this->__destruct_at_end(__raw_begin() + __new_size);
   }
 }
 
@@ -1386,55 +1716,21 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __n
     if (__new_size <= capacity())
       __construct_at_end(__new_size - __current_size, __x);
     else {
-      __split_buffer<value_type, allocator_type&> __v(__recommend(__new_size), __current_size, __alloc_);
+      __split_buffer __v(__recommend(__new_size), __current_size, __allocator_ref());
       __v.__construct_at_end(__new_size - __current_size, __x);
       __swap_out_circular_buffer(__v);
     }
   } else if (__current_size > __new_size) {
-    this->__destruct_at_end(this->__begin_ + __new_size);
+    this->__destruct_at_end(__raw_begin() + __new_size);
   }
 }
 
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::swap(vector& __x)
-#if _LIBCPP_STD_VER >= 14
-    _NOEXCEPT
-#else
-    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
-#endif
-{
-  _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
-      __alloc_traits::propagate_on_container_swap::value || this->__alloc_ == __x.__alloc_,
-      "vector::swap: Either propagate_on_container_swap must be true"
-      " or the allocators must compare equal");
-  std::swap(this->__begin_, __x.__begin_);
-  std::swap(this->__end_, __x.__end_);
-  std::swap(this->__cap_, __x.__cap_);
-  std::__swap_allocator(this->__alloc_, __x.__alloc_);
-}
-
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 bool vector<_Tp, _Allocator>::__invariants() const {
-  if (this->__begin_ == nullptr) {
-    if (this->__end_ != nullptr || this->__cap_ != nullptr)
-      return false;
-  } else {
-    if (this->__begin_ > this->__end_)
-      return false;
-    if (this->__begin_ == this->__cap_)
-      return false;
-    if (this->__end_ > this->__cap_)
-      return false;
-  }
-  return true;
-}
-
 #if _LIBCPP_STD_VER >= 20
-template <>
-inline constexpr bool __format::__enable_insertable<vector<char>> = true;
+template <class _Allocator>
+inline constexpr bool __format::__enable_insertable<vector<char, _Allocator>> = true;
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
-template <>
-inline constexpr bool __format::__enable_insertable<vector<wchar_t>> = true;
+template <class _Allocator>
+inline constexpr bool __format::__enable_insertable<vector<wchar_t, _Allocator>> = true;
 #  endif
 #endif // _LIBCPP_STD_VER >= 20
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp
index 85557ecbbfabc..da42ce56db30a 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp
@@ -67,22 +67,6 @@ TEST_CONSTEXPR_CXX20 void test_iterators() {
   }
 }
 
-template <std::size_t N>
-constexpr void test_vector_bool() {
-  { // Test swap_ranges() with aligned bytes
-    std::vector<bool> f(N, false), t(N, true);
-    std::ranges::swap_ranges(f, t);
-    assert(std::all_of(f.begin(), f.end(), [](bool b) { return b; }));
-    assert(std::all_of(t.begin(), t.end(), [](bool b) { return !b; }));
-  }
-  { // Test swap_ranges() with unaligned bytes
-    std::vector<bool> f(N, false), t(N + 8, true);
-    std::ranges::swap_ranges(f.begin(), f.end(), t.begin() + 4, t.end() - 4);
-    assert(std::all_of(f.begin(), f.end(), [](bool b) { return b; }));
-    assert(std::all_of(t.begin() + 4, t.end() - 4, [](bool b) { return !b; }));
-  }
-}
-
 constexpr bool test() {
   { // Validate swapping ranges directly
     std::array r1 = {1, 2, 3};
@@ -183,15 +167,34 @@ constexpr bool test() {
     });
   });
 
-  { // Test vector<bool>::iterator optimization
-    test_vector_bool<8>();
-    test_vector_bool<19>();
-    test_vector_bool<32>();
-    test_vector_bool<49>();
-    test_vector_bool<64>();
-    test_vector_bool<199>();
-    test_vector_bool<256>();
+  return true;
+}
+
+// Test vector<bool>::iterator optimization
+template <std::size_t N>
+constexpr void test_vector_bool() {
+  { // Test swap_ranges() with aligned bytes
+    std::vector<bool> f(N, false), t(N, true);
+    std::ranges::swap_ranges(f, t);
+    assert(std::all_of(f.begin(), f.end(), [](bool b) { return b; }));
+    assert(std::all_of(t.begin(), t.end(), [](bool b) { return !b; }));
   }
+  { // Test swap_ranges() with unaligned bytes
+    std::vector<bool> f(N, false), t(N + 8, true);
+    std::ranges::swap_ranges(f.begin(), f.end(), t.begin() + 4, t.end() - 4);
+    assert(std::all_of(f.begin(), f.end(), [](bool b) { return b; }));
+    assert(std::all_of(t.begin() + 4, t.end() - 4, [](bool b) { return !b; }));
+  }
+}
+
+constexpr bool test_vector_bool() {
+  test_vector_bool<8>();
+  test_vector_bool<19>();
+  test_vector_bool<32>();
+  test_vector_bool<49>();
+  test_vector_bool<64>();
+  test_vector_bool<199>();
+  test_vector_bool<256>();
   return true;
 }
 
@@ -201,5 +204,8 @@ int main(int, char**) {
   test();
   static_assert(test());
 
+  test_vector_bool();
+  static_assert(test_vector_bool());
+
   return 0;
 }
diff --git a/libcxx/utils/gdb/libcxx/printers.py b/libcxx/utils/gdb/libcxx/printers.py
index 1c8ef6d7feb97..1bfdd718e36bc 100644
--- a/libcxx/utils/gdb/libcxx/printers.py
+++ b/libcxx/utils/gdb/libcxx/printers.py
@@ -13,6 +13,7 @@
 from __future__ import print_function
 
 import re
+import sys
 import gdb
 import gdb.printing
 
@@ -351,17 +352,28 @@ def __init__(self, val):
         """Set val, length, capacity, and iterator for bool and normal vectors."""
         self.val = val
         self.typename = _remove_generics(_prettify_typename(val.type))
-        begin = self.val["__begin_"]
         if self.val.type.template_argument(0).code == gdb.TYPE_CODE_BOOL:
+            begin = self.val["__begin_"]
             self.typename += "<bool>"
             self.length = self.val["__size_"]
             bits_per_word = self.val["__bits_per_word"]
             self.capacity = self.val["__cap_"] * bits_per_word
             self.iterator = self._VectorBoolIterator(begin, self.length, bits_per_word)
         else:
-            end = self.val["__end_"]
+            for i in val.type.fields():
+                if i.is_base_class:
+                    base = val[i]
+                    break
+
+            begin = base["__begin_"]
+            end = base["__end_"]
             self.length = end - begin
-            self.capacity = self.val["__cap_"] - begin
+            for i in base.type.fields():
+                if i.name == "__cap_":
+                    self.capacity = base["__cap_"] - begin
+                elif i.name == None:
+                    self.capacity = base[i]["__cap_"] - begin
+                    break
             self.iterator = self._VectorIterator(begin, end)
 
     def to_string(self):

>From 0580dea4fe36bd54f2b6581411f4584087411c2b Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Tue, 13 Jan 2026 21:14:12 +0000
Subject: [PATCH 2/8] works `__vector_layout` into `vector`

[jyknight pointed out that we'd probably end up with a smaller diff][1]
(and simpler code) if we remove the `__vector_layout` type. [This also
reduces the volume of debuginfo, as pointed out by rnk][2].

[1]: https://github.com/llvm/llvm-project/pull/155330#discussion_r2607411335
[2]: https://github.com/llvm/llvm-project/pull/155330#discussion_r2612499610
---
 libcxx/include/__vector/vector.h | 712 ++++++++++++-------------------
 1 file changed, 281 insertions(+), 431 deletions(-)

diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index a78ee5918517d..29cd205aeb8da 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -84,334 +84,18 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
-template <class _Vector, class _Tp, class _Allocator>
-class __vector_layout {
-public:
-  using value_type                      = _Tp;
-  using allocator_type                  = _Allocator;
-  using __alloc_traits _LIBCPP_NODEBUG  = allocator_traits<allocator_type>;
-  using reference                       = value_type&;
-  using const_reference                 = const value_type&;
-  using size_type                       = typename __alloc_traits::size_type;
-  using difference_type                 = typename __alloc_traits::difference_type;
-  using pointer                         = typename __alloc_traits::pointer;
-  using const_pointer                   = typename __alloc_traits::const_pointer;
-  using __split_buffer _LIBCPP_NODEBUG  = std::__split_buffer<_Tp, _Allocator, __split_buffer_size_layout>;
-  using __sentinel_type _LIBCPP_NODEBUG = size_type;
-
-  _LIBCPP_HIDE_FROM_ABI __vector_layout() = default;
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __vector_layout(allocator_type const& __a)
-      _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
-      : __alloc_(__a) {}
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __vector_layout(allocator_type&& __a)
-      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
-      : __alloc_(std::move(__a)) {}
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __vector_layout(__vector_layout&& __other)
-      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
-      : __begin_(std::move(__other.__begin_)),
-        __size_(std::move(__other.__size_)),
-        __cap_(std::move(__other.__cap_)),
-        __alloc_(std::move(__other.__alloc_)) {
-    __other.__begin_ = nullptr;
-    __other.__size_  = 0;
-    __other.__cap_   = 0;
-  }
-
-  // Capacity
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
-    return __size_;
-  }
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
-    return __cap_;
-  }
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
-    return __size_ == 0;
-  }
-
-  // Access
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
-    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
-    return __begin_[__size_ - 1];
-  }
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
-    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
-    return __begin_[__size_ - 1];
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type& __allocator_ref() _NOEXCEPT {
-    return __alloc_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type const&
-  __allocator_ref() const _NOEXCEPT {
-    return __alloc_;
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__vector_layout& __x)
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>) {
-    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
-        __alloc_traits::propagate_on_container_swap::value || __alloc_ == __x.__alloc_,
-        "vector::swap: Either propagate_on_container_swap must be true"
-        " or the allocators must compare equal");
-    std::swap(__begin_, __x.__begin_);
-    std::swap(__size_, __x.__size_);
-    std::swap(__cap_, __x.__cap_);
-    std::__swap_allocator(__alloc_, __x.__alloc_);
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_begin() const _NOEXCEPT {
-    return __begin_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __raw_sentinel() const _NOEXCEPT {
-    return __size_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __raw_capacity() const _NOEXCEPT {
-    return __cap_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_pointer() const _NOEXCEPT {
-    return __begin_ + __size_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type
-  __remaining_capacity() const _NOEXCEPT {
-    return __cap_ - __size_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
-    return __size_ == __cap_;
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, pointer __end) _NOEXCEPT {
-    __begin_ = __begin;
-    __size_  = __end - __begin_;
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
-  __set_valid_range(pointer __begin, size_type __size) _NOEXCEPT {
-    __begin_ = __begin;
-    __size_  = __size;
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __size) _NOEXCEPT {
-    __size_ = __size;
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __pos) _NOEXCEPT {
-    __size_ = static_cast<size_type>(__pos - __begin_);
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __cap) _NOEXCEPT { __cap_ = __cap; }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __pos) _NOEXCEPT {
-    __cap_ = static_cast<size_type>(__pos - __begin_);
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
-    if (__begin_ == nullptr) {
-      if (__size_ || __cap_)
-        return false;
-    } else {
-      if (__size_ > __cap_)
-        return false;
-    }
-    return true;
-  }
-
-private:
-  pointer __begin_  = nullptr;
-  size_type __size_ = 0;
-  size_type __cap_  = 0;
-  [[no_unique_address]] allocator_type __alloc_;
-};
-#else
-template <class _Vector, class _Tp, class _Allocator>
-class __vector_layout {
-public:
-  using value_type                      = _Tp;
-  using allocator_type                  = _Allocator;
-  using __alloc_traits _LIBCPP_NODEBUG  = allocator_traits<allocator_type>;
-  using reference                       = value_type&;
-  using const_reference                 = const value_type&;
-  using size_type                       = typename __alloc_traits::size_type;
-  using difference_type                 = typename __alloc_traits::difference_type;
-  using pointer                         = typename __alloc_traits::pointer;
-  using const_pointer                   = typename __alloc_traits::const_pointer;
-  using __split_buffer _LIBCPP_NODEBUG  = std::__split_buffer<_Tp, _Allocator, __split_buffer_pointer_layout>;
-  using __sentinel_type _LIBCPP_NODEBUG = pointer;
-
-  // Can't be defaulted due to _LIBCPP_COMPRESSED_PAIR not being an aggregate in C++03 and C++11.
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __vector_layout()
-      _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-      : __cap_(nullptr) {}
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __vector_layout(allocator_type const& __a)
-      _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
-      : __cap_(nullptr), __alloc_(__a) {}
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __vector_layout(allocator_type&& __a)
-      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
-      : __cap_(nullptr), __alloc_(std::move(__a)) {}
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __vector_layout(__vector_layout&& __other)
-      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
-      : __begin_(std::move(__other.__begin_)),
-        __end_(std::move(__other.__end_)),
-        __cap_(std::move(__other.__cap_)),
-        __alloc_(std::move(__other.__alloc_)) {
-    __other.__begin_ = nullptr;
-    __other.__end_   = nullptr;
-    __other.__cap_   = nullptr;
-  }
-
-  // Capacity
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
-    return static_cast<size_type>(__end_ - __begin_);
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
-    return static_cast<size_type>(__cap_ - __begin_);
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
-    return __begin_ == __end_;
-  }
-
-  // Access
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
-    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
-    return *(__end_ - 1);
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
-    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
-    return *(__end_ - 1);
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type& __allocator_ref() _NOEXCEPT {
-    return __alloc_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type const&
-  __allocator_ref() const _NOEXCEPT {
-    return __alloc_;
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__vector_layout& __x)
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>) {
-    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
-        __alloc_traits::propagate_on_container_swap::value || __alloc_ == __x.__alloc_,
-        "vector::swap: Either propagate_on_container_swap must be true"
-        " or the allocators must compare equal");
-    std::swap(__begin_, __x.__begin_);
-    std::swap(__end_, __x.__end_);
-    std::swap(__cap_, __x.__cap_);
-    std::__swap_allocator(__alloc_, __x.__alloc_);
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_begin() const _NOEXCEPT {
-    return __begin_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_sentinel() const _NOEXCEPT {
-    return __end_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_capacity() const _NOEXCEPT {
-    return __cap_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_pointer() const _NOEXCEPT {
-    return __end_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type
-  __remaining_capacity() const _NOEXCEPT {
-    return __cap_ - __end_;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
-    return __end_ == __cap_;
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, pointer __end) _NOEXCEPT {
-    __begin_ = __begin;
-    __end_   = __end;
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
-  __set_valid_range(pointer __begin, size_type __size) _NOEXCEPT {
-    __begin_ = __begin;
-    __end_   = __begin_ + __size;
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __end) _NOEXCEPT { __end_ = __end; }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __offset) _NOEXCEPT {
-    __end_ = __begin_ + __offset;
-  }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __cap) _NOEXCEPT { __cap_ = __cap; }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __offset) _NOEXCEPT {
-    __cap_ = __begin_ + __offset;
-  }
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
-    if (__begin_ == nullptr) {
-      if (__end_ != nullptr || __cap_ != nullptr)
-        return false;
-    } else {
-      if (__begin_ > __end_)
-        return false;
-      if (__begin_ == __cap_)
-        return false;
-      if (__end_ > __cap_)
-        return false;
-    }
-    return true;
-  }
-
-private:
-  pointer __begin_ = nullptr;
-  pointer __end_   = nullptr;
-  _LIBCPP_COMPRESSED_PAIR(pointer, __cap_, allocator_type, __alloc_);
-};
-#endif // _LIBCPP_ABI_SIZE_BASED_VECTOR
-
 template <class _Tp, class _Allocator /* = allocator<_Tp> */>
-class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
-  using __base _LIBCPP_NODEBUG = __vector_layout<vector, _Tp, _Allocator>;
-  using __self _LIBCPP_NODEBUG = vector;
-  using __base::__allocator_ref;
-  using __base::__end_pointer;
-  using __base::__is_full;
-  using __base::__raw_begin;
-  using __base::__raw_capacity;
-  using __base::__raw_sentinel;
-  using __base::__remaining_capacity;
-  using __base::__set_capacity;
-  using __base::__set_sentinel;
-  using __base::__set_valid_range;
-  using typename __base::__alloc_traits;
-  using typename __base::__sentinel_type;
-  using typename __base::__split_buffer;
-
+class vector {
 public:
-  using value_type      = _Tp;
-  using allocator_type  = _Allocator;
-  using reference       = typename __base::reference;
-  using const_reference = typename __base::const_reference;
-  using size_type       = typename __base::size_type;
-  using difference_type = typename __base::difference_type;
-  using pointer         = typename __base::pointer;
-  using const_pointer   = typename __base::const_pointer;
+  using value_type                     = _Tp;
+  using allocator_type                 = _Allocator;
+  using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
+  using reference                      = value_type&;
+  using const_reference                = const value_type&;
+  using size_type                      = typename __alloc_traits::size_type;
+  using difference_type                = typename __alloc_traits::difference_type;
+  using pointer                        = typename __alloc_traits::pointer;
+  using const_pointer                  = typename __alloc_traits::const_pointer;
 #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
   // Users might provide custom allocators, and prior to C++20 we have no existing way to detect whether the allocator's
   // pointer type is contiguous (though it has to be by the Standard). Using the wrapper type ensures the iterator is
@@ -425,8 +109,6 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   using reverse_iterator       = std::reverse_iterator<iterator>;
   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
-  using __base::__invariants;
-
   // A vector contains the following members which may be trivially relocatable:
   // - pointer: may be trivially relocatable, so it's checked
   // - allocator_type: may be trivially relocatable, so it's checked
@@ -451,7 +133,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
 #else
       noexcept
 #endif
-      : __base(__a) {
+      : __alloc_(__a) {
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n) {
@@ -465,7 +147,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
 
 #if _LIBCPP_STD_VER >= 14
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n, const allocator_type& __a)
-      : __base(__a) {
+      : __alloc_(__a) {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
     if (__n > 0) {
       __vallocate(__n);
@@ -487,7 +169,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   template <__enable_if_t<__is_allocator_v<_Allocator>, int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(size_type __n, const value_type& __x, const allocator_type& __a)
-      : __base(__a) {
+      : __alloc_(__a) {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
     if (__n > 0) {
       __vallocate(__n);
@@ -510,7 +192,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
                           int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
-      : __base(__a) {
+      : __alloc_(__a) {
     __init_with_sentinel(__first, __last);
   }
 
@@ -531,7 +213,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
                     int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a)
-      : __base(__a) {
+      : __alloc_(__a) {
     size_type __n = static_cast<size_type>(std::distance(__first, __last));
     __init_with_size(__first, __last, __n);
   }
@@ -540,7 +222,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   template <_ContainerCompatibleRange<_Tp> _Range>
   _LIBCPP_HIDE_FROM_ABI constexpr vector(
       from_range_t, _Range&& __range, const allocator_type& __alloc = allocator_type())
-      : __base(__alloc) {
+      : __alloc_(__alloc) {
     if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
       auto __n = static_cast<size_type>(ranges::distance(__range));
       __init_with_size(ranges::begin(__range), ranges::end(__range), __n);
@@ -557,10 +239,10 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
     _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __destroy_vector(vector& __vec) : __vec_(__vec) {}
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() {
-      if (__vec_.__raw_begin() != nullptr) {
+      if (__vec_.__begin_ != nullptr) {
         __vec_.clear();
         __vec_.__annotate_delete();
-        __alloc_traits::deallocate(__vec_.__allocator_ref(), __vec_.__raw_begin(), __vec_.capacity());
+        __alloc_traits::deallocate(__vec_.__alloc_, __vec_.__begin_, __vec_.capacity());
       }
     }
 
@@ -572,13 +254,13 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~vector() { __destroy_vector (*this)(); }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(const vector& __x)
-      : __base(__alloc_traits::select_on_container_copy_construction(__x.__allocator_ref())) {
-    __init_with_size(__x.__raw_begin(), __x.__end_pointer(), __x.size());
+      : __alloc_(__alloc_traits::select_on_container_copy_construction(__x.__alloc_)) {
+    __init_with_size(__x.__begin_, __x.__end_pointer(), __x.size());
   }
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
-      : __base(__a) {
-    __init_with_size(__x.__raw_begin(), __x.__end_pointer(), __x.size());
+      : __alloc_(__a) {
+    __init_with_size(__x.__begin_, __x.__end_pointer(), __x.size());
   }
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector& operator=(const vector& __x);
 
@@ -589,7 +271,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(initializer_list<value_type> __il, const allocator_type& __a)
-      : __base(__a) {
+      : __alloc_(__a) {
     __init_with_size(__il.begin(), __il.end(), __il.size());
   }
 
@@ -652,17 +334,17 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
 #endif
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
-    return __allocator_ref();
+    return __alloc_;
   }
 
   //
   // Iterators
   //
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
-    return __make_iter(__add_alignment_assumption(__raw_begin()));
+    return __make_iter(__add_alignment_assumption(__begin_));
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
-    return __make_iter(__add_alignment_assumption(__raw_begin()));
+    return __make_iter(__add_alignment_assumption(__begin_));
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
     return __make_iter(__add_alignment_assumption(__end_pointer()));
@@ -704,17 +386,30 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   //
 
   // Capacity
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
-    return __base::size();
+    return __size_;
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
-    return __base::capacity();
+    return __cap_;
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
-    return __base::empty();
+    return __size_ == 0;
   }
+#else
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
+    return static_cast<size_type>(__end_ - __begin_);
+  }
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
+    return static_cast<size_type>(__cap_ - __begin_);
+  }
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
+    return __begin_ == __end_;
+  }
+#endif // _LIBCPP_ABI_SIZE_BASED_VECTOR
+
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
-    return std::min<size_type>(__alloc_traits::max_size(__allocator_ref()), numeric_limits<difference_type>::max());
+    return std::min<size_type>(__alloc_traits::max_size(__alloc_), numeric_limits<difference_type>::max());
   }
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
@@ -724,48 +419,62 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   //
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __n) _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
-    return __raw_begin()[__n];
+    return __begin_[__n];
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference
   operator[](size_type __n) const _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
-    return __raw_begin()[__n];
+    return __begin_[__n];
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference at(size_type __n) {
     if (__n >= size())
       this->__throw_out_of_range();
-    return __raw_begin()[__n];
+    return __begin_[__n];
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const {
     if (__n >= size())
       this->__throw_out_of_range();
-    return __raw_begin()[__n];
+    return __begin_[__n];
   }
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
-    return *__raw_begin();
+    return *__begin_;
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
-    return *__raw_begin();
+    return *__begin_;
   }
+
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
-    return __base::back();
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
+    return __begin_[__size_ - 1];
+  }
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
+    return __begin_[__size_ - 1];
+  }
+#else
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
+    return *(__end_ - 1);
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
-    return __base::back();
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
+    return *(__end_ - 1);
   }
+#endif // _LIBCPP_ABI_SIZE_BASED_VECTOR
 
   //
   // [vector.data], data access
   //
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI value_type* data() _NOEXCEPT {
-    return std::__to_address(__raw_begin());
+    return std::__to_address(__begin_);
   }
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT {
-    return std::__to_address(__raw_begin());
+    return std::__to_address(__begin_);
   }
 
   //
@@ -790,7 +499,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
     _LIBCPP_ASSERT_INTERNAL(
         size() < capacity(), "We assume that we have enough space to insert an element at the end of the vector");
     _ConstructTransaction __tx(*this, 1);
-    __alloc_traits::construct(__allocator_ref(), std::__to_address(__tx.__pos_), std::forward<_Args>(__args)...);
+    __alloc_traits::construct(__alloc_, std::__to_address(__tx.__pos_), std::forward<_Args>(__args)...);
     ++__tx.__pos_;
   }
 
@@ -802,12 +511,12 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
       if (__len < __raw_capacity() - __raw_sentinel()) {
         __construct_at_end(ranges::begin(__range), ranges::end(__range), __len);
       } else {
-        __split_buffer __buffer(__recommend(size() + __len), size(), __allocator_ref());
+        __split_buffer __buffer(__recommend(size() + __len), size(), __alloc_);
         __buffer.__construct_at_end_with_size(ranges::begin(__range), __len);
         __swap_out_circular_buffer(__buffer);
       }
     } else {
-      vector __buffer(__allocator_ref());
+      vector __buffer(__alloc_);
       for (auto&& __val : __range)
         __buffer.emplace_back(std::forward<decltype(__val)>(__val));
       append_range(ranges::as_rvalue_view(__buffer));
@@ -873,7 +582,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
     size_type __old_size = size();
-    __base_destruct_at_end(__raw_begin());
+    __base_destruct_at_end(__begin_);
     __annotate_shrink(__old_size);
   }
 
@@ -887,10 +596,151 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
       _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
 #endif
   {
-    __base::swap(__other);
+    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
+        __alloc_traits::propagate_on_container_swap::value || __alloc_ == __other.__alloc_,
+        "vector::swap: Either propagate_on_container_swap must be true"
+        " or the allocators must compare equal");
+    std::swap(__begin_, __other.__begin_);
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+		std::swap(__size_, __other.__size_);
+#else
+    std::swap(__end_, __other.__end_);
+#endif
+    std::swap(__cap_, __other.__cap_);
+    std::__swap_allocator(__alloc_, __other.__alloc_);
+  }
+
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+public:
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
+    if (__begin_ == nullptr) {
+      if (__size_ != 0 || __cap_ != 0)
+        return false;
+    } else {
+      if (__size_ > __cap_)
+        return false;
+    }
+    return true;
+  }
+private:
+	using __sentinel_type _LIBCPP_NODEBUG = size_type;
+	using __split_buffer _LIBCPP_NODEBUG = __split_buffer<_Tp, _Allocator, __split_buffer_size_layout>;
+
+	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __raw_sentinel() const _NOEXCEPT {
+    return __size_;
+	}
+
+	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_pointer() const _NOEXCEPT {
+		return __begin_ + __size_;
+	}
+
+	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __remaining_capacity() const _NOEXCEPT {
+		return __cap_ - __size_;
+	}
+
+	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
+    return __size_ == __cap_;
+  }
+
+	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, pointer __end) _NOEXCEPT {
+    __begin_ = __begin;
+    __size_ = __end - __begin_;
+	}
+
+	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, size_type __size) _NOEXCEPT {
+    __begin_ = __begin;
+    __size_  = __size;
+  }
+
+	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __size) _NOEXCEPT {
+    __size_ = __size;
   }
 
+	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __pos) _NOEXCEPT {
+    __size_ = static_cast<size_type>(__pos - __begin_);
+	}
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __cap) _NOEXCEPT { __cap_ = __cap; }
+
+	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __pos) _NOEXCEPT {
+    __cap_ = static_cast<size_type>(__pos - __begin_);
+	}
+
+	pointer __begin_  = nullptr;
+	size_type __size_ = 0;
+	size_type __cap_  = 0;
+	[[no_unique_address]] allocator_type __alloc_;
+#else
+public:
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
+    if (__begin_ == nullptr) {
+      if (__end_ != nullptr || __cap_ != nullptr)
+        return false;
+    } else {
+      if (__begin_ > __end_)
+        return false;
+      if (__begin_ == __cap_)
+        return false;
+      if (__end_ > __cap_)
+        return false;
+    }
+    return true;
+  }
 private:
+	using __split_buffer _LIBCPP_NODEBUG = __split_buffer<_Tp, _Allocator, __split_buffer_pointer_layout>;
+	using __sentinel_type _LIBCPP_NODEBUG = pointer;
+
+	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_sentinel() const _NOEXCEPT {
+    return __end_;
+  }
+
+	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_pointer() const _NOEXCEPT {
+		return __end_;
+	}
+
+	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __remaining_capacity() const _NOEXCEPT {
+		return __end_;
+	}
+
+	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
+    return __end_ == __cap_;
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, pointer __end) _NOEXCEPT {
+    __begin_ = __begin;
+    __end_   = __end;
+  }
+
+	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, size_type __size) _NOEXCEPT {
+    __begin_ = __begin;
+    __end_   = __begin_ + __size;
+  }
+
+	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __end) _NOEXCEPT { __end_ = __end; }
+
+	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __pos) _NOEXCEPT {
+    __end_ = __begin_ + __offset;
+	}
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __cap) _NOEXCEPT { __cap_ = __cap; }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __offset) _NOEXCEPT {
+    __cap_ = __begin_ + __offset;
+  }
+
+	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __offset) _NOEXCEPT {
+    __cap_ = __begin_ + __offset;
+  }
+
+	pointer __begin_ = nullptr;
+	pointer __end_   = nullptr;
+	_LIBCPP_COMPRESSED_PAIR(pointer, __cap_ = nullptr, allocator_type, __alloc_);
+#endif // _LIBCPP_ABI_SIZE_BASED_VECTOR
+
+	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __sentinel_type __raw_capacity() const _NOEXCEPT {
+    return __cap_;
+  }
+
   //  Allocate space for __n objects
   //  throws length_error if __n > max_size()
   //  throws (probably bad_alloc) if memory run out
@@ -903,7 +753,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __vallocate(size_type __n) {
     if (__n > max_size())
       this->__throw_length_error();
-    auto __allocation = std::__allocate_at_least(__allocator_ref(), __n);
+    auto __allocation = std::__allocate_at_least(__alloc_, __n);
     __set_valid_range(__allocation.ptr, static_cast<size_type>(0));
     __set_capacity(__allocation.count);
     __annotate_new(0);
@@ -954,7 +804,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
   __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
     for (pointer __end_position = __position + __n; __position != __end_position; ++__position, (void)++__first) {
-      __temp_value<value_type, _Allocator> __tmp(__allocator_ref(), *__first);
+      __temp_value<value_type, _Allocator> __tmp(__alloc_, *__first);
       *__position = std::move(__tmp.get());
     }
   }
@@ -992,7 +842,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
     // a laxer approach.
     return std::__make_bounded_iter(
         std::__wrap_iter<pointer>(__p),
-        std::__wrap_iter<pointer>(__raw_begin()),
+        std::__wrap_iter<pointer>(__begin_),
         std::__wrap_iter<pointer>(__raw_capacity()));
 #else
     return iterator(__p);
@@ -1004,7 +854,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
     // Bound the iterator according to the capacity, rather than the size.
     return std::__make_bounded_iter(
         std::__wrap_iter<const_pointer>(__p),
-        std::__wrap_iter<const_pointer>(__raw_begin()),
+        std::__wrap_iter<const_pointer>(__begin_),
         std::__wrap_iter<const_pointer>(__raw_capacity()));
 #else
     return const_iterator(__p);
@@ -1068,7 +918,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() {
       __v_.__set_sentinel(__pos_);
       if (__pos_ != __new_end_) {
-        __v_.__annotate_shrink(__new_end_ - __v_.__raw_begin());
+        __v_.__annotate_shrink(__new_end_ - __v_.__begin_);
       }
     }
 
@@ -1083,7 +933,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __base_destruct_at_end(pointer __new_last) _NOEXCEPT {
     pointer __soon_to_be_end = __end_pointer();
     while (__new_last != __soon_to_be_end)
-      __alloc_traits::destroy(__allocator_ref(), std::__to_address(--__soon_to_be_end));
+      __alloc_traits::destroy(__alloc_, std::__to_address(--__soon_to_be_end));
     __set_sentinel(__new_last);
   }
 
@@ -1102,21 +952,21 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   [[__noreturn__]] _LIBCPP_HIDE_FROM_ABI static void __throw_out_of_range() { std::__throw_out_of_range("vector"); }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector& __c, true_type) {
-    if (__allocator_ref() != __c.__allocator_ref()) {
+    if (__alloc_ != __c.__alloc_) {
       clear();
       __annotate_delete();
-      __alloc_traits::deallocate(__allocator_ref(), __raw_begin(), capacity());
+      __alloc_traits::deallocate(__alloc_, __begin_, capacity());
       __set_valid_range(nullptr, static_cast<size_type>(0));
       __set_capacity(static_cast<__sentinel_type>(0));
     }
-    __allocator_ref() = __c.__allocator_ref();
+    __alloc_ = __c.__alloc_;
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector&, false_type) {}
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c, true_type)
       _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
-    __allocator_ref() = std::move(__c.__allocator_ref());
+    __alloc_ = std::move(__c.__alloc_);
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector&, false_type) _NOEXCEPT {}
@@ -1137,7 +987,7 @@ class vector : __vector_layout<vector<_Tp, _Allocator>, _Tp, _Allocator> {
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_layouts(__split_buffer& __sb) {
-    auto __vector_begin    = __raw_begin();
+    auto __vector_begin    = __begin_;
     auto __vector_sentinel = __raw_sentinel();
     auto __vector_cap      = __raw_capacity();
 
@@ -1174,7 +1024,7 @@ template <ranges::input_range _Range,
 vector(from_range_t, _Range&&, _Alloc = _Alloc()) -> vector<ranges::range_value_t<_Range>, _Alloc>;
 #endif
 
-// __swap_out_circular_buffer relocates the objects in [__raw_begin(), size()) into the front of __v and swaps the
+// __swap_out_circular_buffer relocates the objects in [__begin_, size()) into the front of __v and swaps the
 // buffers of *this and __v. It is assumed that __v provides space for exactly size() objects in the front. This
 // function has a strong exception guarantee.
 template <class _Tp, class _Allocator>
@@ -1182,8 +1032,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__swap_out_circular_
   __annotate_delete();
   auto __new_begin = __v.begin() - size();
   std::__uninitialized_allocator_relocate(
-      __allocator_ref(),
-      std::__to_address(__raw_begin()),
+      __alloc_,
+      std::__to_address(__begin_),
       std::__to_address(__end_pointer()),
       std::__to_address(__new_begin));
   __v.__set_valid_range(__new_begin, __v.end());
@@ -1195,10 +1045,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__swap_out_circular_
   __annotate_new(size());
 }
 
-// __swap_out_circular_buffer relocates the objects in [__raw_begin(), __p) into the front of __v, the objects in
+// __swap_out_circular_buffer relocates the objects in [__begin_, __p) into the front of __v, the objects in
 // [__p, end()) into the back of __v and swaps the buffers of *this and __v. It is assumed that __v provides space for
-// exactly (__p - __raw_begin()) objects in the front and space for at least (size() - __p) objects in the back. This
-// function has a strong exception guarantee if __raw_begin() == __p || size() == __p.
+// exactly (__p - __begin_) objects in the front and space for at least (size() - __p) objects in the back. This
+// function has a strong exception guarantee if __begin_ == __p || size() == __p.
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer
 vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v, pointer __p) {
@@ -1206,18 +1056,18 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v, pointer
   pointer __ret = __v.begin();
 
   pointer __end = __end_pointer();
-  // Relocate [__p, __end) first to avoid having a hole in [__raw_begin(), __end)
-  // in case something in [__raw_begin(), __p) throws.
+  // Relocate [__p, __end) first to avoid having a hole in [__begin_, __end)
+  // in case something in [__begin_, __p) throws.
   std::__uninitialized_allocator_relocate(
-      __allocator_ref(), std::__to_address(__p), std::__to_address(__end), std::__to_address(__v.end()));
+      __alloc_, std::__to_address(__p), std::__to_address(__end), std::__to_address(__v.end()));
   auto __relocated_so_far = __end - __p;
   __v.__set_sentinel(__v.end() + __relocated_so_far);
   __set_sentinel(
       __raw_sentinel() - __relocated_so_far); // The objects in [__p, __end_) have been destroyed by relocating them.
-  auto __new_begin = __v.begin() - (__p - __raw_begin());
+  auto __new_begin = __v.begin() - (__p - __begin_);
 
   std::__uninitialized_allocator_relocate(
-      __allocator_ref(), std::__to_address(__raw_begin()), std::__to_address(__p), std::__to_address(__new_begin));
+      __alloc_, std::__to_address(__begin_), std::__to_address(__p), std::__to_address(__new_begin));
   __v.__set_valid_range(__new_begin, __v.size() + size());
   __set_sentinel(static_cast<size_type>(0)); // All the objects have been destroyed by relocating them.
 
@@ -1229,10 +1079,10 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v, pointer
 
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT {
-  if (__raw_begin() != nullptr) {
+  if (__begin_ != nullptr) {
     clear();
     __annotate_delete();
-    __alloc_traits::deallocate(__allocator_ref(), __raw_begin(), capacity());
+    __alloc_traits::deallocate(__alloc_, __begin_, capacity());
     __set_valid_range(nullptr, static_cast<size_type>(0));
     __set_capacity(static_cast<size_type>(0));
   }
@@ -1261,7 +1111,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(s
   _ConstructTransaction __tx(*this, __n);
   const_pointer __new_end = __tx.__new_end_;
   for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
-    __alloc_traits::construct(__allocator_ref(), std::__to_address(__pos));
+    __alloc_traits::construct(__alloc_, std::__to_address(__pos));
   }
 }
 
@@ -1277,7 +1127,7 @@ vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
   _ConstructTransaction __tx(*this, __n);
   const_pointer __new_end = __tx.__new_end_;
   for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
-    __alloc_traits::construct(__allocator_ref(), std::__to_address(__pos), __x);
+    __alloc_traits::construct(__alloc_, std::__to_address(__pos), __x);
   }
 }
 
@@ -1287,7 +1137,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
   _ConstructTransaction __tx(*this, __n);
   __tx.__pos_ =
-      std::__uninitialized_allocator_copy(__allocator_ref(), std::move(__first), std::move(__last), __tx.__pos_);
+      std::__uninitialized_allocator_copy(__alloc_, std::move(__first), std::move(__last), __tx.__pos_);
 }
 
 template <class _Tp, class _Allocator>
@@ -1297,8 +1147,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocato
 #else
     _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
 #endif
-    : __base(std::move(__x.__allocator_ref())) {
-  __set_valid_range(__x.__raw_begin(), __x.__raw_sentinel());
+    : __alloc_(std::move(__x.__alloc_)) {
+  __set_valid_range(__x.__begin_, __x.__raw_sentinel());
   __set_capacity(__x.__raw_capacity());
   __x.__set_valid_range(nullptr, static_cast<size_type>(0));
   __x.__set_capacity(static_cast<size_type>(0));
@@ -1307,9 +1157,9 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocato
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI
 vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_type>& __a)
-    : __base(__a) {
-  if (__a == __x.__allocator_ref()) {
-    __set_valid_range(__x.__raw_begin(), __x.__raw_sentinel());
+    : __alloc_(__a) {
+  if (__a == __x.__alloc_) {
+    __set_valid_range(__x.__begin_, __x.__raw_sentinel());
     __set_capacity(__x.__raw_capacity());
     __x.__set_valid_range(nullptr, static_cast<size_type>(0));
     __x.__set_capacity(static_cast<size_type>(0));
@@ -1322,7 +1172,7 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type)
     _NOEXCEPT_(__alloc_traits::is_always_equal::value) {
-  if (__allocator_ref() != __c.__allocator_ref()) {
+  if (__alloc_ != __c.__alloc_) {
     typedef move_iterator<iterator> _Ip;
     assign(_Ip(__c.begin()), _Ip(__c.end()));
   } else
@@ -1334,7 +1184,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector
     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
   __vdeallocate();
   __move_assign_alloc(__c); // this can throw
-  __set_valid_range(__c.__raw_begin(), __c.__raw_sentinel());
+  __set_valid_range(__c.__begin_, __c.__raw_sentinel());
   __set_capacity(__c.__raw_capacity());
   __c.__set_valid_range(nullptr, static_cast<size_type>(0));
   __c.__set_capacity(static_cast<size_type>(0));
@@ -1345,7 +1195,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocato
 vector<_Tp, _Allocator>::operator=(const vector& __x) {
   if (this != std::addressof(__x)) {
     __copy_assign_alloc(__x);
-    assign(__x.__raw_begin(), __x.__end_pointer());
+    assign(__x.__begin_, __x.__end_pointer());
   }
   return *this;
 }
@@ -1354,7 +1204,7 @@ template <class _Tp, class _Allocator>
 template <class _Iterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
 vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) {
-  pointer __cur = __raw_begin();
+  pointer __cur = __begin_;
   pointer __end = __end_pointer();
   for (; __first != __last && __cur != __end; ++__first, (void)++__cur)
     *__cur = *__first;
@@ -1374,10 +1224,10 @@ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last,
   if (__new_size <= capacity()) {
     if (__new_size > size()) {
       auto const __size = size();
-      auto __mid = std::__copy_n<_AlgPolicy>(std::move(__first), __size, __raw_begin()).first;
+      auto __mid = std::__copy_n<_AlgPolicy>(std::move(__first), __size, __begin_).first;
       __construct_at_end(std::move(__mid), std::move(__last), __new_size - __size);
     } else {
-      pointer __m = std::__copy(std::move(__first), __last, __raw_begin()).second;
+      pointer __m = std::__copy(std::move(__first), __last, __begin_).second;
       this->__destruct_at_end(__m);
     }
   } else {
@@ -1391,11 +1241,11 @@ template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u) {
   if (__n <= capacity()) {
     size_type __s = size();
-    std::fill_n(__raw_begin(), std::min(__n, __s), __u);
+    std::fill_n(__begin_, std::min(__n, __s), __u);
     if (__n > __s)
       __construct_at_end(__n - __s, __u);
     else
-      this->__destruct_at_end(__raw_begin() + __n);
+      this->__destruct_at_end(__begin_ + __n);
   } else {
     __vdeallocate();
     __vallocate(__recommend(static_cast<size_type>(__n)));
@@ -1408,7 +1258,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::reserve(size_type __
   if (__n > capacity()) {
     if (__n > max_size())
       this->__throw_length_error();
-    __split_buffer __v(__n, size(), __allocator_ref());
+    __split_buffer __v(__n, size(), __alloc_);
     __swap_out_circular_buffer(__v);
   }
 }
@@ -1419,7 +1269,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::shrink_to_fit() _NOE
 #if _LIBCPP_HAS_EXCEPTIONS
     try {
 #endif // _LIBCPP_HAS_EXCEPTIONS
-      __split_buffer __v(size(), size(), __allocator_ref());
+      __split_buffer __v(size(), size(), __alloc_);
       // The Standard mandates shrink_to_fit() does not increase the capacity.
       // With equal capacity keep the existing buffer. This avoids extra work
       // due to swapping the elements.
@@ -1436,10 +1286,10 @@ template <class _Tp, class _Allocator>
 template <class... _Args>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::__sentinel_type
 vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) {
-  __split_buffer __v(__recommend(size() + 1), size(), __allocator_ref());
+  __split_buffer __v(__recommend(size() + 1), size(), __alloc_);
   //    __v.emplace_back(std::forward<_Args>(__args)...);
   pointer __end = __v.end();
-  __alloc_traits::construct(__allocator_ref(), std::__to_address(__end), std::forward<_Args>(__args)...);
+  __alloc_traits::construct(__alloc_, std::__to_address(__end), std::forward<_Args>(__args)...);
   __v.__set_sentinel(++__end);
   __swap_out_circular_buffer(__v);
   return __raw_sentinel();
@@ -1493,7 +1343,7 @@ vector<_Tp, _Allocator>::erase(const_iterator __position) {
   _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
       __position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator");
   difference_type __ps = __position - cbegin();
-  pointer __p          = __raw_begin() + __ps;
+  pointer __p          = __begin_ + __ps;
   this->__destruct_at_end(std::move(__p + 1, __end_pointer(), __p));
   return __make_iter(__p);
 }
@@ -1502,7 +1352,7 @@ template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) {
   _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range");
-  pointer __p = __raw_begin() + (__first - begin());
+  pointer __p = __begin_ + (__first - begin());
   if (__first != __last) {
     this->__destruct_at_end(std::move(__p + (__last - __first), __end_pointer(), __p));
   }
@@ -1518,7 +1368,7 @@ vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointe
     pointer __i = __from_s + __n;
     _ConstructTransaction __tx(*this, __from_e - __i);
     for (pointer __pos = __tx.__pos_; __i < __from_e; ++__i, (void)++__pos, __tx.__pos_ = __pos) {
-      __alloc_traits::construct(__allocator_ref(), std::__to_address(__pos), std::move(*__i));
+      __alloc_traits::construct(__alloc_, std::__to_address(__pos), std::move(*__i));
     }
   }
   std::move_backward(__from_s, __from_s + __n, __old_last);
@@ -1527,7 +1377,7 @@ vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointe
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) {
-  pointer __p = __raw_begin() + (__position - begin());
+  pointer __p = __begin_ + (__position - begin());
   if (!__is_full()) {
     pointer __end = __end_pointer();
     if (__p == __end) {
@@ -1540,7 +1390,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
       *__p = *__xr;
     }
   } else {
-    __split_buffer __v(__recommend(size() + 1), __p - __raw_begin(), __allocator_ref());
+    __split_buffer __v(__recommend(size() + 1), __p - __begin_, __alloc_);
     __v.emplace_back(__x);
     __p = __swap_out_circular_buffer(__v, __p);
   }
@@ -1550,7 +1400,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) {
-  pointer __p = __raw_begin() + (__position - begin());
+  pointer __p = __begin_ + (__position - begin());
   if (!__is_full()) {
     pointer __end = __end_pointer();
     if (__p == __end) {
@@ -1560,7 +1410,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) {
       *__p = std::move(__x);
     }
   } else {
-    __split_buffer __v(__recommend(size() + 1), __p - __raw_begin(), __allocator_ref());
+    __split_buffer __v(__recommend(size() + 1), __p - __begin_, __alloc_);
     __v.emplace_back(std::move(__x));
     __p = __swap_out_circular_buffer(__v, __p);
   }
@@ -1571,18 +1421,18 @@ template <class _Tp, class _Allocator>
 template <class... _Args>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) {
-  pointer __p = __raw_begin() + (__position - begin());
+  pointer __p = __begin_ + (__position - begin());
   if (!__is_full()) {
     pointer __end = __end_pointer();
     if (__p == __end) {
       __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
     } else {
-      __temp_value<value_type, _Allocator> __tmp(__allocator_ref(), std::forward<_Args>(__args)...);
+      __temp_value<value_type, _Allocator> __tmp(__alloc_, std::forward<_Args>(__args)...);
       __move_range(__p, __end, __p + 1);
       *__p = std::move(__tmp.get());
     }
   } else {
-    __split_buffer __v(__recommend(size() + 1), __p - __raw_begin(), __allocator_ref());
+    __split_buffer __v(__recommend(size() + 1), __p - __begin_, __alloc_);
     __v.emplace_back(std::forward<_Args>(__args)...);
     __p = __swap_out_circular_buffer(__v, __p);
   }
@@ -1592,7 +1442,7 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) {
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x) {
-  pointer __p = __raw_begin() + (__position - begin());
+  pointer __p = __begin_ + (__position - begin());
   if (__n > 0) {
     if (__n <= __remaining_capacity()) {
       size_type __old_n  = __n;
@@ -1611,7 +1461,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_
         std::fill_n(__p, __n, *__xr);
       }
     } else {
-      __split_buffer __v(__recommend(size() + __n), __p - __raw_begin(), __allocator_ref());
+      __split_buffer __v(__recommend(size() + __n), __p - __begin_, __alloc_);
       __v.__construct_at_end(__n, __x);
       __p = __swap_out_circular_buffer(__v, __p);
     }
@@ -1624,7 +1474,7 @@ template <class _InputIterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) {
   difference_type __off = __position - begin();
-  pointer __p           = __raw_begin() + __off;
+  pointer __p           = __begin_ + __off;
   pointer __old_last    = __end_pointer();
   for (; !__is_full() && __first != __last; ++__first)
     __emplace_back_assume_capacity(*__first);
@@ -1632,15 +1482,15 @@ vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _Inpu
   if (__first == __last)
     (void)std::rotate(__p, __old_last, __end_pointer());
   else {
-    __split_buffer __v(__allocator_ref());
+    __split_buffer __v(__alloc_);
     pointer __end = __end_pointer();
     auto __guard  = std::__make_exception_guard(
-        _AllocatorDestroyRangeReverse<allocator_type, pointer>(__allocator_ref(), __old_last, __end));
+        _AllocatorDestroyRangeReverse<allocator_type, pointer>(__alloc_, __old_last, __end));
     __v.__construct_at_end_with_sentinel(std::move(__first), std::move(__last));
     __split_buffer __merged(
-        __recommend(size() + __v.size()), __off, __allocator_ref()); // has `__off` positions available at the front
+        __recommend(size() + __v.size()), __off, __alloc_); // has `__off` positions available at the front
     std::__uninitialized_allocator_relocate(
-        __allocator_ref(),
+        __alloc_,
         std::__to_address(__old_last),
         std::__to_address(__end_pointer()),
         std::__to_address(__merged.end()));
@@ -1649,7 +1499,7 @@ vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _Inpu
     __merged.__set_sentinel(__merged.end() + (__end_pointer() - __old_last));
     __set_sentinel(__old_last);
     std::__uninitialized_allocator_relocate(
-        __allocator_ref(),
+        __alloc_,
         std::__to_address(__v.begin()),
         std::__to_address(__v.end()),
         std::__to_address(__merged.end()));
@@ -1665,7 +1515,7 @@ template <class _AlgPolicy, class _Iterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::__insert_with_size(
     const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) {
-  pointer __p = __raw_begin() + (__position - begin());
+  pointer __p = __begin_ + (__position - begin());
   if (__n > 0) {
     if (__n <= static_cast<difference_type>(__remaining_capacity())) {
       pointer __end        = __end_pointer();
@@ -1691,7 +1541,7 @@ vector<_Tp, _Allocator>::__insert_with_size(
         __insert_assign_n_unchecked<_AlgPolicy>(std::move(__first), __n, __p);
       }
     } else {
-      __split_buffer __v(__recommend(size() + __n), __p - __raw_begin(), __allocator_ref());
+      __split_buffer __v(__recommend(size() + __n), __p - __begin_, __alloc_);
       __v.__construct_at_end_with_size(std::move(__first), __n);
       __p = __swap_out_circular_buffer(__v, __p);
     }
@@ -1706,12 +1556,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __n
     if (__new_size <= capacity()) {
       __construct_at_end(__new_size - __current_size);
     } else {
-      __split_buffer __v(__recommend(__new_size), __current_size, __allocator_ref());
+      __split_buffer __v(__recommend(__new_size), __current_size, __alloc_);
       __v.__construct_at_end(__new_size - __current_size);
       __swap_out_circular_buffer(__v);
     }
   } else if (__current_size > __new_size) {
-    this->__destruct_at_end(__raw_begin() + __new_size);
+    this->__destruct_at_end(__begin_ + __new_size);
   }
 }
 
@@ -1722,12 +1572,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __n
     if (__new_size <= capacity())
       __construct_at_end(__new_size - __current_size, __x);
     else {
-      __split_buffer __v(__recommend(__new_size), __current_size, __allocator_ref());
+      __split_buffer __v(__recommend(__new_size), __current_size, __alloc_);
       __v.__construct_at_end(__new_size - __current_size, __x);
       __swap_out_circular_buffer(__v);
     }
   } else if (__current_size > __new_size) {
-    this->__destruct_at_end(__raw_begin() + __new_size);
+    this->__destruct_at_end(__begin_ + __new_size);
   }
 }
 

>From f502629b7f53444056ef164cb057e2d321e1ea05 Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Tue, 13 Jan 2026 22:48:54 +0000
Subject: [PATCH 3/8] further reduces the diff

0580dea significantly reduced the diff by returning the stable ABI code
to its original location. `__vector_base` did away with using `this->`
for most things, since it's largely redundant, but these were left out
in 0580dea. This commit adds most of those back.
---
 libcxx/include/__vector/vector.h | 194 ++++++++++++++++---------------
 1 file changed, 100 insertions(+), 94 deletions(-)

diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 29cd205aeb8da..28465a6b4c44d 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -334,17 +334,17 @@ class vector {
 #endif
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
-    return __alloc_;
+    return this->__alloc_;
   }
 
   //
   // Iterators
   //
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
-    return __make_iter(__add_alignment_assumption(__begin_));
+    return __make_iter(__add_alignment_assumption(this->__begin_));
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
-    return __make_iter(__add_alignment_assumption(__begin_));
+    return __make_iter(__add_alignment_assumption(this->__begin_));
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
     return __make_iter(__add_alignment_assumption(__end_pointer()));
@@ -398,18 +398,18 @@ class vector {
   }
 #else
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
-    return static_cast<size_type>(__end_ - __begin_);
+    return static_cast<size_type>(this->__end_ - this->__begin_);
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
-    return static_cast<size_type>(__cap_ - __begin_);
+    return static_cast<size_type>(this->__cap_ - this->__begin_);
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
-    return __begin_ == __end_;
+    return this->__begin_ == this->__end_;
   }
 #endif // _LIBCPP_ABI_SIZE_BASED_VECTOR
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
-    return std::min<size_type>(__alloc_traits::max_size(__alloc_), numeric_limits<difference_type>::max());
+    return std::min<size_type>(__alloc_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max());
   }
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
@@ -419,31 +419,31 @@ class vector {
   //
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __n) _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
-    return __begin_[__n];
+    return this->__begin_[__n];
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference
   operator[](size_type __n) const _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
-    return __begin_[__n];
+    return this->__begin_[__n];
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference at(size_type __n) {
     if (__n >= size())
       this->__throw_out_of_range();
-    return __begin_[__n];
+    return this->__begin_[__n];
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const {
     if (__n >= size())
       this->__throw_out_of_range();
-    return __begin_[__n];
+    return this->__begin_[__n];
   }
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
-    return *__begin_;
+    return *this->__begin_;
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
-    return *__begin_;
+    return *this->__begin_;
   }
 
 #ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
@@ -458,11 +458,11 @@ class vector {
 #else
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
-    return *(__end_ - 1);
+    return *(this->__end_ - 1);
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
-    return *(__end_ - 1);
+    return *(this->__end_ - 1);
   }
 #endif // _LIBCPP_ABI_SIZE_BASED_VECTOR
 
@@ -470,11 +470,11 @@ class vector {
   // [vector.data], data access
   //
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI value_type* data() _NOEXCEPT {
-    return std::__to_address(__begin_);
+    return std::__to_address(this->__begin_);
   }
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT {
-    return std::__to_address(__begin_);
+    return std::__to_address(this->__begin_);
   }
 
   //
@@ -499,7 +499,7 @@ class vector {
     _LIBCPP_ASSERT_INTERNAL(
         size() < capacity(), "We assume that we have enough space to insert an element at the end of the vector");
     _ConstructTransaction __tx(*this, 1);
-    __alloc_traits::construct(__alloc_, std::__to_address(__tx.__pos_), std::forward<_Args>(__args)...);
+    __alloc_traits::construct(this->__alloc_, std::__to_address(__tx.__pos_), std::forward<_Args>(__args)...);
     ++__tx.__pos_;
   }
 
@@ -582,7 +582,7 @@ class vector {
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
     size_type __old_size = size();
-    __base_destruct_at_end(__begin_);
+    __base_destruct_at_end(this->__begin_);
     __annotate_shrink(__old_size);
   }
 
@@ -610,18 +610,10 @@ class vector {
     std::__swap_allocator(__alloc_, __other.__alloc_);
   }
 
+
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
+
 #ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
-public:
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
-    if (__begin_ == nullptr) {
-      if (__size_ != 0 || __cap_ != 0)
-        return false;
-    } else {
-      if (__size_ > __cap_)
-        return false;
-    }
-    return true;
-  }
 private:
 	using __sentinel_type _LIBCPP_NODEBUG = size_type;
 	using __split_buffer _LIBCPP_NODEBUG = __split_buffer<_Tp, _Allocator, __split_buffer_size_layout>;
@@ -671,21 +663,6 @@ class vector {
 	size_type __cap_  = 0;
 	[[no_unique_address]] allocator_type __alloc_;
 #else
-public:
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
-    if (__begin_ == nullptr) {
-      if (__end_ != nullptr || __cap_ != nullptr)
-        return false;
-    } else {
-      if (__begin_ > __end_)
-        return false;
-      if (__begin_ == __cap_)
-        return false;
-      if (__end_ > __cap_)
-        return false;
-    }
-    return true;
-  }
 private:
 	using __split_buffer _LIBCPP_NODEBUG = __split_buffer<_Tp, _Allocator, __split_buffer_pointer_layout>;
 	using __sentinel_type _LIBCPP_NODEBUG = pointer;
@@ -753,7 +730,7 @@ class vector {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __vallocate(size_type __n) {
     if (__n > max_size())
       this->__throw_length_error();
-    auto __allocation = std::__allocate_at_least(__alloc_, __n);
+    auto __allocation = std::__allocate_at_least(this->__alloc_, __n);
     __set_valid_range(__allocation.ptr, static_cast<size_type>(0));
     __set_capacity(__allocation.count);
     __annotate_new(0);
@@ -804,7 +781,7 @@ class vector {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
   __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
     for (pointer __end_position = __position + __n; __position != __end_position; ++__position, (void)++__first) {
-      __temp_value<value_type, _Allocator> __tmp(__alloc_, *__first);
+      __temp_value<value_type, _Allocator> __tmp(this->__alloc_, *__first);
       *__position = std::move(__tmp.get());
     }
   }
@@ -842,7 +819,7 @@ class vector {
     // a laxer approach.
     return std::__make_bounded_iter(
         std::__wrap_iter<pointer>(__p),
-        std::__wrap_iter<pointer>(__begin_),
+        std::__wrap_iter<pointer>(this->__begin_),
         std::__wrap_iter<pointer>(__raw_capacity()));
 #else
     return iterator(__p);
@@ -854,7 +831,7 @@ class vector {
     // Bound the iterator according to the capacity, rather than the size.
     return std::__make_bounded_iter(
         std::__wrap_iter<const_pointer>(__p),
-        std::__wrap_iter<const_pointer>(__begin_),
+        std::__wrap_iter<const_pointer>(this->__begin_),
         std::__wrap_iter<const_pointer>(__raw_capacity()));
 #else
     return const_iterator(__p);
@@ -933,7 +910,7 @@ class vector {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __base_destruct_at_end(pointer __new_last) _NOEXCEPT {
     pointer __soon_to_be_end = __end_pointer();
     while (__new_last != __soon_to_be_end)
-      __alloc_traits::destroy(__alloc_, std::__to_address(--__soon_to_be_end));
+      __alloc_traits::destroy(this->__alloc_, std::__to_address(--__soon_to_be_end));
     __set_sentinel(__new_last);
   }
 
@@ -952,21 +929,21 @@ class vector {
   [[__noreturn__]] _LIBCPP_HIDE_FROM_ABI static void __throw_out_of_range() { std::__throw_out_of_range("vector"); }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector& __c, true_type) {
-    if (__alloc_ != __c.__alloc_) {
+    if (this->__alloc_ != __c.__alloc_) {
       clear();
       __annotate_delete();
-      __alloc_traits::deallocate(__alloc_, __begin_, capacity());
+      __alloc_traits::deallocate(this->__alloc_, this->__begin_, capacity());
       __set_valid_range(nullptr, static_cast<size_type>(0));
       __set_capacity(static_cast<__sentinel_type>(0));
     }
-    __alloc_ = __c.__alloc_;
+    this->__alloc_ = __c.__alloc_;
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector&, false_type) {}
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c, true_type)
       _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
-    __alloc_ = std::move(__c.__alloc_);
+    this->__alloc_ = std::move(__c.__alloc_);
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector&, false_type) _NOEXCEPT {}
@@ -1032,7 +1009,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__swap_out_circular_
   __annotate_delete();
   auto __new_begin = __v.begin() - size();
   std::__uninitialized_allocator_relocate(
-      __alloc_,
+      this->__alloc_,
       std::__to_address(__begin_),
       std::__to_address(__end_pointer()),
       std::__to_address(__new_begin));
@@ -1059,7 +1036,7 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v, pointer
   // Relocate [__p, __end) first to avoid having a hole in [__begin_, __end)
   // in case something in [__begin_, __p) throws.
   std::__uninitialized_allocator_relocate(
-      __alloc_, std::__to_address(__p), std::__to_address(__end), std::__to_address(__v.end()));
+      this->__alloc_, std::__to_address(__p), std::__to_address(__end), std::__to_address(__v.end()));
   auto __relocated_so_far = __end - __p;
   __v.__set_sentinel(__v.end() + __relocated_so_far);
   __set_sentinel(
@@ -1067,7 +1044,7 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v, pointer
   auto __new_begin = __v.begin() - (__p - __begin_);
 
   std::__uninitialized_allocator_relocate(
-      __alloc_, std::__to_address(__begin_), std::__to_address(__p), std::__to_address(__new_begin));
+      this->__alloc_, std::__to_address(__begin_), std::__to_address(__p), std::__to_address(__new_begin));
   __v.__set_valid_range(__new_begin, __v.size() + size());
   __set_sentinel(static_cast<size_type>(0)); // All the objects have been destroyed by relocating them.
 
@@ -1079,10 +1056,10 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v, pointer
 
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT {
-  if (__begin_ != nullptr) {
+  if (this->__begin_ != nullptr) {
     clear();
     __annotate_delete();
-    __alloc_traits::deallocate(__alloc_, __begin_, capacity());
+    __alloc_traits::deallocate(this->__alloc_, this->__begin_, capacity());
     __set_valid_range(nullptr, static_cast<size_type>(0));
     __set_capacity(static_cast<size_type>(0));
   }
@@ -1111,7 +1088,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(s
   _ConstructTransaction __tx(*this, __n);
   const_pointer __new_end = __tx.__new_end_;
   for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
-    __alloc_traits::construct(__alloc_, std::__to_address(__pos));
+    __alloc_traits::construct(this->__alloc_, std::__to_address(__pos));
   }
 }
 
@@ -1127,7 +1104,7 @@ vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
   _ConstructTransaction __tx(*this, __n);
   const_pointer __new_end = __tx.__new_end_;
   for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
-    __alloc_traits::construct(__alloc_, std::__to_address(__pos), __x);
+    __alloc_traits::construct(this->__alloc_, std::__to_address(__pos), __x);
   }
 }
 
@@ -1136,8 +1113,7 @@ template <class _InputIterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
   _ConstructTransaction __tx(*this, __n);
-  __tx.__pos_ =
-      std::__uninitialized_allocator_copy(__alloc_, std::move(__first), std::move(__last), __tx.__pos_);
+  __tx.__pos_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __tx.__pos_);
 }
 
 template <class _Tp, class _Allocator>
@@ -1172,7 +1148,7 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type)
     _NOEXCEPT_(__alloc_traits::is_always_equal::value) {
-  if (__alloc_ != __c.__alloc_) {
+  if (this->__alloc_ != __c.__alloc_) {
     typedef move_iterator<iterator> _Ip;
     assign(_Ip(__c.begin()), _Ip(__c.end()));
   } else
@@ -1224,10 +1200,10 @@ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last,
   if (__new_size <= capacity()) {
     if (__new_size > size()) {
       auto const __size = size();
-      auto __mid = std::__copy_n<_AlgPolicy>(std::move(__first), __size, __begin_).first;
+      auto __mid = std::__copy_n<_AlgPolicy>(std::move(__first), __size, this->__begin_).first;
       __construct_at_end(std::move(__mid), std::move(__last), __new_size - __size);
     } else {
-      pointer __m = std::__copy(std::move(__first), __last, __begin_).second;
+      pointer __m = std::__copy(std::move(__first), __last, this->__begin_).second;
       this->__destruct_at_end(__m);
     }
   } else {
@@ -1241,11 +1217,11 @@ template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u) {
   if (__n <= capacity()) {
     size_type __s = size();
-    std::fill_n(__begin_, std::min(__n, __s), __u);
+    std::fill_n(this->__begin_, std::min(__n, __s), __u);
     if (__n > __s)
       __construct_at_end(__n - __s, __u);
     else
-      this->__destruct_at_end(__begin_ + __n);
+      this->__destruct_at_end(this->__begin_ + __n);
   } else {
     __vdeallocate();
     __vallocate(__recommend(static_cast<size_type>(__n)));
@@ -1258,7 +1234,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::reserve(size_type __
   if (__n > capacity()) {
     if (__n > max_size())
       this->__throw_length_error();
-    __split_buffer __v(__n, size(), __alloc_);
+    __split_buffer __v(__n, size(), this->__alloc_);
     __swap_out_circular_buffer(__v);
   }
 }
@@ -1269,7 +1245,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::shrink_to_fit() _NOE
 #if _LIBCPP_HAS_EXCEPTIONS
     try {
 #endif // _LIBCPP_HAS_EXCEPTIONS
-      __split_buffer __v(size(), size(), __alloc_);
+      __split_buffer __v(size(), size(), this->__alloc_);
       // The Standard mandates shrink_to_fit() does not increase the capacity.
       // With equal capacity keep the existing buffer. This avoids extra work
       // due to swapping the elements.
@@ -1286,10 +1262,10 @@ template <class _Tp, class _Allocator>
 template <class... _Args>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::__sentinel_type
 vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) {
-  __split_buffer __v(__recommend(size() + 1), size(), __alloc_);
+  __split_buffer __v(__recommend(size() + 1), size(), this->__alloc_);
   //    __v.emplace_back(std::forward<_Args>(__args)...);
   pointer __end = __v.end();
-  __alloc_traits::construct(__alloc_, std::__to_address(__end), std::forward<_Args>(__args)...);
+  __alloc_traits::construct(this->__alloc_, std::__to_address(__end), std::forward<_Args>(__args)...);
   __v.__set_sentinel(++__end);
   __swap_out_circular_buffer(__v);
   return __raw_sentinel();
@@ -1343,7 +1319,7 @@ vector<_Tp, _Allocator>::erase(const_iterator __position) {
   _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
       __position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator");
   difference_type __ps = __position - cbegin();
-  pointer __p          = __begin_ + __ps;
+  pointer __p          = this->__begin_ + __ps;
   this->__destruct_at_end(std::move(__p + 1, __end_pointer(), __p));
   return __make_iter(__p);
 }
@@ -1352,7 +1328,7 @@ template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) {
   _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range");
-  pointer __p = __begin_ + (__first - begin());
+  pointer __p = this->__begin_ + (__first - begin());
   if (__first != __last) {
     this->__destruct_at_end(std::move(__p + (__last - __first), __end_pointer(), __p));
   }
@@ -1368,7 +1344,7 @@ vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointe
     pointer __i = __from_s + __n;
     _ConstructTransaction __tx(*this, __from_e - __i);
     for (pointer __pos = __tx.__pos_; __i < __from_e; ++__i, (void)++__pos, __tx.__pos_ = __pos) {
-      __alloc_traits::construct(__alloc_, std::__to_address(__pos), std::move(*__i));
+      __alloc_traits::construct(this->__alloc_, std::__to_address(__pos), std::move(*__i));
     }
   }
   std::move_backward(__from_s, __from_s + __n, __old_last);
@@ -1377,7 +1353,7 @@ vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointe
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) {
-  pointer __p = __begin_ + (__position - begin());
+  pointer __p = this->__begin_ + (__position - begin());
   if (!__is_full()) {
     pointer __end = __end_pointer();
     if (__p == __end) {
@@ -1390,7 +1366,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
       *__p = *__xr;
     }
   } else {
-    __split_buffer __v(__recommend(size() + 1), __p - __begin_, __alloc_);
+    __split_buffer __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
     __v.emplace_back(__x);
     __p = __swap_out_circular_buffer(__v, __p);
   }
@@ -1400,7 +1376,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) {
-  pointer __p = __begin_ + (__position - begin());
+  pointer __p = this->__begin_ + (__position - begin());
   if (!__is_full()) {
     pointer __end = __end_pointer();
     if (__p == __end) {
@@ -1410,7 +1386,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) {
       *__p = std::move(__x);
     }
   } else {
-    __split_buffer __v(__recommend(size() + 1), __p - __begin_, __alloc_);
+    __split_buffer __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
     __v.emplace_back(std::move(__x));
     __p = __swap_out_circular_buffer(__v, __p);
   }
@@ -1421,18 +1397,18 @@ template <class _Tp, class _Allocator>
 template <class... _Args>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) {
-  pointer __p = __begin_ + (__position - begin());
+  pointer __p = this->__begin_ + (__position - begin());
   if (!__is_full()) {
     pointer __end = __end_pointer();
     if (__p == __end) {
       __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
     } else {
-      __temp_value<value_type, _Allocator> __tmp(__alloc_, std::forward<_Args>(__args)...);
+      __temp_value<value_type, _Allocator> __tmp(this->__alloc_, std::forward<_Args>(__args)...);
       __move_range(__p, __end, __p + 1);
       *__p = std::move(__tmp.get());
     }
   } else {
-    __split_buffer __v(__recommend(size() + 1), __p - __begin_, __alloc_);
+    __split_buffer __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
     __v.emplace_back(std::forward<_Args>(__args)...);
     __p = __swap_out_circular_buffer(__v, __p);
   }
@@ -1442,7 +1418,7 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) {
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x) {
-  pointer __p = __begin_ + (__position - begin());
+  pointer __p = this->__begin_ + (__position - begin());
   if (__n > 0) {
     if (__n <= __remaining_capacity()) {
       size_type __old_n  = __n;
@@ -1461,7 +1437,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_
         std::fill_n(__p, __n, *__xr);
       }
     } else {
-      __split_buffer __v(__recommend(size() + __n), __p - __begin_, __alloc_);
+      __split_buffer __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
       __v.__construct_at_end(__n, __x);
       __p = __swap_out_circular_buffer(__v, __p);
     }
@@ -1474,7 +1450,7 @@ template <class _InputIterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) {
   difference_type __off = __position - begin();
-  pointer __p           = __begin_ + __off;
+  pointer __p           = this->__begin_ + __off;
   pointer __old_last    = __end_pointer();
   for (; !__is_full() && __first != __last; ++__first)
     __emplace_back_assume_capacity(*__first);
@@ -1515,7 +1491,7 @@ template <class _AlgPolicy, class _Iterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::__insert_with_size(
     const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) {
-  pointer __p = __begin_ + (__position - begin());
+  pointer __p = this->__begin_ + (__position - begin());
   if (__n > 0) {
     if (__n <= static_cast<difference_type>(__remaining_capacity())) {
       pointer __end        = __end_pointer();
@@ -1541,7 +1517,7 @@ vector<_Tp, _Allocator>::__insert_with_size(
         __insert_assign_n_unchecked<_AlgPolicy>(std::move(__first), __n, __p);
       }
     } else {
-      __split_buffer __v(__recommend(size() + __n), __p - __begin_, __alloc_);
+      __split_buffer __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
       __v.__construct_at_end_with_size(std::move(__first), __n);
       __p = __swap_out_circular_buffer(__v, __p);
     }
@@ -1556,12 +1532,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __n
     if (__new_size <= capacity()) {
       __construct_at_end(__new_size - __current_size);
     } else {
-      __split_buffer __v(__recommend(__new_size), __current_size, __alloc_);
+      __split_buffer __v(__recommend(__new_size), __current_size, this->__alloc_);
       __v.__construct_at_end(__new_size - __current_size);
       __swap_out_circular_buffer(__v);
     }
   } else if (__current_size > __new_size) {
-    this->__destruct_at_end(__begin_ + __new_size);
+    this->__destruct_at_end(this->__begin_ + __new_size);
   }
 }
 
@@ -1577,16 +1553,46 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __n
       __swap_out_circular_buffer(__v);
     }
   } else if (__current_size > __new_size) {
-    this->__destruct_at_end(__begin_ + __new_size);
+    this->__destruct_at_end(this->__begin_ + __new_size);
+  }
+}
+
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+template<class _Tp, class _Allocator>
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool vector<_Tp, _Allocator>::__invariants() const {
+  if (__begin_ == nullptr) {
+    if (__size_ != 0 || __cap_ != 0)
+      return false;
+  } else {
+    if (__size_ > __cap_)
+      return false;
   }
+  return true;
 }
+#else
+template<class _Tp, class _Allocator>
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool vector<_Tp, _Allocator>::__invariants() const {
+  if (__begin_ == nullptr) {
+    if (__end_ != nullptr || __cap_ != nullptr)
+      return false;
+  } else {
+    if (__begin_ > __end_)
+      return false;
+    if (__begin_ == __cap_)
+      return false;
+    if (__end_ > __cap_)
+      return false;
+  }
+  return true;
+}
+#endif // _LIBCPP_ABI_SIZE_BASED_VECTOR
 
 #if _LIBCPP_STD_VER >= 20
-template <class _Allocator>
-inline constexpr bool __format::__enable_insertable<vector<char, _Allocator>> = true;
+template <>
+inline constexpr bool __format::__enable_insertable<vector<char>> = true;
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
-template <class _Allocator>
-inline constexpr bool __format::__enable_insertable<vector<wchar_t, _Allocator>> = true;
+template <>
+inline constexpr bool __format::__enable_insertable<vector<wchar_t>> = true;
 #  endif
 #endif // _LIBCPP_STD_VER >= 20
 

>From 935405c3d732684229ed15ba4721d0fcb4fde9cb Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Tue, 13 Jan 2026 23:25:20 +0000
Subject: [PATCH 4/8] fixes breaks from generic-cxx20

---
 libcxx/include/__vector/vector.h | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 28465a6b4c44d..ea56b3ecc65b3 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -676,7 +676,7 @@ class vector {
 	}
 
 	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __remaining_capacity() const _NOEXCEPT {
-		return __end_;
+		return __cap_ - __end_;
 	}
 
 	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
@@ -695,16 +695,12 @@ class vector {
 
 	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __end) _NOEXCEPT { __end_ = __end; }
 
-	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __pos) _NOEXCEPT {
+	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __offset) _NOEXCEPT {
     __end_ = __begin_ + __offset;
 	}
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __cap) _NOEXCEPT { __cap_ = __cap; }
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __offset) _NOEXCEPT {
-    __cap_ = __begin_ + __offset;
-  }
-
 	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __offset) _NOEXCEPT {
     __cap_ = __begin_ + __offset;
   }

>From 970d4588c0e261f762b47258b6bc620b8825fdaf Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Wed, 14 Jan 2026 01:38:47 +0000
Subject: [PATCH 5/8] further reduces diff

---
 libcxx/include/__split_buffer    |   3 +-
 libcxx/include/__vector/vector.h | 187 ++++++++++++++++---------------
 2 files changed, 99 insertions(+), 91 deletions(-)

diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer
index 1b1492dadaddc..da26a6e74935a 100644
--- a/libcxx/include/__split_buffer
+++ b/libcxx/include/__split_buffer
@@ -310,7 +310,8 @@ public:
     return __begin_[__size_ - 1];
   }
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_without_allocator(__split_buffer_size_layout& __other) _NOEXCEPT {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
+  __swap_without_allocator(__split_buffer_size_layout& __other) _NOEXCEPT {
     std::swap(__front_cap_, __other.__front_cap_);
     std::swap(__begin_, __other.__begin_);
     std::swap(__cap_, __other.__cap_);
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index ea56b3ecc65b3..2ffa67453adc9 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -87,6 +87,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Tp, class _Allocator /* = allocator<_Tp> */>
 class vector {
 public:
+  ///
+  /// Types
+  ///
   using value_type                     = _Tp;
   using allocator_type                 = _Allocator;
   using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
@@ -589,97 +592,87 @@ class vector {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz, const_reference __x);
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(vector& __other)
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(vector&)
 #if _LIBCPP_STD_VER >= 14
-      _NOEXCEPT
+      _NOEXCEPT;
 #else
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
+      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
 #endif
-  {
-    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
-        __alloc_traits::propagate_on_container_swap::value || __alloc_ == __other.__alloc_,
-        "vector::swap: Either propagate_on_container_swap must be true"
-        " or the allocators must compare equal");
-    std::swap(__begin_, __other.__begin_);
-#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
-		std::swap(__size_, __other.__size_);
-#else
-    std::swap(__end_, __other.__end_);
-#endif
-    std::swap(__cap_, __other.__cap_);
-    std::__swap_allocator(__alloc_, __other.__alloc_);
-  }
 
-
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
 
 #ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+
 private:
-	using __sentinel_type _LIBCPP_NODEBUG = size_type;
-	using __split_buffer _LIBCPP_NODEBUG = __split_buffer<_Tp, _Allocator, __split_buffer_size_layout>;
+  using __sentinel_type _LIBCPP_NODEBUG = size_type;
+  using __split_buffer _LIBCPP_NODEBUG  = __split_buffer<_Tp, _Allocator, __split_buffer_size_layout>;
 
-	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __raw_sentinel() const _NOEXCEPT {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __raw_sentinel() const _NOEXCEPT {
     return __size_;
-	}
+  }
 
-	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_pointer() const _NOEXCEPT {
-		return __begin_ + __size_;
-	}
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_pointer() const _NOEXCEPT {
+    return __begin_ + __size_;
+  }
 
-	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __remaining_capacity() const _NOEXCEPT {
-		return __cap_ - __size_;
-	}
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type
+  __remaining_capacity() const _NOEXCEPT {
+    return __cap_ - __size_;
+  }
 
-	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
     return __size_ == __cap_;
   }
 
-	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, pointer __end) _NOEXCEPT {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, pointer __end) _NOEXCEPT {
     __begin_ = __begin;
-    __size_ = __end - __begin_;
-	}
+    __size_  = __end - __begin_;
+  }
 
-	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, size_type __size) _NOEXCEPT {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
+  __set_valid_range(pointer __begin, size_type __size) _NOEXCEPT {
     __begin_ = __begin;
     __size_  = __size;
   }
 
-	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __size) _NOEXCEPT {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __size) _NOEXCEPT {
     __size_ = __size;
   }
 
-	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __pos) _NOEXCEPT {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __pos) _NOEXCEPT {
     __size_ = static_cast<size_type>(__pos - __begin_);
-	}
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __cap) _NOEXCEPT { __cap_ = __cap; }
 
-	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __pos) _NOEXCEPT {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __pos) _NOEXCEPT {
     __cap_ = static_cast<size_type>(__pos - __begin_);
-	}
+  }
 
-	pointer __begin_  = nullptr;
-	size_type __size_ = 0;
-	size_type __cap_  = 0;
-	[[no_unique_address]] allocator_type __alloc_;
+  pointer __begin_  = nullptr;
+  size_type __size_ = 0;
+  size_type __cap_  = 0;
+  [[no_unique_address]] allocator_type __alloc_;
 #else
+
 private:
-	using __split_buffer _LIBCPP_NODEBUG = __split_buffer<_Tp, _Allocator, __split_buffer_pointer_layout>;
-	using __sentinel_type _LIBCPP_NODEBUG = pointer;
+  using __split_buffer _LIBCPP_NODEBUG  = __split_buffer<_Tp, _Allocator, __split_buffer_pointer_layout>;
+  using __sentinel_type _LIBCPP_NODEBUG = pointer;
 
-	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_sentinel() const _NOEXCEPT {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_sentinel() const _NOEXCEPT {
     return __end_;
   }
 
-	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_pointer() const _NOEXCEPT {
-		return __end_;
-	}
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_pointer() const _NOEXCEPT {
+    return __end_;
+  }
 
-	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __remaining_capacity() const _NOEXCEPT {
-		return __cap_ - __end_;
-	}
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type
+  __remaining_capacity() const _NOEXCEPT {
+    return __cap_ - __end_;
+  }
 
-	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __is_full() const _NOEXCEPT {
     return __end_ == __cap_;
   }
 
@@ -688,29 +681,31 @@ class vector {
     __end_   = __end;
   }
 
-	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_valid_range(pointer __begin, size_type __size) _NOEXCEPT {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
+  __set_valid_range(pointer __begin, size_type __size) _NOEXCEPT {
     __begin_ = __begin;
     __end_   = __begin_ + __size;
   }
 
-	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __end) _NOEXCEPT { __end_ = __end; }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __end) _NOEXCEPT { __end_ = __end; }
 
-	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __offset) _NOEXCEPT {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __offset) _NOEXCEPT {
     __end_ = __begin_ + __offset;
-	}
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __cap) _NOEXCEPT { __cap_ = __cap; }
 
-	_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __offset) _NOEXCEPT {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __offset) _NOEXCEPT {
     __cap_ = __begin_ + __offset;
   }
 
-	pointer __begin_ = nullptr;
-	pointer __end_   = nullptr;
-	_LIBCPP_COMPRESSED_PAIR(pointer, __cap_ = nullptr, allocator_type, __alloc_);
+  pointer __begin_ = nullptr;
+  pointer __end_   = nullptr;
+  _LIBCPP_COMPRESSED_PAIR(pointer, __cap_ = nullptr, allocator_type, __alloc_);
 #endif // _LIBCPP_ABI_SIZE_BASED_VECTOR
 
-	[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __sentinel_type __raw_capacity() const _NOEXCEPT {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20
+  _LIBCPP_HIDE_FROM_ABI __sentinel_type __raw_capacity() const _NOEXCEPT {
     return __cap_;
   }
 
@@ -834,8 +829,7 @@ class vector {
 #endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
   }
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
-  __swap_out_circular_buffer(__split_buffer& __v);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_out_circular_buffer(__split_buffer& __v);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer
   __swap_out_circular_buffer(__split_buffer& __v, pointer __p);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
@@ -851,7 +845,8 @@ class vector {
   }
 
   template <class... _Args>
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __sentinel_type __emplace_back_slow_path(_Args&&... __args);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI inline __sentinel_type
+  __emplace_back_slow_path(_Args&&... __args);
 
   // The following functions are no-ops outside of AddressSanitizer mode.
   // We call annotations for every allocator, unless explicitly disabled.
@@ -1005,13 +1000,9 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__swap_out_circular_
   __annotate_delete();
   auto __new_begin = __v.begin() - size();
   std::__uninitialized_allocator_relocate(
-      this->__alloc_,
-      std::__to_address(__begin_),
-      std::__to_address(__end_pointer()),
-      std::__to_address(__new_begin));
+      this->__alloc_, std::__to_address(__begin_), std::__to_address(__end_pointer()), std::__to_address(__new_begin));
   __v.__set_valid_range(__new_begin, __v.end());
   __set_sentinel(static_cast<size_type>(0)); // All the objects have been destroyed by relocating them.
-  // __v.__size_ += __size_;
 
   __swap_layouts(__v);
   __v.__set_data(__v.begin());
@@ -1194,8 +1185,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
 vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n) {
   size_type __new_size = static_cast<size_type>(__n);
   if (__new_size <= capacity()) {
-    if (__new_size > size()) {
-      auto const __size = size();
+    auto const __size = size();
+    if (__new_size > __size) {
       auto __mid = std::__copy_n<_AlgPolicy>(std::move(__first), __size, this->__begin_).first;
       __construct_at_end(std::move(__mid), std::move(__last), __new_size - __size);
     } else {
@@ -1462,19 +1453,13 @@ vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _Inpu
     __split_buffer __merged(
         __recommend(size() + __v.size()), __off, __alloc_); // has `__off` positions available at the front
     std::__uninitialized_allocator_relocate(
-        __alloc_,
-        std::__to_address(__old_last),
-        std::__to_address(__end_pointer()),
-        std::__to_address(__merged.end()));
+        __alloc_, std::__to_address(__old_last), std::__to_address(__end_pointer()), std::__to_address(__merged.end()));
     __guard.__complete(); // Release the guard once objects in [__old_last_, __end_pointer()) have been successfully
                           // relocated.
     __merged.__set_sentinel(__merged.end() + (__end_pointer() - __old_last));
     __set_sentinel(__old_last);
     std::__uninitialized_allocator_relocate(
-        __alloc_,
-        std::__to_address(__v.begin()),
-        std::__to_address(__v.end()),
-        std::__to_address(__merged.end()));
+        __alloc_, std::__to_address(__v.begin()), std::__to_address(__v.end()), std::__to_address(__merged.end()));
     __merged.__set_sentinel(__merged.size() + __v.size());
     __v.__set_sentinel(__v.begin());
     __p        = __swap_out_circular_buffer(__merged, __p);
@@ -1528,7 +1513,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __n
     if (__new_size <= capacity()) {
       __construct_at_end(__new_size - __current_size);
     } else {
-      __split_buffer __v(__recommend(__new_size), __current_size, this->__alloc_);
+      __split_buffer __v(__recommend(__new_size), __current_size, __alloc_);
       __v.__construct_at_end(__new_size - __current_size);
       __swap_out_circular_buffer(__v);
     }
@@ -1553,9 +1538,31 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __n
   }
 }
 
+template <class _Tp, class _Allocator>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::swap(vector& __x)
+#if _LIBCPP_STD_VER >= 14
+    _NOEXCEPT
+#else
+    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
+#endif
+{
+  _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
+      __alloc_traits::propagate_on_container_swap::value || __alloc_ == __x.__alloc_,
+      "vector::swap: Either propagate_on_container_swap must be true"
+      " or the allocators must compare equal");
+  std::swap(this->__begin_, __x.__begin_);
 #ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
-template<class _Tp, class _Allocator>
-[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool vector<_Tp, _Allocator>::__invariants() const {
+  std::swap(this->__size_, __x.__size_);
+#else
+  std::swap(this->__end_, __x.__end_);
+#endif
+  std::swap(this->__cap_, __x.__cap_);
+  std::__swap_allocator(this->__alloc_, __x.__alloc_);
+}
+
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+template <class _Tp, class _Allocator>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 bool vector<_Tp, _Allocator>::__invariants() const {
   if (__begin_ == nullptr) {
     if (__size_ != 0 || __cap_ != 0)
       return false;
@@ -1566,17 +1573,17 @@ template<class _Tp, class _Allocator>
   return true;
 }
 #else
-template<class _Tp, class _Allocator>
-[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool vector<_Tp, _Allocator>::__invariants() const {
-  if (__begin_ == nullptr) {
-    if (__end_ != nullptr || __cap_ != nullptr)
+template <class _Tp, class _Allocator>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 bool vector<_Tp, _Allocator>::__invariants() const {
+  if (this->__begin_ == nullptr) {
+    if (this->__end_ != nullptr || this->__cap_ != nullptr)
       return false;
   } else {
-    if (__begin_ > __end_)
+    if (this->__begin_ > this->__end_)
       return false;
-    if (__begin_ == __cap_)
+    if (this->__begin_ == this->__cap_)
       return false;
-    if (__end_ > __cap_)
+    if (this->__end_ > this->__cap_)
       return false;
   }
   return true;

>From c87e88382d31e74a946bbc3f58c213dae1324d15 Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Wed, 14 Jan 2026 02:35:00 +0000
Subject: [PATCH 6/8] gets GDB pretty-printer working

---
 libcxx/utils/gdb/libcxx/printers.py | 32 ++++++++++++++---------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/libcxx/utils/gdb/libcxx/printers.py b/libcxx/utils/gdb/libcxx/printers.py
index 1bfdd718e36bc..83df6be78a1bb 100644
--- a/libcxx/utils/gdb/libcxx/printers.py
+++ b/libcxx/utils/gdb/libcxx/printers.py
@@ -13,7 +13,6 @@
 from __future__ import print_function
 
 import re
-import sys
 import gdb
 import gdb.printing
 
@@ -352,28 +351,29 @@ def __init__(self, val):
         """Set val, length, capacity, and iterator for bool and normal vectors."""
         self.val = val
         self.typename = _remove_generics(_prettify_typename(val.type))
+        begin = self.val["__begin_"]
         if self.val.type.template_argument(0).code == gdb.TYPE_CODE_BOOL:
-            begin = self.val["__begin_"]
             self.typename += "<bool>"
             self.length = self.val["__size_"]
             bits_per_word = self.val["__bits_per_word"]
             self.capacity = self.val["__cap_"] * bits_per_word
             self.iterator = self._VectorBoolIterator(begin, self.length, bits_per_word)
         else:
-            for i in val.type.fields():
-                if i.is_base_class:
-                    base = val[i]
-                    break
-
-            begin = base["__begin_"]
-            end = base["__end_"]
-            self.length = end - begin
-            for i in base.type.fields():
-                if i.name == "__cap_":
-                    self.capacity = base["__cap_"] - begin
-                elif i.name == None:
-                    self.capacity = base[i]["__cap_"] - begin
-                    break
+            cap = self.val["__cap_"]
+
+            # We test for integers because `vector<T>::size_type` is required to
+            # be an unsigned integer, whereas `vector<T>::pointer` can be any
+            # type that satisfies the Cpp17NullablePointer requirements.
+            if cap.type.strip_typedefs().code == gdb.TYPE_CODE_INT:
+                size = self.val["__size_"]
+                self.length = size
+                self.capacity = cap
+                end = begin + size
+            else:
+                end = self.val["__end_"]
+                self.length = end - begin
+                self.capacity = cap - begin
+
             self.iterator = self._VectorIterator(begin, end)
 
     def to_string(self):

>From 44adc2d0c03ea421871d7a9b2aaa178ad828b1b7 Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Thu, 15 Jan 2026 01:10:06 +0000
Subject: [PATCH 7/8] ensures that generic-cxx23 passes

---
 libcxx/include/__vector/vector.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 2ffa67453adc9..46635045bc704 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -510,8 +510,8 @@ class vector {
   template <_ContainerCompatibleRange<_Tp> _Range>
   _LIBCPP_HIDE_FROM_ABI constexpr void append_range(_Range&& __range) {
     if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
-      auto __len = static_cast<size_type>(ranges::distance(__range));
-      if (__len < __raw_capacity() - __raw_sentinel()) {
+      auto __len = ranges::distance(__range);
+      if (__len < static_cast<difference_type>(__raw_capacity() - __raw_sentinel())) {
         __construct_at_end(ranges::begin(__range), ranges::end(__range), __len);
       } else {
         __split_buffer __buffer(__recommend(size() + __len), size(), __alloc_);

>From fe98721a13c700986159e12a90a20134daf671b9 Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Thu, 15 Jan 2026 02:23:38 +0000
Subject: [PATCH 8/8] attempts to fix GCC issue

---
 libcxx/include/__vector/vector.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 46635045bc704..18004abbd1899 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -86,6 +86,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Allocator /* = allocator<_Tp> */>
 class vector {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+  using __split_buffer _LIBCPP_NODEBUG  = __split_buffer<_Tp, _Allocator, __split_buffer_size_layout>;
+#else
+  using __split_buffer _LIBCPP_NODEBUG  = __split_buffer<_Tp, _Allocator, __split_buffer_pointer_layout>;
+#endif
 public:
   ///
   /// Types
@@ -605,7 +610,6 @@ class vector {
 
 private:
   using __sentinel_type _LIBCPP_NODEBUG = size_type;
-  using __split_buffer _LIBCPP_NODEBUG  = __split_buffer<_Tp, _Allocator, __split_buffer_size_layout>;
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __raw_sentinel() const _NOEXCEPT {
     return __size_;
@@ -656,7 +660,6 @@ class vector {
 #else
 
 private:
-  using __split_buffer _LIBCPP_NODEBUG  = __split_buffer<_Tp, _Allocator, __split_buffer_pointer_layout>;
   using __sentinel_type _LIBCPP_NODEBUG = pointer;
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __raw_sentinel() const _NOEXCEPT {



More information about the libcxx-commits mailing list