[libcxx-commits] [libcxx] [libc++] Implement P0843R14: `inplace_vector` (PR #204008)

William Tran-Viet via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jun 17 22:55:40 PDT 2026


https://github.com/smallp-o-p updated https://github.com/llvm/llvm-project/pull/204008

>From 2b57d1e56ab1c58386c78e9c983e0a9d53639e14 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Mon, 11 May 2026 20:55:42 -0400
Subject: [PATCH 01/11] Update documentation, transitive includes, module map
 for inplace_vector

---
 libcxx/docs/FeatureTestMacroTable.rst         |  2 +-
 libcxx/docs/Hardening.rst                     |  7 +++
 libcxx/docs/ReleaseNotes/23.rst               |  1 +
 libcxx/docs/Status/Cxx2cPapers.csv            |  6 +-
 libcxx/include/module.modulemap.in            |  5 ++
 libcxx/modules/std.compat.cppm.in             |  3 -
 libcxx/modules/std.cppm.in                    |  4 +-
 libcxx/modules/std/inplace_vector.inc         | 15 +++++
 .../test/libcxx/transitive_includes/cxx03.csv |  5 ++
 .../test/libcxx/transitive_includes/cxx11.csv |  5 ++
 .../test/libcxx/transitive_includes/cxx14.csv |  5 ++
 .../test/libcxx/transitive_includes/cxx17.csv |  5 ++
 .../test/libcxx/transitive_includes/cxx26.csv | 11 ++++
 .../inplace_vector.version.compile.pass.cpp   | 62 +++++++++++++++++++
 .../version.version.compile.pass.cpp          | 16 ++---
 .../generate_feature_test_macro_components.py |  3 +-
 libcxx/utils/libcxx/header_information.py     |  1 -
 17 files changed, 132 insertions(+), 24 deletions(-)
 create mode 100644 libcxx/modules/std/inplace_vector.inc
 create mode 100644 libcxx/test/std/language.support/support.limits/support.limits.general/inplace_vector.version.compile.pass.cpp

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 1b748e37293df..9ac0f558900f7 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -484,7 +484,7 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_hazard_pointer``                               *unimplemented*
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_inplace_vector``                               *unimplemented*
+    ``__cpp_lib_inplace_vector``                               ``202603L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_integer_sequence``                             ``202511L``
     ---------------------------------------------------------- -----------------
diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst
index 1360518379aef..f32f24ad9fdb6 100644
--- a/libcxx/docs/Hardening.rst
+++ b/libcxx/docs/Hardening.rst
@@ -440,6 +440,13 @@ CMake configuration time. The available options are:
 
   ABI impact: changes the iterator type of ``std::array``, its size and its layout.
 
+- ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_INPLACE_VECTOR`` -- changes the iterator type of
+  ``inplace_vector`` to a bounded iterator that keeps track of whether it's within the
+  bounds of the original container and asserts it on every dereference and when
+  performing iterator arithmetics.
+
+  ABI impact: changes the iterator type of ``inplace_vector``.
+
 ABI tags
 --------
 
diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index c8f7cf5455d92..aa2ecd5510e19 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -51,6 +51,7 @@ Implemented Papers
 - P2542R8: ``views::concat`` (`Github <https://llvm.org/PR105419>`__)
 - P3383R3: ``mdspan.at()`` (`Github <https://llvm.org/PR175213>`__)
 - P3508R0: Wording for "constexpr for specialized memory algorithms" (`Github <https://llvm.org/PR118379>`__)
+- P0843R14: ``inplace_vector`` (`Github <https://llvm.org/PR105433>`__)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 2132e80251657..337a28eae5889 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -69,7 +69,7 @@
 "`P3168R2 <https://wg21.link/P3168R2>`__","Give ``std::optional`` Range Support","2024-06 (St. Louis)","|Complete|","22","`#105430 <https://github.com/llvm/llvm-project/issues/105430>`__",""
 "`P3217R0 <https://wg21.link/P3217R0>`__","Adjoints to 'Enabling list-initialization for algorithms': find_last","2024-06 (St. Louis)","","","`#105431 <https://github.com/llvm/llvm-project/issues/105431>`__",""
 "`P2985R0 <https://wg21.link/P2985R0>`__","A type trait for detecting virtual base classes","2024-06 (St. Louis)","|Complete|","20","`#105432 <https://github.com/llvm/llvm-project/issues/105432>`__",""
-"`P0843R14 <https://wg21.link/P0843R14>`__","``inplace_vector``","2024-06 (St. Louis)","","","`#105433 <https://github.com/llvm/llvm-project/issues/105433>`__",""
+"`P0843R14 <https://wg21.link/P0843R14>`__","``inplace_vector``","2024-06 (St. Louis)","|Partial|","23","`#105433 <https://github.com/llvm/llvm-project/issues/105433>`__","inplace_vector<T,N> where T is not a trivial type cannot be used in a constant expression."
 "`P3235R3 <https://wg21.link/P3235R3>`__","``std::print`` more types faster with less memory","2024-06 (St. Louis)","","","`#105435 <https://github.com/llvm/llvm-project/issues/105435>`__",""
 "`P2968R2 <https://wg21.link/P2968R2>`__","Make ``std::ignore`` a first-class object","2024-06 (St. Louis)","|Complete|","19","`#105436 <https://github.com/llvm/llvm-project/issues/105436>`__",""
 "`P2075R6 <https://wg21.link/P2075R6>`__","Philox as an extension of the C++ RNG engines","2024-06 (St. Louis)","","","`#105437 <https://github.com/llvm/llvm-project/issues/105437>`__",""
@@ -195,8 +195,8 @@
 "`P3948R1 <https://wg21.link/P3948R1>`__","``constant_wrapper`` is the only tool needed for passing constant expressions via function arguments","2026-03 (Croydon)","","","`#189604 <https://github.com/llvm/llvm-project/issues/189604>`__",""
 "`P3978R3 <https://wg21.link/P3978R3>`__","``constant_wrapper`` should unwrap on call and subscript","2026-03 (Croydon)","|Complete|","23","`#189605 <https://github.com/llvm/llvm-project/issues/189605>`__",""
 "`P3961R1 <https://wg21.link/P3961R1>`__","Less double indirection in ``function_ref`` (RU-220)","2026-03 (Croydon)","","","`#189606 <https://github.com/llvm/llvm-project/issues/189606>`__",""
-"`P3981R2 <https://wg21.link/P3981R2>`__","Better return types in ``std::inplace_vector`` and ``std::exception_ptr_cast``","2026-03 (Croydon)","","","`#189607 <https://github.com/llvm/llvm-project/issues/189607>`__",""
-"`P4022R0 <https://wg21.link/P4022R0>`__","Remove ``try_append_range`` from ``inplace_vector`` for now","2026-03 (Croydon)","","","`#189608 <https://github.com/llvm/llvm-project/issues/189608>`__",""
+"`P3981R2 <https://wg21.link/P3981R2>`__","Better return types in ``std::inplace_vector`` and ``std::exception_ptr_cast``","2026-03 (Croydon)","|Partial|","23","`#189607 <https://github.com/llvm/llvm-project/issues/189607>`__","inplace_vector portion is completed."
+"`P4022R0 <https://wg21.link/P4022R0>`__","Remove ``try_append_range`` from ``inplace_vector`` for now","2026-03 (Croydon)","|Complete|","23","`#189608 <https://github.com/llvm/llvm-project/issues/189608>`__",""
 "`P4037R1 <https://wg21.link/P4037R1>`__","Supporting ``signed char`` and ``unsigned char`` in random number generation","2026-03 (Croydon)","","","`#189609 <https://github.com/llvm/llvm-project/issues/189609>`__",""
 "`P3450R1 <https://wg21.link/P3450R1>`__","Extend ``std::is_within_lifetime``","2026-03 (Croydon)","","","`#189610 <https://github.com/llvm/llvm-project/issues/189610>`__",""
 "`P3982R2 <https://wg21.link/P3982R2>`__","Split ``strided_slice`` into ``extent_slice`` and ``range_slice`` for C++26","2026-03 (Croydon)","","","`#189611 <https://github.com/llvm/llvm-project/issues/189611>`__",""
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index b11055940a82c..1301b80da9ce8 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1504,6 +1504,11 @@ module std [system] {
     export std.ios // base class
   }
 
+  module inplace_vector {
+    header "inplace_vector"
+    export *
+  }
+
   module iterator {
     module access                     { header "__iterator/access.h" }
     module advance                    { header "__iterator/advance.h" }
diff --git a/libcxx/modules/std.compat.cppm.in b/libcxx/modules/std.compat.cppm.in
index dd7385bf33a42..09ceace63cc83 100644
--- a/libcxx/modules/std.compat.cppm.in
+++ b/libcxx/modules/std.compat.cppm.in
@@ -57,9 +57,6 @@ module;
 #  if __has_include(<hazard_pointer>)
 #    error "please update the header information for <hazard_pointer> in headers_not_available in utils/libcxx/header_information.py"
 #  endif // __has_include(<hazard_pointer>)
-#  if __has_include(<inplace_vector>)
-#    error "please update the header information for <inplace_vector> in headers_not_available in utils/libcxx/header_information.py"
-#  endif // __has_include(<inplace_vector>)
 #  if __has_include(<linalg>)
 #    error "please update the header information for <linalg> in headers_not_available in utils/libcxx/header_information.py"
 #  endif // __has_include(<linalg>)
diff --git a/libcxx/modules/std.cppm.in b/libcxx/modules/std.cppm.in
index 6de6369c3387f..bbdcad23cf8d5 100644
--- a/libcxx/modules/std.cppm.in
+++ b/libcxx/modules/std.cppm.in
@@ -66,6 +66,7 @@ module;
 #include <functional>
 #include <future>
 #include <initializer_list>
+#include <inplace_vector>
 #include <iomanip>
 #include <ios>
 #include <iosfwd>
@@ -139,9 +140,6 @@ module;
 #  if __has_include(<hazard_pointer>)
 #    error "please update the header information for <hazard_pointer> in headers_not_available in utils/libcxx/header_information.py"
 #  endif // __has_include(<hazard_pointer>)
-#  if __has_include(<inplace_vector>)
-#    error "please update the header information for <inplace_vector> in headers_not_available in utils/libcxx/header_information.py"
-#  endif // __has_include(<inplace_vector>)
 #  if __has_include(<linalg>)
 #    error "please update the header information for <linalg> in headers_not_available in utils/libcxx/header_information.py"
 #  endif // __has_include(<linalg>)
diff --git a/libcxx/modules/std/inplace_vector.inc b/libcxx/modules/std/inplace_vector.inc
new file mode 100644
index 0000000000000..458ca4488fb46
--- /dev/null
+++ b/libcxx/modules/std/inplace_vector.inc
@@ -0,0 +1,15 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+export namespace std {
+#if _LIBCPP_STD_VER >= 26
+  using std::inplace_vector;
+#endif
+
+}
diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index c0031543e47bc..920a6145a02b8 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -122,15 +122,19 @@ atomic ratio
 atomic type_traits
 atomic version
 barrier atomic
+barrier cctype
 barrier climits
 barrier cmath
 barrier compare
 barrier concepts
 barrier cstddef
 barrier cstdint
+barrier cstdio
 barrier cstdlib
 barrier cstring
 barrier ctime
+barrier cwchar
+barrier cwctype
 barrier exception
 barrier initializer_list
 barrier iosfwd
@@ -2032,6 +2036,7 @@ stdexcept new
 stdexcept type_traits
 stdexcept typeinfo
 stdexcept version
+stop_token cstddef
 stop_token iosfwd
 stop_token version
 streambuf algorithm
diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index c0031543e47bc..920a6145a02b8 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -122,15 +122,19 @@ atomic ratio
 atomic type_traits
 atomic version
 barrier atomic
+barrier cctype
 barrier climits
 barrier cmath
 barrier compare
 barrier concepts
 barrier cstddef
 barrier cstdint
+barrier cstdio
 barrier cstdlib
 barrier cstring
 barrier ctime
+barrier cwchar
+barrier cwctype
 barrier exception
 barrier initializer_list
 barrier iosfwd
@@ -2032,6 +2036,7 @@ stdexcept new
 stdexcept type_traits
 stdexcept typeinfo
 stdexcept version
+stop_token cstddef
 stop_token iosfwd
 stop_token version
 streambuf algorithm
diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index c2eb5b44e8d7a..cfcf7bc7c4c19 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -125,15 +125,19 @@ atomic ratio
 atomic type_traits
 atomic version
 barrier atomic
+barrier cctype
 barrier climits
 barrier cmath
 barrier compare
 barrier concepts
 barrier cstddef
 barrier cstdint
+barrier cstdio
 barrier cstdlib
 barrier cstring
 barrier ctime
+barrier cwchar
+barrier cwctype
 barrier exception
 barrier initializer_list
 barrier iosfwd
@@ -2072,6 +2076,7 @@ stdexcept new
 stdexcept type_traits
 stdexcept typeinfo
 stdexcept version
+stop_token cstddef
 stop_token iosfwd
 stop_token version
 streambuf algorithm
diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index 332cb62f35b5f..534776e6f0526 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -122,15 +122,19 @@ atomic ratio
 atomic type_traits
 atomic version
 barrier atomic
+barrier cctype
 barrier climits
 barrier cmath
 barrier compare
 barrier concepts
 barrier cstddef
 barrier cstdint
+barrier cstdio
 barrier cstdlib
 barrier cstring
 barrier ctime
+barrier cwchar
+barrier cwctype
 barrier exception
 barrier initializer_list
 barrier iosfwd
@@ -2085,6 +2089,7 @@ stdexcept new
 stdexcept type_traits
 stdexcept typeinfo
 stdexcept version
+stop_token cstddef
 stop_token iosfwd
 stop_token version
 streambuf algorithm
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index 1450a13e125ef..7aa17cdb19acc 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -443,6 +443,17 @@ future tuple
 future typeinfo
 future version
 initializer_list version
+inplace_vector cctype
+inplace_vector compare
+inplace_vector cstdint
+inplace_vector cstring
+inplace_vector cwchar
+inplace_vector cwctype
+inplace_vector initializer_list
+inplace_vector limits
+inplace_vector optional
+inplace_vector stdexcept
+inplace_vector version
 iomanip cctype
 iomanip cerrno
 iomanip climits
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/inplace_vector.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/inplace_vector.version.compile.pass.cpp
new file mode 100644
index 0000000000000..849c754f015f3
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/inplace_vector.version.compile.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <inplace_vector>
+
+// Test the feature test macros defined by <inplace_vector>
+
+// clang-format off
+
+#include <inplace_vector>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+#  ifdef __cpp_lib_inplace_vector
+#    error "__cpp_lib_inplace_vector should not be defined before c++26"
+#  endif
+
+#elif TEST_STD_VER == 14
+
+#  ifdef __cpp_lib_inplace_vector
+#    error "__cpp_lib_inplace_vector should not be defined before c++26"
+#  endif
+
+#elif TEST_STD_VER == 17
+
+#  ifdef __cpp_lib_inplace_vector
+#    error "__cpp_lib_inplace_vector should not be defined before c++26"
+#  endif
+
+#elif TEST_STD_VER == 20
+
+#  ifdef __cpp_lib_inplace_vector
+#    error "__cpp_lib_inplace_vector should not be defined before c++26"
+#  endif
+
+#elif TEST_STD_VER == 23
+
+#  ifdef __cpp_lib_inplace_vector
+#    error "__cpp_lib_inplace_vector should not be defined before c++26"
+#  endif
+
+#elif TEST_STD_VER > 23
+
+#  ifndef __cpp_lib_inplace_vector
+#    error "__cpp_lib_inplace_vector should be defined in c++26"
+#  endif
+#  if __cpp_lib_inplace_vector != 202603L
+#    error "__cpp_lib_inplace_vector should have the value 202603L in c++26"
+#  endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 20c16700ef76a..0a51929660a55 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -7199,17 +7199,11 @@
 #    error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++26"
 #  endif
 
-#  if !defined(_LIBCPP_VERSION)
-#    ifndef __cpp_lib_inplace_vector
-#      error "__cpp_lib_inplace_vector should be defined in c++26"
-#    endif
-#    if __cpp_lib_inplace_vector != 202406L
-#      error "__cpp_lib_inplace_vector should have the value 202406L in c++26"
-#    endif
-#  else
-#    ifdef __cpp_lib_inplace_vector
-#      error "__cpp_lib_inplace_vector should not be defined because it is unimplemented in libc++!"
-#    endif
+#  ifndef __cpp_lib_inplace_vector
+#    error "__cpp_lib_inplace_vector should be defined in c++26"
+#  endif
+#  if __cpp_lib_inplace_vector != 202603L
+#    error "__cpp_lib_inplace_vector should have the value 202603L in c++26"
 #  endif
 
 #  ifndef __cpp_lib_int_pow2
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index d8fb575b97b2f..f57e64ee12a39 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -759,9 +759,8 @@ def add_version_header(tc):
         },
         {
             "name": "__cpp_lib_inplace_vector",
-            "values": {"c++26": 202406},  # P0843R14 inplace_vector
+            "values": {"c++26": 202603},  # P0843R14 inplace_vector
             "headers": ["inplace_vector"],
-            "unimplemented": True,
         },
         {
             "name": "__cpp_lib_int_pow2",
diff --git a/libcxx/utils/libcxx/header_information.py b/libcxx/utils/libcxx/header_information.py
index 384ff9f759460..5e6e4565383e8 100644
--- a/libcxx/utils/libcxx/header_information.py
+++ b/libcxx/utils/libcxx/header_information.py
@@ -166,7 +166,6 @@ def __hash__(self) -> int:
     "debugging",
     "generator",
     "hazard_pointer",
-    "inplace_vector",
     "linalg",
     "rcu",
     "spanstream",

>From 70bdc288f0c7d69001e5f9517926716b3c72aa07 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Mon, 11 May 2026 20:55:57 -0400
Subject: [PATCH 02/11] Implement std::inplace_vector<T,N>

---
 ...-hardening-mode-fast-with-abi-breaks.cmake |    1 +
 libcxx/include/CMakeLists.txt                 |    1 +
 libcxx/include/inplace_vector                 | 1130 +++++++++++++++++
 libcxx/include/version                        |    4 +-
 .../inplace_vector/assert.back.empty.pass.cpp |   29 +
 .../assert.front.empty.pass.cpp               |   27 +
 .../inplace_vector/assert.index.oob.pass.cpp  |   32 +
 .../inplace_vector/assert.iterator.pass.cpp   |  116 ++
 .../assert.pop_back.empty.pass.cpp            |   26 +
 ...sert.unchecked_push_back.capacity.pass.cpp |   35 +
 .../assert.zero_capacity.pass.cpp             |   31 +
 .../inplace_vector/nodiscard.verify.cpp       |   90 ++
 .../sequences/inplace_vector/access.pass.cpp  |  121 ++
 .../inplace_vector/addressof.compile.pass.cpp |   52 +
 .../sequences/inplace_vector/common.h         |  161 +++
 .../sequences/inplace_vector/compare.pass.cpp |  104 ++
 .../inplace_vector/compare.three_way.pass.cpp |  108 ++
 .../constant_initialization.pass.cpp          |   26 +
 .../inplace_vector/contiguous.pass.cpp        |   39 +
 .../inplace.vector.capacity/capacity.pass.cpp |   44 +
 .../inplace.vector.capacity/empty.pass.cpp    |   37 +
 .../inplace.vector.capacity/max_size.pass.cpp |   44 +
 .../inplace.vector.capacity/reserve.pass.cpp  |   49 +
 .../resize_size.pass.cpp                      |   44 +
 .../resize_size_exceptions.pass.cpp           |   42 +
 .../resize_size_value.pass.cpp                |   44 +
 .../resize_size_value_exceptions.pass.cpp     |   44 +
 .../shrink_to_fit.pass.cpp                    |   38 +
 .../inplace.vector.capacity/size.pass.cpp     |   43 +
 .../inplace.vector.capacity/swap.pass.cpp     |   76 ++
 .../inplace.vector.cons/assign_copy.pass.cpp  |   65 +
 .../assign_initializer_list.pass.cpp          |   44 +
 .../assign_iter_iter.pass.cpp                 |   58 +
 .../inplace.vector.cons/assign_move.pass.cpp  |   95 ++
 .../assign_size_value.pass.cpp                |   44 +
 .../construct_default.pass.cpp                |   67 +
 .../construct_from_range.pass.cpp             |   52 +
 .../construct_iter_iter.pass.cpp              |   54 +
 .../construct_size.pass.cpp                   |   47 +
 .../construct_size_value.pass.cpp             |   47 +
 .../copy.move_only.verify.cpp                 |   25 +
 .../inplace.vector.cons/copy.pass.cpp         |   42 +
 .../inplace.vector.cons/exceptions.pass.cpp   |  128 ++
 .../initializer_list.pass.cpp                 |   40 +
 .../inplace.vector.cons/move.pass.cpp         |   67 +
 .../op_equal_initializer_list.pass.cpp        |   45 +
 .../inplace.vector.data/data.pass.cpp         |   50 +
 .../inplace.vector.data/data_const.pass.cpp   |   63 +
 .../inplace.vector.erasure/erase.pass.cpp     |   42 +
 .../inplace.vector.erasure/erase_if.pass.cpp  |   42 +
 .../append_range.pass.cpp                     |   68 +
 .../assign_range.pass.cpp                     |   64 +
 .../inplace.vector.modifiers/clear.pass.cpp   |   38 +
 .../destroy_elements.pass.cpp                 |   72 ++
 .../inplace.vector.modifiers/emplace.pass.cpp |   62 +
 .../emplace_back.pass.cpp                     |   59 +
 .../erase_iter.pass.cpp                       |   50 +
 .../erase_iter_iter.pass.cpp                  |   50 +
 .../insert_iter_initializer_list.pass.cpp     |   46 +
 .../insert_iter_iter_iter.pass.cpp            |   82 ++
 .../insert_iter_lvalue.pass.cpp               |   49 +
 .../insert_iter_rvalue.pass.cpp               |   55 +
 .../insert_iter_size_value.pass.cpp           |   46 +
 .../insert_range.pass.cpp                     |   84 ++
 .../pop_back.pass.cpp                         |   38 +
 .../push_back.pass.cpp                        |   48 +
 .../push_back_exception_safety.pass.cpp       |   72 ++
 .../push_back_rvalue.pass.cpp                 |   54 +
 .../try_push_back.pass.cpp                    |  116 ++
 .../unchecked_push_back.pass.cpp              |   68 +
 .../inplace.vector.special/swap.pass.cpp      |   63 +
 ...rator_concept_conformance.compile.pass.cpp |   32 +
 .../inplace_vector/iterators.pass.cpp         |  128 ++
 ...range_concept_conformance.compile.pass.cpp |   30 +
 .../inplace_vector/reverse_iterators.pass.cpp |   68 +
 .../triviality.compile.pass.cpp               |  141 ++
 .../inplace_vector/types.compile.pass.cpp     |   53 +
 .../zero_capacity.exceptions.pass.cpp         |  124 ++
 .../libcxx/test/features/libcxx_macros.py     |    1 +
 79 files changed, 5614 insertions(+), 2 deletions(-)
 create mode 100644 libcxx/include/inplace_vector
 create mode 100644 libcxx/test/libcxx/containers/sequences/inplace_vector/assert.back.empty.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/inplace_vector/assert.front.empty.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/inplace_vector/assert.index.oob.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/inplace_vector/assert.iterator.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/inplace_vector/assert.pop_back.empty.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/inplace_vector/assert.unchecked_push_back.capacity.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/inplace_vector/nodiscard.verify.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/access.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/addressof.compile.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/common.h
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/compare.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/compare.three_way.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/constant_initialization.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/contiguous.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/capacity.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/empty.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/max_size.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/reserve.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_value.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_value_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/shrink_to_fit.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/size.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/swap.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_copy.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_initializer_list.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_iter_iter.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_move.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_size_value.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_default.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_from_range.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_iter_iter.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_size.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_size_value.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/copy.move_only.verify.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/copy.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/initializer_list.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/move.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/op_equal_initializer_list.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.data/data.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.data/data_const.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase_if.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/append_range.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/assign_range.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/clear.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/destroy_elements.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/emplace.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/emplace_back.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/erase_iter.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/erase_iter_iter.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_initializer_list.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_iter_iter.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_lvalue.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_rvalue.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_size_value.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_range.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/pop_back.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_exception_safety.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_rvalue.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/try_push_back.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/unchecked_push_back.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.special/swap.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/iterator_concept_conformance.compile.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/iterators.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/range_concept_conformance.compile.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/reverse_iterators.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/triviality.compile.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/types.compile.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/inplace_vector/zero_capacity.exceptions.pass.cpp

diff --git a/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake b/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake
index 2d617737e9635..185b6fa2abfcd 100644
--- a/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake
+++ b/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake
@@ -6,6 +6,7 @@ set(_defines
     _LIBCPP_ABI_BOUNDED_UNIQUE_PTR
     _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY
     _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
+    _LIBCPP_ABI_BOUNDED_ITERATORS_IN_INPLACE_VECTOR
 )
 set(LIBCXX_ABI_DEFINES "${_defines}" CACHE STRING "")
 set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index cb7ae820bc012..b2add223b1dd0 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -1042,6 +1042,7 @@ set(files
   functional
   future
   initializer_list
+  inplace_vector
   iomanip
   ios
   iosfwd
diff --git a/libcxx/include/inplace_vector b/libcxx/include/inplace_vector
new file mode 100644
index 0000000000000..0d0f0418274dd
--- /dev/null
+++ b/libcxx/include/inplace_vector
@@ -0,0 +1,1130 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_INPLACE_VECTOR
+#define _LIBCPP_INPLACE_VECTOR
+
+/*
+    inplace_vector synopsis
+
+namespace std {
+  template<class T, size_t N>
+  class inplace_vector {
+  public:
+    // types:
+    using value_type             = T;
+    using pointer                = T*;
+    using const_pointer          = const T*;
+    using reference              = value_type&;
+    using const_reference        = const value_type&;
+    using size_type              = size_t;
+    using difference_type        = ptrdiff_t;
+    using iterator               = implementation-defined; // see [container.requirements]
+    using const_iterator         = implementation-defined; // see [container.requirements]
+    using reverse_iterator       = std::reverse_iterator<iterator>;
+    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+    // [inplace.vector.cons], construct/copy/destroy
+    constexpr inplace_vector() noexcept;
+    constexpr explicit inplace_vector(size_type n);                         // freestanding-deleted
+    constexpr inplace_vector(size_type n, const T& value);                  // freestanding-deleted
+    template<class InputIterator>
+      constexpr inplace_vector(InputIterator first, InputIterator last);    // freestanding-deleted
+    template<container-compatible-range<T> R>
+      constexpr inplace_vector(from_range_t, R&& rg);                       // freestanding-deleted
+    constexpr inplace_vector(const inplace_vector&);
+    constexpr inplace_vector(inplace_vector&&)
+      noexcept(N == 0 || is_nothrow_move_constructible_v<T>);
+    constexpr inplace_vector(initializer_list<T> il);                       // freestanding-deleted
+    constexpr ~inplace_vector();
+    constexpr inplace_vector& operator=(const inplace_vector& other);
+    constexpr inplace_vector& operator=(inplace_vector&& other)
+      noexcept(N == 0 || (is_nothrow_move_assignable_v<T> &&
+                          is_nothrow_move_constructible_v<T>));
+    constexpr inplace_vector& operator=(initializer_list<T>);               // freestanding-deleted
+    template<class InputIterator>
+      constexpr void assign(InputIterator first, InputIterator last);       // freestanding-deleted
+    template<container-compatible-range<T> R>
+      constexpr void assign_range(R&& rg);                                  // freestanding-deleted
+    constexpr void assign(size_type n, const T& u);                         // freestanding-deleted
+    constexpr void assign(initializer_list<T> il);                          // freestanding-deleted
+
+    // iterators
+    constexpr iterator               begin()         noexcept;
+    constexpr const_iterator         begin()   const noexcept;
+    constexpr iterator               end()           noexcept;
+    constexpr const_iterator         end()     const noexcept;
+    constexpr reverse_iterator       rbegin()        noexcept;
+    constexpr const_reverse_iterator rbegin()  const noexcept;
+    constexpr reverse_iterator       rend()          noexcept;
+    constexpr const_reverse_iterator rend()    const noexcept;
+
+    constexpr const_iterator         cbegin()  const noexcept;
+    constexpr const_iterator         cend()    const noexcept;
+    constexpr const_reverse_iterator crbegin() const noexcept;
+    constexpr const_reverse_iterator crend()   const noexcept;
+
+    // [inplace.vector.capacity], capacity
+    constexpr bool empty() const noexcept;
+    constexpr size_type size() const noexcept;
+    static constexpr size_type max_size() noexcept;
+    static constexpr size_type capacity() noexcept;
+    constexpr void resize(size_type sz);                                    // freestanding-deleted
+    constexpr void resize(size_type sz, const T& c);                        // freestanding-deleted
+    static constexpr void reserve(size_type n);                             // freestanding-deleted
+    static constexpr void shrink_to_fit() noexcept;
+
+    // element access
+    constexpr reference       operator[](size_type n);
+    constexpr const_reference operator[](size_type n) const;
+    constexpr reference       at(size_type n);                              // freestanding-deleted
+    constexpr const_reference at(size_type n) const;                        // freestanding-deleted
+    constexpr reference       front();
+    constexpr const_reference front() const;
+    constexpr reference       back();
+    constexpr const_reference back() const;
+
+    // [inplace.vector.data], data access
+    constexpr       T* data()       noexcept;
+    constexpr const T* data() const noexcept;
+
+    // [inplace.vector.modifiers], modifiers
+    template<class... Args>
+      constexpr reference emplace_back(Args&&... args);                     // freestanding-deleted
+    constexpr reference push_back(const T& x);                              // freestanding-deleted
+    constexpr reference push_back(T&& x);                                   // freestanding-deleted
+    template<container-compatible-range<T> R>
+      constexpr void append_range(R&& rg);                                  // freestanding-deleted
+    constexpr void pop_back();
+
+    template<class... Args>
+      constexpr optional<reference> try_emplace_back(Args&&... args);
+    constexpr optional<reference> try_push_back(const T& x);
+    constexpr optional<reference> try_push_back(T&& x);
+
+    template<class... Args>
+      constexpr reference unchecked_emplace_back(Args&&... args);
+    constexpr reference unchecked_push_back(const T& x);
+    constexpr reference unchecked_push_back(T&& x);
+
+    template<class... Args>
+      constexpr iterator emplace(const_iterator position, Args&&... args);  // freestanding-deleted
+    constexpr iterator insert(const_iterator position, const T& x);         // freestanding-deleted
+    constexpr iterator insert(const_iterator position, T&& x);              // freestanding-deleted
+    constexpr iterator insert(const_iterator position, size_type n,         // freestanding-deleted
+                              const T& x);
+    template<class InputIterator>
+      constexpr iterator insert(const_iterator position,                    // freestanding-deleted
+                                InputIterator first, InputIterator last);
+    template<container-compatible-range<T> R>
+      constexpr iterator insert_range(const_iterator position, R&& rg);     // freestanding-deleted
+    constexpr iterator insert(const_iterator position,                      // freestanding-deleted
+                              initializer_list<T> il);
+    constexpr iterator erase(const_iterator position);
+    constexpr iterator erase(const_iterator first, const_iterator last);
+    constexpr void swap(inplace_vector& x)
+      noexcept(N == 0 || (is_nothrow_swappable_v<T> &&
+                          is_nothrow_move_constructible_v<T>));
+    constexpr void clear() noexcept;
+
+    friend constexpr bool operator==(const inplace_vector& x,
+                                     const inplace_vector& y);
+    friend constexpr auto
+      operator<=>(const inplace_vector& x, const inplace_vector& y)
+        requires requires (const T t) { synth-three-way(t, t); }
+      {
+        return lexicographical_compare_three_way(x.begin(), x.end(), y.begin(), y.end(),
+                                                 synth-three-way);
+      }
+    friend constexpr void swap(inplace_vector& x, inplace_vector& y)
+      noexcept(N == 0 || (is_nothrow_swappable_v<T> &&
+                          is_nothrow_move_constructible_v<T>))
+      { x.swap(y); }
+  };
+}
+*/
+
+#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
+#  include <__cxx03/__config>
+#else
+#  include <__config>
+
+#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#    pragma GCC system_header
+#  endif
+
+_LIBCPP_PUSH_MACROS
+#  include <__undef_macros>
+
+#  if _LIBCPP_STD_VER >= 26
+#    include <__algorithm/fill_n.h>
+#    include <__algorithm/lexicographical_compare_three_way.h>
+#    include <__algorithm/min.h>
+#    include <__algorithm/move.h>
+#    include <__algorithm/move_backward.h>
+#    include <__algorithm/ranges_copy.h>
+#    include <__algorithm/ranges_copy_n.h>
+#    include <__algorithm/remove.h>
+#    include <__algorithm/remove_if.h>
+#    include <__algorithm/rotate.h>
+#    include <__algorithm/swap_ranges.h>
+#    include <__compare/synth_three_way.h>
+#    include <__compare/three_way_comparable.h>
+#    include <__concepts/assignable.h>
+#    include <__cstddef/ptrdiff_t.h>
+#    include <__cstddef/size_t.h>
+#    include <__iterator/bounded_iter.h>
+#    include <__iterator/capacity_aware_iterator.h>
+#    include <__iterator/concepts.h>
+#    include <__iterator/distance.h>
+#    include <__iterator/iterator_traits.h>
+#    include <__iterator/move_iterator.h>
+#    include <__iterator/reverse_iterator.h>
+#    include <__memory/construct_at.h>
+#    include <__memory/destroy.h>
+#    include <__memory/ranges_destroy.h>
+#    include <__memory/ranges_uninitialized_algorithms.h>
+#    include <__memory/uninitialized_algorithms.h>
+#    include <__new/exceptions.h>
+#    include <__ranges/access.h>
+#    include <__ranges/concepts.h>
+#    include <__ranges/container_compatible_range.h>
+#    include <__ranges/from_range.h>
+#    include <__type_traits/is_nothrow_constructible.h>
+#    include <__type_traits/is_swappable.h>
+#    include <__type_traits/is_trivially_assignable.h>
+#    include <__type_traits/is_trivially_constructible.h>
+#    include <__type_traits/is_trivially_copyable.h>
+#    include <__type_traits/is_trivially_destructible.h>
+#    include <__utility/exception_guard.h>
+#    include <__utility/move.h>
+#    include <__utility/unreachable.h>
+#    include <__verbose_trap>
+#    include <initializer_list>
+#    include <limits>
+#    include <optional>
+#    include <stdexcept>
+#    include <version>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, size_t _Cap>
+class inplace_vector {
+private:
+  static constexpr decltype(auto) __get_size_type() {
+    if constexpr (_Cap <= std::numeric_limits<unsigned char>::max() && sizeof(unsigned char) < sizeof(std::size_t))
+      return static_cast<unsigned char>(0);
+    else if constexpr (_Cap <= std::numeric_limits<unsigned short>::max() &&
+                       sizeof(unsigned short) < sizeof(std::size_t))
+      return static_cast<unsigned short>(0);
+    else if constexpr (_Cap <= std::numeric_limits<unsigned int>::max() && sizeof(unsigned int) < sizeof(std::size_t))
+      return static_cast<unsigned int>(0);
+    else if constexpr (_Cap <= std::numeric_limits<unsigned long>::max() && sizeof(unsigned long) < sizeof(std::size_t))
+      return static_cast<unsigned long>(0);
+    else
+      return static_cast<std::size_t>(0);
+  }
+
+  using __size_type = decltype(__get_size_type());
+
+  union {
+    _Tp __elems_[_Cap];
+  };
+  __size_type __size_{0};
+
+  constexpr void __init() {
+    if consteval {
+      if constexpr (is_trivially_copyable_v<_Tp> && is_trivially_default_constructible_v<_Tp> &&
+                    is_trivially_assignable_v<_Tp&, _Tp>) {
+        for (size_t __i{0}; __i < _Cap; ++__i) {
+          __elems_[__i] = _Tp();
+        }
+      } else {
+#    if !defined(__cpp_trivial_union)
+        _LIBCPP_VERBOSE_ABORT("std::inplace_vector<T,N> currently cannot be used in constant expressions for "
+                              "non-trivial T on compilers where P3074 is not implemented.");
+#    endif
+      }
+    }
+    // std::start_lifetime_as_array?
+  }
+
+public:
+  using value_type      = _Tp;
+  using pointer         = _Tp*;
+  using const_pointer   = const _Tp*;
+  using reference       = value_type&;
+  using const_reference = const value_type&;
+  using size_type       = size_t;
+  using difference_type = ptrdiff_t;
+#    ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_INPLACE_VECTOR
+  using iterator       = __bounded_iter<pointer>;
+  using const_iterator = __bounded_iter<const_pointer>;
+#    else
+  using iterator       = __capacity_aware_iterator<pointer, inplace_vector<_Tp, _Cap>, _Cap>;
+  using const_iterator = __capacity_aware_iterator<const_pointer, inplace_vector<_Tp, _Cap>, _Cap>;
+#    endif
+  using reverse_iterator       = std::reverse_iterator<iterator>;
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+private:
+  struct _ConstructTransaction {
+    constexpr explicit _ConstructTransaction(inplace_vector& __v, size_type __n)
+        : __v_(__v), __pos_(__v.data() + __v.__size_), __new_end_(__v.data() + __v.__size_ + __n) {}
+
+    constexpr ~_ConstructTransaction() { __v_.__size_ = __pos_ - __v_.data(); }
+
+    inplace_vector& __v_;
+    pointer __pos_;
+    const_pointer const __new_end_;
+
+    _ConstructTransaction(_ConstructTransaction const&)            = delete;
+    _ConstructTransaction& operator=(_ConstructTransaction const&) = delete;
+  };
+
+  constexpr void __move_range(pointer __from_s, pointer __from_e, pointer __to) {
+    pointer __old_last  = data() + __size_;
+    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, ++__pos, __tx.__pos_ = __pos) {
+        std::construct_at(__pos, std::move(*__i));
+      }
+    }
+    std::move_backward(__from_s, __from_s + __n, __old_last);
+  }
+
+  template <class _It, class _Sentinel>
+  constexpr void __assign(_It __first, _Sentinel __last) {
+    if constexpr (std::sized_sentinel_for<_Sentinel, _It>) {
+      auto __d = std::ranges::distance(__first, __last);
+      reserve(__d);
+
+      if (size() > static_cast<size_type>(__d)) {
+        auto [__it_in, __it_out] = std::ranges::copy(std::move(__first), __last, begin());
+        std::ranges::destroy(__it_out, end());
+      } else {
+        auto [__it_in, __it_out] = std::ranges::copy_n(std::move(__first), __size_, data());
+        std::ranges::uninitialized_copy(__it_in, __last, __it_out, data() + _Cap);
+      }
+      __size_ = __d;
+    } else {
+      size_t __d = 0;
+      for (; __first != __last && __d < __size_; (void)++__first, ++__d) {
+        data()[__d] = *__first;
+      }
+
+      if (__first == __last) { // __d <= size()
+        std::destroy(data() + __d, data() + __size_);
+        __size_ = __d;
+      } else { // __d > size()
+        while (__first != __last) {
+          emplace_back(*__first);
+          __first++;
+        }
+      }
+    }
+  }
+
+  template <class _It, class _Sentinel>
+  constexpr iterator __insert(const_iterator __position, _It __first, _Sentinel __last) {
+    pointer __pos        = data() + (__position - cbegin());
+    size_type __old_size = __size_;
+    if constexpr (std::sized_sentinel_for<_Sentinel, _It>) {
+      const auto __d = std::ranges::distance(__first, __last);
+      if (__d > static_cast<difference_type>(_Cap - __size_)) {
+        std::__throw_bad_alloc();
+      }
+      std::ranges::uninitialized_copy(std::move(__first), __last, data() + __size_, data() + _Cap);
+      __size_ += __d;
+    } else {
+      auto __guard = std::__make_exception_guard([this, __old_size]() {
+        std::ranges::destroy(this->data() + __old_size, this->data() + __size_);
+        this->__size_ = __old_size;
+      });
+
+      while (__first != __last) {
+        emplace_back(*__first);
+        __first++;
+      }
+
+      __guard.__complete();
+    }
+
+    iterator __iter = __make_iter(__pos);
+    if (__size_ > 0) {
+      std::rotate(__iter, begin() + __old_size, end());
+    }
+
+    return __iter;
+  }
+
+  constexpr iterator __make_iter(pointer __p) {
+#    ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_INPLACE_VECTOR
+    return std::__make_bounded_iter(__p, data(), data() + __size_);
+#    else
+    return std::__make_capacity_aware_iterator<pointer, inplace_vector<_Tp, _Cap>, _Cap>(__p);
+#    endif
+  }
+
+  constexpr const_iterator __make_iter(const_pointer __p) const {
+#    ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_INPLACE_VECTOR
+    return std::__make_bounded_iter(__p, data(), data() + __size_);
+#    else
+    return std::__make_capacity_aware_iterator<const_pointer, inplace_vector<_Tp, _Cap>, _Cap>(__p);
+#    endif
+  }
+
+public:
+  // [inplace.vector.cons], construct/copy/destroy
+  constexpr inplace_vector() noexcept { __init(); }
+
+  constexpr explicit inplace_vector(size_type __n) {
+    __init();
+    reserve(__n);
+    std::uninitialized_value_construct_n(data(), __n);
+    __size_ = __n;
+  }
+
+  constexpr inplace_vector(size_type __n, const _Tp& __c) {
+    __init();
+    reserve(__n);
+    std::uninitialized_fill_n(data(), __n, __c);
+    __size_ = __n;
+  }
+
+  template <class _InputIterator>
+    requires __has_input_iterator_category<_InputIterator>::value
+  constexpr inplace_vector(_InputIterator __first, _InputIterator __last) {
+    __init();
+    if constexpr (std::sized_sentinel_for<_InputIterator, _InputIterator>) {
+      auto __n = std::ranges::distance(__first, __last);
+      reserve(__n);
+      std::uninitialized_copy(__first, __last, data());
+      __size_ = __n;
+    } else {
+      auto __guard = std::__make_exception_guard([this] { clear(); });
+
+      while (__first != __last) {
+        emplace_back(*__first);
+        __first++;
+      }
+
+      __guard.__complete();
+    }
+  }
+
+  template <_ContainerCompatibleRange<_Tp> _Range>
+  constexpr inplace_vector(from_range_t, _Range&& __rg) {
+    __init();
+    append_range(__rg);
+  }
+
+  constexpr inplace_vector(const inplace_vector&)
+    requires is_trivially_copy_constructible_v<_Tp>
+  = default;
+
+  constexpr inplace_vector(const inplace_vector& __x) noexcept(is_nothrow_copy_constructible_v<_Tp>) {
+    __init();
+    std::uninitialized_copy(__x.begin(), __x.end(), data());
+    __size_ = __x.size();
+  }
+
+  constexpr inplace_vector(inplace_vector&&)
+    requires is_trivially_move_constructible_v<_Tp>
+  = default;
+
+  constexpr inplace_vector(inplace_vector&& __x) noexcept(is_nothrow_move_constructible_v<_Tp>) {
+    __init();
+    std::uninitialized_move(__x.begin(), __x.end(), data());
+    __size_ = __x.size();
+  }
+
+  constexpr inplace_vector(std::initializer_list<_Tp> __il) {
+    __init();
+    reserve(__il.size());
+    std::uninitialized_copy(__il.begin(), __il.end(), data());
+    __size_ = __il.size();
+  }
+
+  constexpr ~inplace_vector()
+    requires is_trivially_destructible_v<_Tp>
+  = default;
+
+  constexpr ~inplace_vector() { clear(); }
+
+  constexpr inplace_vector& operator=(const inplace_vector&)
+    requires is_trivially_destructible_v<_Tp> && is_trivially_copy_assignable_v<_Tp> &&
+                 is_trivially_copy_constructible_v<_Tp>
+  = default;
+
+  constexpr inplace_vector& operator=(const inplace_vector& __x) noexcept(
+      is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_assignable_v<_Tp>) {
+    if (std::addressof(__x) != this) {
+      assign(__x.begin(), __x.end());
+    }
+
+    return *this;
+  }
+
+  constexpr inplace_vector& operator=(inplace_vector&&)
+    requires is_trivially_destructible_v<_Tp> && is_trivially_move_assignable_v<_Tp> &&
+                 is_trivially_move_constructible_v<_Tp>
+  = default;
+
+  constexpr inplace_vector&
+  operator=(inplace_vector&& __x) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) {
+    if (std::addressof(__x) != this) {
+      assign(std::make_move_iterator(__x.begin()), std::make_move_iterator(__x.end()));
+    }
+
+    return *this;
+  }
+
+  constexpr inplace_vector& operator=(std::initializer_list<_Tp> __il) {
+    assign(__il.begin(), __il.end());
+    return *this;
+  }
+
+  template <class _InputIterator>
+    requires __has_input_iterator_category<_InputIterator>::value
+  constexpr void assign(_InputIterator __first, _InputIterator __last) {
+    __assign(__first, __last);
+  }
+
+  template <_ContainerCompatibleRange<_Tp> _Range>
+  constexpr void assign_range(_Range&& __rg) {
+    static_assert(std::assignable_from<_Tp&, std::ranges::range_reference_t<_Range>>);
+    __assign(std::ranges::begin(__rg), std::ranges::end(__rg));
+  }
+
+  constexpr void assign(size_type __n, const _Tp& __u) {
+    reserve(__n);
+    std::__fill_n(begin(), std::min(__n, static_cast<size_type>(__size_)), __u);
+
+    if (__n <= size()) {
+      std::destroy(begin() + __n, end());
+    } else {
+      std::uninitialized_fill(data() + size(), data() + __n, __u);
+    }
+    __size_ = __n;
+  }
+
+  constexpr void assign(std::initializer_list<_Tp> __il) { assign(__il.begin(), __il.end()); }
+
+  // iterators
+  [[nodiscard]] constexpr iterator begin() noexcept { return __make_iter(data()); }
+  [[nodiscard]] constexpr const_iterator begin() const noexcept { return __make_iter(data()); }
+  [[nodiscard]] constexpr iterator end() noexcept { return __make_iter(data() + __size_); }
+  [[nodiscard]] constexpr const_iterator end() const noexcept { return __make_iter(data() + __size_); }
+
+  [[nodiscard]] constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
+  [[nodiscard]] constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
+  [[nodiscard]] constexpr reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
+  [[nodiscard]] constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
+
+  [[nodiscard]] constexpr const_iterator cbegin() const noexcept { return begin(); }
+  [[nodiscard]] constexpr const_iterator cend() const noexcept { return end(); }
+  [[nodiscard]] constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
+  [[nodiscard]] constexpr const_reverse_iterator crend() const noexcept { return rend(); }
+
+  // [inplace.vector.capacity], capacity
+  [[nodiscard]] constexpr bool empty() const noexcept { return __size_ == 0; }
+  [[nodiscard]] constexpr size_type size() const noexcept { return __size_; }
+  [[nodiscard]] static constexpr size_type max_size() noexcept { return _Cap; }
+  [[nodiscard]] static constexpr size_type capacity() noexcept { return _Cap; }
+
+  constexpr void resize(size_t __count) {
+    reserve(__count);
+    if (__count > __size_) {
+      std::uninitialized_value_construct_n(data() + __size_, __count - __size_);
+    } else if (__count < __size_) {
+      std::destroy_n(data() + __count, __size_ - __count);
+    }
+    __size_ = __count;
+  }
+
+  constexpr void resize(size_t __count, const _Tp& __v) {
+    reserve(__count);
+    if (__count > __size_) {
+      std::uninitialized_fill_n(data() + __size_, __count - __size_, __v);
+    } else if (__count < __size_) {
+      std::destroy_n(data() + __count, __size_ - __count);
+    }
+    __size_ = __count;
+  }
+
+  static constexpr void reserve(size_type __new_cap) {
+    if (__new_cap > _Cap) {
+      std::__throw_bad_alloc();
+    }
+  }
+
+  static constexpr void shrink_to_fit() noexcept {}
+
+  // element access
+  [[nodiscard]] constexpr reference operator[](size_type __pos) {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __pos < _Cap, "inplace_vector<T, N>::operator[](size_type pos): index with pos >= N");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __pos < __size_, "inplace_vector<T, N>::operator[](size_type pos): index with pos >= size()");
+    return data()[__pos];
+  }
+
+  [[nodiscard]] constexpr const_reference operator[](size_type __pos) const {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __pos < _Cap, "inplace_vector<T, N>::operator[](size_type pos) const: index with pos >= N");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __pos < __size_, "inplace_vector<T, N>::operator[](size_type pos) const: index with pos >= size()");
+    return data()[__pos];
+  }
+
+  [[nodiscard]] constexpr reference at(size_type __pos) {
+    if (__pos >= __size_) {
+      std::__throw_out_of_range("inplace_vector<T,N>::at(size_type pos): access with pos >= size()");
+    }
+    return data()[__pos];
+  }
+
+  [[nodiscard]] constexpr const_reference at(size_type __pos) const {
+    if (__pos >= __size_) {
+      std::__throw_out_of_range("inplace_vector<T,N>::at(size_type pos) const: access with pos >= size()");
+    }
+    return data()[__pos];
+  }
+
+  [[nodiscard]] constexpr reference front() {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__size_ > 0, "inplace_vector<T,N>::front(): access with size() == 0");
+    return *data();
+  }
+
+  [[nodiscard]] constexpr const_reference front() const {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__size_ > 0, "inplace_vector<T,N>::front() const: access with size() == 0");
+    return *data();
+  }
+
+  [[nodiscard]] constexpr reference back() {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__size_ > 0, "inplace_vector<T,N>::back(): access with size() == 0");
+    return *(data() + __size_ - 1);
+  }
+
+  [[nodiscard]] constexpr const_reference back() const {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__size_ > 0, "inplace_vector<T,N>::back() const: access with size() == 0");
+    return *(data() + __size_ - 1);
+  }
+
+  // [inplace.vector.data], data access
+  [[nodiscard]] constexpr pointer data() noexcept { return __elems_; }
+  [[nodiscard]] constexpr const_pointer data() const noexcept { return __elems_; }
+
+  // [inplace.vector.modifiers], modifiers
+  template <class... _Args>
+  constexpr reference emplace_back(_Args&&... __args) {
+    if (size() == capacity())
+      std::__throw_bad_alloc();
+    return unchecked_emplace_back(std::forward<_Args>(__args)...);
+  }
+
+  constexpr reference push_back(const _Tp& __x) { return emplace_back(__x); }
+  constexpr reference push_back(_Tp&& __x) { return emplace_back(std::move(__x)); }
+
+  template <_ContainerCompatibleRange<_Tp> _Range>
+  constexpr void append_range(_Range&& __rg) {
+    if constexpr (std::ranges::sized_range<_Range> || std::ranges::forward_range<_Range>) {
+      const auto __d = std::ranges::distance(__rg);
+
+      if (__d > static_cast<difference_type>(_Cap - size())) {
+        std::__throw_bad_alloc();
+      }
+
+      std::ranges::uninitialized_copy(
+          std::ranges::begin(__rg), std::ranges::end(__rg), data() + __size_, data() + __size_ + __d);
+      __size_ += __d;
+    } else {
+      auto __guard = std::__make_exception_guard([__old_size = this->__size_, this] {
+        std::destroy(this->data() + __old_size, this->data() + this->__size_);
+        this->__size_ = __old_size;
+      });
+
+      auto [__it_in, __it_out] = std::ranges::uninitialized_copy(
+          std::ranges::begin(__rg), std::ranges::end(__rg), data() + __size_, data() + _Cap);
+
+      __size_ = __it_out - data();
+
+      if (__it_in != std::ranges::end(__rg)) {
+        std::__throw_bad_alloc();
+      }
+
+      __guard.__complete();
+    }
+  }
+
+  constexpr void pop_back() {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "inplace_vector<T,N>::pop_back(): Called on empty inplace_vector");
+    --__size_;
+    std::destroy_at(data() + __size_);
+  }
+
+  template <class... _Args>
+  [[nodiscard]] constexpr optional<reference> try_emplace_back(_Args&&... __args) {
+    if (size() == capacity()) {
+      return std::nullopt;
+    }
+
+    return std::optional<reference>(std::in_place, unchecked_emplace_back(std::forward<_Args>(__args)...));
+  }
+
+  [[nodiscard]] constexpr optional<reference> try_push_back(const _Tp& __x) { return try_emplace_back(__x); }
+  [[nodiscard]] constexpr optional<reference> try_push_back(_Tp&& __x) { return try_emplace_back(std::move(__x)); }
+
+  template <class... _Args>
+  constexpr reference unchecked_emplace_back(_Args&&... __args) {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        size() < capacity(),
+        "inplace_vector<T,N>::unchecked_emplace_back(Args...): Adding element when size() >= capacity()");
+    {
+      _ConstructTransaction __tx(*this, 1);
+      std::construct_at(data() + __size_, std::forward<_Args>(__args)...);
+      __tx.__pos_++;
+    }
+
+    return back();
+  }
+
+  constexpr reference unchecked_push_back(const _Tp& __x) { return unchecked_emplace_back(__x); }
+  constexpr reference unchecked_push_back(_Tp&& __x) { return unchecked_emplace_back(std::move(__x)); }
+
+  template <class... _Args>
+  constexpr iterator emplace(const_iterator __position, _Args&&... __args) {
+    if (size() == capacity()) {
+      std::__throw_bad_alloc();
+    }
+
+    pointer __p = data() + (__position - begin());
+
+    if (__position == end()) {
+      emplace_back(std::forward<_Args>(__args)...);
+    } else {
+      _Tp __temp_value = _Tp(std::forward<_Args>(__args)...);
+      __move_range(__p, data() + __size_, __p + 1);
+      *__p = std::move(__temp_value);
+    }
+
+    return __make_iter(__p);
+  }
+
+  constexpr iterator insert(const_iterator __position, const _Tp& __x) { return emplace(__position, __x); }
+  constexpr iterator insert(const_iterator __position, _Tp&& __x) { return emplace(__position, std::move(__x)); }
+
+  constexpr iterator insert(const_iterator __position, size_type __n, const _Tp& __x) {
+    if ((_Cap - __size_) < __n) {
+      std::__throw_bad_alloc();
+    }
+
+    pointer __p = data() + (__position - begin());
+
+    if (__n == 0) {
+      return __make_iter(__p);
+    }
+
+    std::uninitialized_fill_n(data() + __size_, __n, __x);
+    __size_ = __size_ + __n;
+
+    iterator __it = __make_iter(__p);
+
+    std::rotate(__it, end() - __n, end());
+
+    return __it;
+  }
+
+  template <class _InputIterator>
+    requires __has_input_iterator_category<_InputIterator>::value
+  constexpr iterator insert(const_iterator __position, _InputIterator __first, _InputIterator __last) {
+    return __insert(__position, __first, __last);
+  }
+
+  template <_ContainerCompatibleRange<_Tp> _Range>
+  constexpr iterator insert_range(const_iterator __position, _Range&& __rg) {
+    return __insert(__position, std::ranges::begin(__rg), std::ranges::end(__rg));
+  }
+
+  constexpr iterator insert(const_iterator __position, std::initializer_list<_Tp> __il) {
+    return __insert(__position, __il.begin(), __il.end());
+  }
+
+  constexpr iterator erase(const_iterator __position) {
+    pointer __pos = data() + (__position - cbegin());
+
+    std::move(__pos + 1, data() + __size_, __pos);
+    pop_back();
+
+    return __make_iter(__pos);
+  }
+
+  constexpr iterator erase(const_iterator __first, const_iterator __last) {
+    __size_type __x = __last - __first;
+    pointer __pos   = data() + (__first - cbegin());
+
+    if (__x == 0) {
+      return __make_iter(__pos);
+    }
+
+    pointer __end = std::move(__pos + __x, data() + __size_, __pos);
+    std::destroy_n(__end, __x);
+
+    __size_ -= __x;
+    return __make_iter(__pos);
+  }
+
+  constexpr void
+  swap(inplace_vector& __x) noexcept(is_nothrow_swappable_v<_Tp> && is_nothrow_move_constructible_v<_Tp>) {
+    inplace_vector& __smaller = __x.size() < size() ? __x : *this;
+    inplace_vector& __bigger  = __x.size() >= size() ? __x : *this;
+
+    size_type __n1 = __smaller.size();
+    size_type __n2 = __bigger.size();
+
+    std::swap_ranges(__smaller.begin(), __smaller.end(), __bigger.begin());
+
+    if (__n1 != __n2) {
+      using std::swap;
+      std::uninitialized_move(__bigger.data() + __n1, __bigger.data() + __n2, __smaller.data() + __n1);
+      __smaller.__size_ = __n2;
+      std::destroy(__bigger.data() + __n1, __bigger.data() + __n2);
+      __bigger.__size_ = __n1;
+    }
+  }
+
+  constexpr void clear() noexcept {
+    std::destroy(begin(), end());
+    __size_ = 0;
+  }
+
+  friend constexpr bool operator==(const inplace_vector& __x, const inplace_vector& __y) {
+    if (__x.size() != __y.size()) {
+      return false;
+    }
+
+    for (size_type __i{0}; __i < __x.size(); __i++) {
+      if (__x[__i] != __y[__i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  friend constexpr auto operator<=>(const inplace_vector& __x, const inplace_vector& __y)
+    requires requires(const _Tp __t) { std::__synth_three_way(__t, __t); }
+  {
+    return std::lexicographical_compare_three_way(
+        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
+  }
+
+  friend constexpr void
+  swap(inplace_vector& __x,
+       inplace_vector& __y) noexcept(is_nothrow_swappable_v<_Tp> && is_nothrow_move_constructible_v<_Tp>) {
+    __x.swap(__y);
+  }
+};
+
+template <class _Tp>
+class inplace_vector<_Tp, 0> {
+public:
+  using value_type      = _Tp;
+  using pointer         = _Tp*;
+  using const_pointer   = const _Tp*;
+  using reference       = value_type&;
+  using const_reference = const value_type&;
+  using size_type       = size_t;
+  using difference_type = ptrdiff_t;
+#    ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_INPLACE_VECTOR
+  using iterator       = __bounded_iter<pointer>;
+  using const_iterator = __bounded_iter<const_pointer>;
+#    else
+  using iterator       = __capacity_aware_iterator<pointer, inplace_vector<_Tp, 0>, 0>;
+  using const_iterator = __capacity_aware_iterator<const_pointer, inplace_vector<_Tp, 0>, 0>;
+#    endif
+  using reverse_iterator       = std::reverse_iterator<iterator>;
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+  constexpr inplace_vector() = default;
+  constexpr explicit inplace_vector(size_type __n) { reserve(__n); }
+  constexpr inplace_vector(size_type __n, const _Tp&) { reserve(__n); }
+
+  template <class _InputIterator>
+    requires __has_input_iterator_category<_InputIterator>::value
+  constexpr inplace_vector(_InputIterator __first, _InputIterator __last) {
+    if (__first != __last) {
+      std::__throw_bad_alloc();
+    }
+  }
+
+  template <_ContainerCompatibleRange<_Tp> _Range>
+  constexpr inplace_vector(from_range_t, _Range&& __rg) {
+    if (std::ranges::begin(__rg) != std::ranges::end(__rg)) {
+      std::__throw_bad_alloc();
+    }
+  }
+
+  constexpr inplace_vector(const inplace_vector&) = default;
+  constexpr inplace_vector(inplace_vector&&)      = default;
+  constexpr inplace_vector(std::initializer_list<_Tp> __il) { reserve(__il.size()); }
+  constexpr ~inplace_vector()                                = default;
+  constexpr inplace_vector& operator=(const inplace_vector&) = default;
+  constexpr inplace_vector& operator=(inplace_vector&&)      = default;
+
+  constexpr inplace_vector& operator=(std::initializer_list<_Tp> __il) {
+    reserve(__il.size());
+    return *this;
+  }
+
+  template <class _InputIterator>
+    requires __has_input_iterator_category<_InputIterator>::value
+  constexpr void assign(_InputIterator __first, _InputIterator __last) {
+    if (__first != __last) {
+      std::__throw_bad_alloc();
+    }
+  }
+
+  template <_ContainerCompatibleRange<_Tp> _Range>
+  constexpr void assign_range(_Range&& __rg) {
+    static_assert(std::assignable_from<_Tp&, std::ranges::range_reference_t<_Range>>);
+    if (std::ranges::begin(__rg) != std::ranges::end(__rg)) {
+      std::__throw_bad_alloc();
+    }
+  }
+
+  constexpr void assign(size_type __n, const _Tp&) { reserve(__n); }
+  constexpr void assign(std::initializer_list<_Tp> __il) { reserve(__il.size()); }
+
+private:
+  constexpr iterator __make_iter() {
+#    ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_INPLACE_VECTOR
+    return std::__make_bounded_iter(data(), data(), data());
+#    else
+    return std::__make_capacity_aware_iterator<pointer, inplace_vector<_Tp, 0>, 0>(data());
+#    endif
+  }
+
+  constexpr const_iterator __make_iter() const {
+#    ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_INPLACE_VECTOR
+    return std::__make_bounded_iter(data(), data(), data());
+#    else
+    return std::__make_capacity_aware_iterator<const_pointer, inplace_vector<_Tp, 0>, 0>(data());
+#    endif
+  }
+
+public:
+  // iterators
+  [[nodiscard]] constexpr iterator begin() noexcept { return __make_iter(); }
+  [[nodiscard]] constexpr const_iterator begin() const noexcept { return __make_iter(); }
+  [[nodiscard]] constexpr iterator end() noexcept { return __make_iter(); }
+  [[nodiscard]] constexpr const_iterator end() const noexcept { return __make_iter(); }
+
+  [[nodiscard]] constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
+  [[nodiscard]] constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
+  [[nodiscard]] constexpr reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
+  [[nodiscard]] constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
+
+  [[nodiscard]] constexpr const_iterator cbegin() const noexcept { return begin(); }
+  [[nodiscard]] constexpr const_iterator cend() const noexcept { return end(); }
+  [[nodiscard]] constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
+  [[nodiscard]] constexpr const_reverse_iterator crend() const noexcept { return rend(); }
+
+  // [inplace.vector.capacity], capacity
+  [[nodiscard]] constexpr bool empty() const noexcept { return true; }
+  [[nodiscard]] constexpr size_type size() const noexcept { return 0; }
+  [[nodiscard]] static constexpr size_type max_size() noexcept { return 0; }
+  [[nodiscard]] static constexpr size_type capacity() noexcept { return 0; }
+
+  constexpr void resize(size_type __sz) {
+    if (__sz != 0) {
+      std::__throw_bad_alloc();
+    }
+  }
+
+  constexpr void resize(size_type __sz, const _Tp&) {
+    if (__sz != 0) {
+      std::__throw_bad_alloc();
+    }
+  }
+
+  static constexpr void reserve(size_type __n) {
+    if (__n != 0) {
+      std::__throw_bad_alloc();
+    }
+  }
+
+  static constexpr void shrink_to_fit() noexcept {}
+
+  // element access
+  [[nodiscard, noreturn]] constexpr reference operator[](size_type) {
+    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::operator[]: access with N == 0");
+  }
+
+  [[nodiscard, noreturn]] constexpr const_reference operator[](size_type) const {
+    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::operator[] const: access with N == 0");
+  }
+
+  [[nodiscard, noreturn]] constexpr reference at(size_type) {
+    std::__throw_out_of_range("inplace_vector<T,0>::at(size_type n): access with N == 0");
+  }
+
+  [[nodiscard, noreturn]] constexpr const_reference at(size_type) const {
+    std::__throw_out_of_range("inplace_vector<T,0>::at(size_type n) const: access with N == 0");
+  }
+
+  [[nodiscard, noreturn]] constexpr reference front() {
+    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::front(): access with N == 0");
+  }
+
+  [[nodiscard, noreturn]] constexpr const_reference front() const {
+    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::front() const: access with N == 0");
+  }
+
+  [[nodiscard, noreturn]] constexpr reference back() {
+    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::back(): access with N == 0");
+  }
+
+  [[nodiscard, noreturn]] constexpr const_reference back() const {
+    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::back() const: access with N == 0");
+  }
+
+  // [inplace.vector.data], data access
+  [[nodiscard]] constexpr pointer data() noexcept { return nullptr; }
+  [[nodiscard]] constexpr const_pointer data() const noexcept { return nullptr; }
+
+  // [inplace.vector.modifiers], modifiers
+
+  template <class... _Args>
+  constexpr reference emplace_back(_Args&&...) {
+    std::__throw_bad_alloc();
+  }
+
+  constexpr reference push_back(const _Tp&) { std::__throw_bad_alloc(); }
+  constexpr reference push_back(_Tp&&) { std::__throw_bad_alloc(); }
+
+  template <_ContainerCompatibleRange<_Tp> _Range>
+  constexpr void append_range(_Range&& __rg) {
+    if (std::ranges::begin(__rg) != std::ranges::end(__rg)) {
+      std::__throw_bad_alloc();
+    }
+  }
+
+  constexpr void pop_back() { _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::pop_back(): use with N == 0"); }
+
+  template <class... _Args>
+  [[nodiscard]] constexpr optional<reference> try_emplace_back(_Args&&...) {
+    return std::nullopt;
+  }
+
+  [[nodiscard]] constexpr optional<reference> try_push_back(const _Tp&) { return std::nullopt; }
+  [[nodiscard]] constexpr optional<reference> try_push_back(_Tp&&) { return std::nullopt; }
+
+  template <class... _Args>
+  [[noreturn]] constexpr reference unchecked_emplace_back(_Args&&...) {
+    std::__throw_bad_alloc();
+  }
+
+  [[noreturn]] constexpr reference unchecked_push_back(const _Tp&) { std::__throw_bad_alloc(); }
+  [[noreturn]] constexpr reference unchecked_push_back(_Tp&&) { std::__throw_bad_alloc(); }
+
+  template <class... _Args>
+  [[noreturn]] constexpr iterator emplace(const_iterator, _Args&&...) {
+    std::__throw_bad_alloc();
+  }
+
+  [[noreturn]] constexpr iterator insert(const_iterator, const _Tp&) { std::__throw_bad_alloc(); }
+  [[noreturn]] constexpr iterator insert(const_iterator, _Tp&&) { std::__throw_bad_alloc(); }
+
+  constexpr iterator insert(const_iterator, size_type __n, const _Tp&) {
+    reserve(__n);
+    return begin();
+  }
+
+  template <class _InputIterator>
+    requires __has_input_iterator_category<_InputIterator>::value
+  constexpr iterator insert(const_iterator, _InputIterator __f, _InputIterator __l) {
+    if (__f != __l)
+      std::__throw_bad_alloc();
+
+    return begin();
+  }
+
+  template <_ContainerCompatibleRange<_Tp> _Range>
+  constexpr iterator insert_range(const_iterator, _Range&& __rg) {
+    if (std::ranges::begin(__rg) != std::ranges::end(__rg)) {
+      std::__throw_bad_alloc();
+    }
+    return begin();
+  }
+
+  constexpr iterator insert(const_iterator, initializer_list<_Tp> __il) {
+    reserve(__il.size());
+    return begin();
+  }
+
+  [[noreturn]] constexpr iterator erase(const_iterator) {
+    _LIBCPP_VERBOSE_ABORT("std::inplace_vector<T,0>::erase(const_iterator): use with N == 0");
+  }
+
+  constexpr iterator erase(const_iterator __f, const_iterator __l) {
+    if (__f != __l) {
+      _LIBCPP_VERBOSE_ABORT("std::inplace_vector<T,0>::erase(const_iterator, const_iterator): use with N == 0");
+    }
+
+    return begin();
+  }
+
+  constexpr void swap(inplace_vector&) noexcept {}
+
+  constexpr void clear() noexcept {}
+
+  constexpr friend bool operator==(const inplace_vector&, const inplace_vector&) { return true; }
+
+  constexpr friend auto operator<=>(const inplace_vector& __x, const inplace_vector& __y)
+    requires requires(const _Tp __t) { std::__synth_three_way(__t, __t); }
+  {
+    return std::lexicographical_compare_three_way(
+        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
+  }
+
+  constexpr friend void swap(inplace_vector&, inplace_vector&) noexcept {}
+};
+
+template <class _Tp, std::size_t _Cap, class _Pred>
+constexpr typename std::inplace_vector<_Tp, _Cap>::size_type
+erase_if(std::inplace_vector<_Tp, _Cap>& __c, _Pred __pred) {
+  if constexpr (_Cap != 0) {
+    auto __it = std::remove_if(__c.begin(), __c.end(), __pred);
+    auto __r  = std::distance(__it, __c.end());
+    __c.erase(__it, __c.end());
+
+    return __r;
+  }
+
+  return 0;
+}
+
+template <class _Tp, std::size_t _Cap, class _Up = _Tp>
+constexpr typename std::inplace_vector<_Tp, _Cap>::size_type
+erase(std::inplace_vector<_Tp, _Cap>& __c, const _Up& __value) {
+  return std::erase_if(__c, [&](const auto& __elem) { return __elem == __value; });
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#  endif // _LIBCPP_STD_VER >= 26
+
+#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
+
+#endif // _LIBCPP_INPLACE_VECTOR
diff --git a/libcxx/include/version b/libcxx/include/version
index d4d29b4d31a72..320799ea52c9b 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -140,7 +140,7 @@ __cpp_lib_has_unique_object_representations             201606L <type_traits>
 __cpp_lib_hazard_pointer                                202306L <hazard_pointer>
 __cpp_lib_hypot                                         201603L <cmath>
 __cpp_lib_incomplete_container_elements                 201505L <forward_list> <list> <vector>
-__cpp_lib_inplace_vector                                202406L <inplace_vector>
+__cpp_lib_inplace_vector                                202603L <inplace_vector>
 __cpp_lib_int_pow2                                      202002L <bit>
 __cpp_lib_integer_comparison_functions                  202002L <utility>
 __cpp_lib_integer_sequence                              202511L <utility>
@@ -593,7 +593,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_function_ref                         202306L
 // # define __cpp_lib_generate_random                      202403L
 // # define __cpp_lib_hazard_pointer                       202306L
-// # define __cpp_lib_inplace_vector                       202406L
+# define __cpp_lib_inplace_vector                       202603L
 # undef  __cpp_lib_integer_sequence
 # define __cpp_lib_integer_sequence                     202511L
 # define __cpp_lib_is_sufficiently_aligned              202411L
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.back.empty.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.back.empty.pass.cpp
new file mode 100644
index 0000000000000..1f49170059828
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.back.empty.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers, std-at-least-c++26
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <inplace_vector>
+
+// Call back() on an empty container.
+
+#include <cassert>
+#include <inplace_vector>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::inplace_vector<int, 4> c;
+  TEST_LIBCPP_ASSERT_FAILURE(c.back(), "inplace_vector<T,N>::back(): access with size() == 0");
+  TEST_LIBCPP_ASSERT_FAILURE(std::as_const(c).back(), "inplace_vector<T,N>::back() const: access with size() == 0");
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.front.empty.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.front.empty.pass.cpp
new file mode 100644
index 0000000000000..6656581073cfb
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.front.empty.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers, std-at-least-c++26
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <inplace_vector>
+
+#include <cassert>
+#include <inplace_vector>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::inplace_vector<int, 4> c;
+  TEST_LIBCPP_ASSERT_FAILURE(c.front(), "inplace_vector<T,N>::front(): access with size() == 0");
+  TEST_LIBCPP_ASSERT_FAILURE(std::as_const(c).front(), "inplace_vector<T,N>::front() const: access with size() == 0");
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.index.oob.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.index.oob.pass.cpp
new file mode 100644
index 0000000000000..45b07456d4ff3
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.index.oob.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers, std-at-least-c++26
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <inplace_vector>
+
+#include <cassert>
+#include <inplace_vector>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::inplace_vector<int, 4> c{1};
+  TEST_LIBCPP_ASSERT_FAILURE(c[1], "inplace_vector<T, N>::operator[](size_type pos): index with pos >= size()");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      std::as_const(c)[1], "inplace_vector<T, N>::operator[](size_type pos) const: index with pos >= size()");
+
+  TEST_LIBCPP_ASSERT_FAILURE(c[5], "inplace_vector<T, N>::operator[](size_type pos): index with pos >= N");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      std::as_const(c)[5], "inplace_vector<T, N>::operator[](size_type pos) const: index with pos >= N");
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.iterator.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.iterator.pass.cpp
new file mode 100644
index 0000000000000..78980fefdc78b
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.iterator.pass.cpp
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers, std-at-least-c++26
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: availability-verbose_abort-missing
+
+// <inplace_vector>
+
+// Check invalid iterator operations.
+
+#include <inplace_vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_INPLACE_VECTOR
+  { // operator++
+    std::inplace_vector<int, 4> c{1};
+    auto i = c.end();
+
+    TEST_LIBCPP_ASSERT_FAILURE(++i, "__bounded_iter::operator++: Attempt to advance an iterator past the end");
+    TEST_LIBCPP_ASSERT_FAILURE(i++, "__bounded_iter::operator++: Attempt to advance an iterator past the end");
+  }
+
+  { // operator--
+    std::inplace_vector<int, 4> c{1};
+    auto i = c.begin();
+
+    TEST_LIBCPP_ASSERT_FAILURE(--i, "__bounded_iter::operator--: Attempt to rewind an iterator past the start");
+    TEST_LIBCPP_ASSERT_FAILURE(i--, "__bounded_iter::operator--: Attempt to rewind an iterator past the start");
+  }
+
+  { // operator*
+    std::inplace_vector<int, 4> c;
+    auto i = c.begin();
+
+    TEST_LIBCPP_ASSERT_FAILURE(*i, "__bounded_iter::operator*: Attempt to dereference an iterator at the end");
+  }
+
+  { // operator[]
+    std::inplace_vector<int, 4> c{1};
+    auto i = c.begin();
+
+    TEST_LIBCPP_ASSERT_FAILURE(i[1], "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
+    TEST_LIBCPP_ASSERT_FAILURE(i[-1], "__bounded_iter::operator[]: Attempt to index an iterator past the start");
+  }
+
+  { // operator->
+    std::inplace_vector<int, 4> c{1};
+    auto i = c.end();
+
+    TEST_LIBCPP_ASSERT_FAILURE(
+        i.operator->(), "__bounded_iter::operator->: Attempt to dereference an iterator at the end");
+  }
+
+  { // operator+=
+    std::inplace_vector<int, 4> c{1};
+    auto i = c.begin();
+
+    TEST_LIBCPP_ASSERT_FAILURE(i += 2, "__bounded_iter::operator+=: Attempt to advance an iterator past the end");
+    TEST_LIBCPP_ASSERT_FAILURE(i += -1, "__bounded_iter::operator+=: Attempt to rewind an iterator past the start");
+  }
+
+  { // operator-=
+    std::inplace_vector<int, 4> c{1};
+    auto i = c.begin();
+
+    TEST_LIBCPP_ASSERT_FAILURE(i -= 1, "__bounded_iter::operator-=: Attempt to rewind an iterator past the start");
+    TEST_LIBCPP_ASSERT_FAILURE(i -= -2, "__bounded_iter::operator-=: Attempt to advance an iterator past the end");
+  }
+
+  {
+    std::inplace_vector<int, 0> c;
+
+    auto i = c.begin();
+    TEST_LIBCPP_ASSERT_FAILURE(++i, "__bounded_iter::operator++: Attempt to advance an iterator past the end");
+    TEST_LIBCPP_ASSERT_FAILURE(i++, "__bounded_iter::operator++: Attempt to advance an iterator past the end");
+    TEST_LIBCPP_ASSERT_FAILURE(--i, "__bounded_iter::operator--: Attempt to rewind an iterator past the start");
+    TEST_LIBCPP_ASSERT_FAILURE(i--, "__bounded_iter::operator--: Attempt to rewind an iterator past the start");
+    TEST_LIBCPP_ASSERT_FAILURE(i[0], "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
+    TEST_LIBCPP_ASSERT_FAILURE(i[0], "__bounded_iter::operator[]: Attempt to index an iterator past the start");
+    TEST_LIBCPP_ASSERT_FAILURE(
+        i.operator->(), "__bounded_iter::operator->: Attempt to dereference an iterator at the end");
+    TEST_LIBCPP_ASSERT_FAILURE(i += 1, "__bounded_iter::operator+=: Attempt to advance an iterator past the end");
+    TEST_LIBCPP_ASSERT_FAILURE(i += -1, "__bounded_iter::operator+=: Attempt to rewind an iterator past the start");
+    TEST_LIBCPP_ASSERT_FAILURE(i -= 1, "__bounded_iter::operator-=: Attempt to rewind an iterator past the start");
+    TEST_LIBCPP_ASSERT_FAILURE(i -= -1, "__bounded_iter::operator-=: Attempt to advance an iterator past the end");
+  }
+#else
+  std::inplace_vector<int, 4> c{1};
+  auto i = c.begin();
+
+  TEST_LIBCPP_ASSERT_FAILURE(
+      i += 5, "__capacity_aware_iterator::operator+=: Attempting to move iterator past its container's possible range");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      i += -5,
+      "__capacity_aware_iterator::operator+=: Attempting to move iterator past its container's possible range");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      i -= 5, "__capacity_aware_iterator::operator-=: Attempting to move iterator past its container's possible range");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      i -= -5,
+      "__capacity_aware_iterator::operator-=: Attempting to move iterator past its container's possible range");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      i[4], "__capacity_aware_iterator::operator[]: Attempting to index iterator past its container's possible range");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      i[-5], "__capacity_aware_iterator::operator[]: Attempting to index iterator past its container's possible range");
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.pop_back.empty.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.pop_back.empty.pass.cpp
new file mode 100644
index 0000000000000..2122618785d68
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.pop_back.empty.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers, std-at-least-c++26
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <inplace_vector>
+
+// Call pop_back() on an empty container.
+
+#include <inplace_vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::inplace_vector<int, 4> c;
+  TEST_LIBCPP_ASSERT_FAILURE(c.pop_back(), "inplace_vector<T,N>::pop_back(): Called on empty inplace_vector");
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.unchecked_push_back.capacity.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.unchecked_push_back.capacity.pass.cpp
new file mode 100644
index 0000000000000..222e4181125a5
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.unchecked_push_back.capacity.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers, std-at-least-c++26
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <inplace_vector>
+
+#include <cassert>
+#include <inplace_vector>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::inplace_vector<int, 2> c{1, 2};
+  int value = 3;
+  TEST_LIBCPP_ASSERT_FAILURE(
+      c.unchecked_emplace_back(3),
+      "inplace_vector<T,N>::unchecked_emplace_back(Args...): Adding element when size() >= capacity()");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      c.unchecked_push_back(value),
+      "inplace_vector<T,N>::unchecked_emplace_back(Args...): Adding element when size() >= capacity()");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      c.unchecked_push_back(std::move(value)),
+      "inplace_vector<T,N>::unchecked_emplace_back(Args...): Adding element when size() >= capacity()");
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
new file mode 100644
index 0000000000000..fefe61e1eef53
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers, std-at-least-c++26
+
+// <inplace_vector>
+
+#include <inplace_vector>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::inplace_vector<int, 0> c;
+
+  EXPECT_ANY_DEATH((void)c[0]);
+  EXPECT_ANY_DEATH((void)c.front());
+  EXPECT_ANY_DEATH((void)c.back());
+  EXPECT_ANY_DEATH(c.pop_back());
+  EXPECT_ANY_DEATH(c.erase(c.begin()));
+  EXPECT_ANY_DEATH((void)std::as_const(c)[0]);
+  EXPECT_ANY_DEATH((void)std::as_const(c).front());
+  EXPECT_ANY_DEATH((void)std::as_const(c).back());
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..4144f3be5d25c
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/nodiscard.verify.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+#include <inplace_vector>
+
+void test() {
+  std::inplace_vector<int, 4> v;
+
+  v.at(0);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.back();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.begin();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.capacity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.cbegin();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.cend();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.crbegin();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.crend();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.data();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.empty();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.end();      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.front();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.rbegin();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.rend();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.size();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v[0];         // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.try_emplace_back(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.try_push_back(1);    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  std::inplace_vector<int, 0> v0;
+  v0.begin();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.capacity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.cbegin();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.cend();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.crbegin();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.crend();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.data();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.empty();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.end();      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.rbegin();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.rend();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.size();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.try_emplace_back(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.try_push_back(1);    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  // Defined in lambdas because these are marked [[noreturn]], and would emit a 'code unreachable' warning if code followed any one of them.
+  (void)[&] {
+    v0.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  };
+
+  (void)[&] {
+    v0.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  };
+
+  (void)[&] {
+    v0.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  };
+
+  (void)[&] {
+    v0[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  };
+
+  // iterator [[nodiscard]]
+  {
+    std::inplace_vector<int, 4>::iterator it = v.begin();
+    *it;     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    it[0];   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    it + 1;  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    1 + it;  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    it - 1;  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    it - it; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  }
+
+  {
+    std::inplace_vector<int, 4>::const_iterator it = v.cbegin();
+    *it;     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    it[0];   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    it + 1;  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    1 + it;  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    it - 1;  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    it - it; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  }
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/access.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/access.pass.cpp
new file mode 100644
index 0000000000000..8d70255bad0bf
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/access.pass.cpp
@@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+//       reference operator[](size_type n);
+// const_reference operator[](size_type n) const;
+//       reference at(size_type n);
+// const_reference at(size_type n) const;
+//       reference front();
+// const_reference front() const;
+//       reference back();
+// const_reference back() const;
+
+#include <cassert>
+#include <inplace_vector>
+#include <stdexcept>
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <class C>
+constexpr C make(int size, int start) {
+  C c;
+  for (int i = 0; i != size; ++i)
+    c.push_back(start + i);
+  return c;
+}
+
+template <class C>
+constexpr void test_get_basic(C& c, int start_value) {
+  const int n = static_cast<int>(c.size());
+  for (int i = 0; i != n; ++i)
+    assert(c[i] == start_value + i);
+  for (int i = 0; i != n; ++i)
+    assert(c.at(i) == start_value + i);
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    try {
+      (void)c.at(n);
+      assert(false);
+    } catch (const std::out_of_range&) {
+    }
+  }
+#endif
+
+  assert(c.front() == start_value);
+  assert(c.back() == start_value + n - 1);
+}
+
+template <class C>
+constexpr void test_get() {
+  int start_value = 35;
+  C c             = make<C>(10, start_value);
+  const C& cc     = c;
+  test_get_basic(c, start_value);
+  test_get_basic(cc, start_value);
+}
+
+template <class C>
+constexpr void test_set() {
+  int start_value = 35;
+  const int n     = 10;
+  C c             = make<C>(n, start_value);
+
+  for (int i = 0; i != n; ++i) {
+    assert(c[i] == start_value + i);
+    c[i] = start_value + i + 1;
+    assert(c[i] == start_value + i + 1);
+  }
+  for (int i = 0; i != n; ++i) {
+    assert(c.at(i) == start_value + i + 1);
+    c.at(i) = start_value + i + 2;
+    assert(c.at(i) == start_value + i + 2);
+  }
+
+  assert(c.front() == start_value + 2);
+  c.front() = start_value + 3;
+  assert(c.front() == start_value + 3);
+
+  assert(c.back() == start_value + n + 1);
+  c.back() = start_value + n + 2;
+  assert(c.back() == start_value + n + 2);
+}
+
+template <class C>
+constexpr void test() {
+  test_get<C>();
+  test_set<C>();
+
+  C c;
+  const C& cc = c;
+  ASSERT_SAME_TYPE(typename C::reference, decltype(c[0]));
+  ASSERT_SAME_TYPE(typename C::const_reference, decltype(cc[0]));
+  ASSERT_SAME_TYPE(typename C::reference, decltype(c.at(0)));
+  ASSERT_SAME_TYPE(typename C::const_reference, decltype(cc.at(0)));
+  ASSERT_SAME_TYPE(typename C::reference, decltype(c.front()));
+  ASSERT_SAME_TYPE(typename C::const_reference, decltype(cc.front()));
+  ASSERT_SAME_TYPE(typename C::reference, decltype(c.back()));
+  ASSERT_SAME_TYPE(typename C::const_reference, decltype(cc.back()));
+}
+
+constexpr bool tests() {
+  test<std::inplace_vector<int, 16> >();
+  return true;
+}
+
+int main(int, char**) {
+  tests();
+  static_assert(tests());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/addressof.compile.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/addressof.compile.pass.cpp
new file mode 100644
index 0000000000000..94a722eea6d04
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/addressof.compile.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// Validate various member functions of std::inplace_vector with an ADL-hijacking operator&.
+
+#include <inplace_vector>
+#include <utility>
+
+#include "operator_hijacker.h"
+#include "test_iterators.h"
+
+using InplaceVector = std::inplace_vector<operator_hijacker, 16>;
+
+void test(
+    InplaceVector v,
+    InplaceVector::const_iterator it,
+    cpp17_input_iterator<operator_hijacker*> other_it,
+    operator_hijacker val) {
+  // emplace / insert
+  v.emplace(it);
+  v.insert(it, it, it);
+  v.insert(it, other_it, other_it);
+  v.insert(it, operator_hijacker());
+  v.insert(it, 1, val);
+  v.insert(it, val);
+
+  // erase
+  v.erase(it);
+  v.erase(it, it);
+
+  // assignment
+  v = static_cast<InplaceVector&>(v);
+  v = std::move(v);
+
+  // construction
+  {
+    InplaceVector v2(std::move(v));
+    (void)v2;
+  }
+
+  // swap
+  v.swap(v);
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/common.h b/libcxx/test/std/containers/sequences/inplace_vector/common.h
new file mode 100644
index 0000000000000..0b895580e19c1
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/common.h
@@ -0,0 +1,161 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_STD_CONTAINERS_SEQUENCES_INPLACE_VECTOR_COMMON_H
+#define TEST_STD_CONTAINERS_SEQUENCES_INPLACE_VECTOR_COMMON_H
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <inplace_vector>
+#include <initializer_list>
+#include <new>
+#include <ranges>
+#include <stdexcept>
+#include <utility>
+
+#include "test_macros.h"
+
+// inplace_vector<T,N> usage for non-trivial T in constant expressions is gated by
+// implementations of P3074R7 (trivial unions), inplace_vector<T, N>
+#ifdef __cpp_trivial_union
+#  define TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR 1
+#else
+#  define TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR 0
+#endif
+
+template <class T>
+using InplaceVector = std::inplace_vector<T, 32>;
+
+template <class T>
+using SmallInplaceVector = std::inplace_vector<T, 8>;
+
+template <class T, class Expected>
+constexpr void assert_inplace_vector_equal(const T& c, const Expected& expected) {
+  assert(c.size() == std::ranges::size(expected));
+  assert(std::ranges::equal(c, expected));
+}
+
+template <class C, class T>
+constexpr void assert_inplace_vector_equal(const C& c, std::initializer_list<T> expected) {
+  assert(c.size() == expected.size());
+  assert(std::ranges::equal(c, expected));
+}
+
+template <class T, std::size_t N>
+constexpr std::inplace_vector<T, N> make_inplace_vector(std::initializer_list<T> il) {
+  std::inplace_vector<T, N> result;
+  result.insert(result.end(), il.begin(), il.end());
+  return result;
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct ThrowingValue {
+  inline static int alive       = 0;
+  inline static int throw_after = -1;
+
+  int value = 0;
+
+  static void reset() {
+    alive       = 0;
+    throw_after = -1;
+  }
+
+  static void maybe_throw() {
+    if (throw_after == 0)
+      throw 1;
+    if (throw_after > 0)
+      --throw_after;
+  }
+
+  ThrowingValue() {
+    maybe_throw();
+    ++alive;
+  }
+
+  explicit ThrowingValue(int v) : value(v) {
+    maybe_throw();
+    ++alive;
+  }
+
+  ThrowingValue(const ThrowingValue& other) : value(other.value) {
+    maybe_throw();
+    ++alive;
+  }
+
+  ThrowingValue(ThrowingValue&& other) : value(other.value) {
+    maybe_throw();
+    ++alive;
+  }
+
+  ThrowingValue& operator=(const ThrowingValue& other) {
+    maybe_throw();
+    value = other.value;
+    return *this;
+  }
+
+  ThrowingValue& operator=(ThrowingValue&& other) {
+    maybe_throw();
+    value = other.value;
+    return *this;
+  }
+
+  ~ThrowingValue() { --alive; }
+
+  friend bool operator==(const ThrowingValue& lhs, const ThrowingValue& rhs) { return lhs.value == rhs.value; }
+};
+
+template <class T, class IterCat>
+struct throwing_iterator {
+  using iterator_category = IterCat;
+  using difference_type   = std::ptrdiff_t;
+  using value_type        = T;
+  using reference         = T&;
+  using pointer           = T*;
+
+  int i_;
+  T* ptr_;
+
+  throwing_iterator() : i_(0), ptr_(nullptr) {}
+
+  throwing_iterator(T* ptr, int i = 0) : i_(i), ptr_(ptr) {}
+
+  reference operator*() const {
+    if (i_ == 1)
+      throw 1;
+    return *ptr_;
+  }
+
+  friend bool operator==(const throwing_iterator& lhs, const throwing_iterator& rhs) { return lhs.i_ == rhs.i_; }
+  friend bool operator!=(const throwing_iterator& lhs, const throwing_iterator& rhs) { return !(lhs == rhs); }
+
+  throwing_iterator& operator++() {
+    ++i_;
+    ++ptr_;
+    return *this;
+  }
+
+  throwing_iterator operator++(int) {
+    auto tmp = *this;
+    ++*this;
+    return tmp;
+  }
+};
+
+template <class Func>
+void assert_throws_bad_alloc(Func func) {
+  try {
+    func();
+    assert(false);
+  } catch (const std::bad_alloc&) {
+  }
+}
+#endif
+
+#endif // TEST_STD_CONTAINERS_SEQUENCES_INPLACE_VECTOR_COMMON_H
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/compare.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/compare.pass.cpp
new file mode 100644
index 0000000000000..208b41d94bbe4
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/compare.pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class T, size_t N>
+//   constexpr bool operator==(const inplace_vector<T, N>& x, const inplace_vector<T, N>& y);
+
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+
+#include "common.h"
+#include "test_comparisons.h"
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 8> c1;
+    std::inplace_vector<int, 8> c2;
+    std::same_as<bool> decltype(auto) result = c1 == c2;
+    assert(result);
+    assert(!(c1 != c2));
+  }
+  {
+    std::inplace_vector<int, 8> c1{1, 2, 3};
+    std::inplace_vector<int, 8> c2{1, 2, 3};
+    std::inplace_vector<int, 8> c3{1, 2, 4};
+    std::inplace_vector<int, 8> c4{1, 2};
+    assert(c1 == c2);
+    assert(c1 != c3);
+    assert(c1 != c4);
+  }
+  { // all six comparison operators (!=, <, <=, >, >= are rewritten in terms of == and <=>)
+    std::inplace_vector<int, 8> c1;
+    std::inplace_vector<int, 8> c2;
+    assert(testComparisons(c1, c2, true, false));
+  }
+  {
+    std::inplace_vector<int, 8> c1{1, 2, 1};
+    std::inplace_vector<int, 8> c2{1, 2, 2};
+    assert(testComparisons(c1, c2, false, true));
+  }
+  {
+    std::inplace_vector<int, 8> c1{3, 2, 3};
+    std::inplace_vector<int, 8> c2{3, 1, 3};
+    assert(testComparisons(c1, c2, false, false));
+  }
+  { // a shorter inplace_vector that is a prefix of the longer one compares less
+    std::inplace_vector<int, 8> c1{1, 2};
+    std::inplace_vector<int, 8> c2{1, 2, 0};
+    assert(testComparisons(c1, c2, false, true));
+  }
+  {
+    std::inplace_vector<int, 8> c1{1, 2, 0};
+    std::inplace_vector<int, 8> c2{3};
+    assert(testComparisons(c1, c2, false, true));
+  }
+
+  // types that only provide operator< and operator==
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    {
+      std::inplace_vector<LessAndEqComp, 8> c1;
+      std::inplace_vector<LessAndEqComp, 8> c2;
+      assert(testComparisons(c1, c2, true, false));
+    }
+    {
+      std::inplace_vector<LessAndEqComp, 8> c1{LessAndEqComp(1), LessAndEqComp(2)};
+      std::inplace_vector<LessAndEqComp, 8> c2{LessAndEqComp(1), LessAndEqComp(2)};
+      assert(testComparisons(c1, c2, true, false));
+    }
+    {
+      std::inplace_vector<LessAndEqComp, 8> c1{LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(2)};
+      std::inplace_vector<LessAndEqComp, 8> c2{LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(1)};
+      assert(testComparisons(c1, c2, false, false));
+    }
+    {
+      std::inplace_vector<LessAndEqComp, 8> c1{LessAndEqComp(1), LessAndEqComp(2)};
+      std::inplace_vector<LessAndEqComp, 8> c2{LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(0)};
+      assert(testComparisons(c1, c2, false, true));
+    }
+  }
+
+  { // zero capacity inplace_vectors are always equal
+    std::inplace_vector<int, 0> c1;
+    std::inplace_vector<int, 0> c2;
+    assert(testComparisons(c1, c2, true, false));
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/compare.three_way.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/compare.three_way.pass.cpp
new file mode 100644
index 0000000000000..9661db1e44e05
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/compare.three_way.pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class T, size_t N>
+//   constexpr synth-three-way-result<T>
+//     operator<=>(const inplace_vector<T, N>& x, const inplace_vector<T, N>& y);
+
+#include <cassert>
+#include <compare>
+#include <concepts>
+#include <inplace_vector>
+#include <limits>
+#include <type_traits>
+
+#include "common.h"
+#include "test_comparisons.h"
+
+static_assert(std::three_way_comparable<std::inplace_vector<int, 8>>);
+static_assert(!std::three_way_comparable<std::inplace_vector<NonComparable, 8>>);
+
+template <class Elem, class Order>
+constexpr void test_with_type() {
+  {
+    std::inplace_vector<Elem, 8> c1;
+    std::inplace_vector<Elem, 8> c2;
+    std::same_as<Order> decltype(auto) result = c1 <=> c2;
+    assert(result == Order::equivalent);
+  }
+  {
+    std::inplace_vector<Elem, 8> c1{Elem(1), Elem(1)};
+    std::inplace_vector<Elem, 8> c2{Elem(1), Elem(1)};
+    assert(testOrder(c1, c2, Order::equivalent));
+  }
+  {
+    std::inplace_vector<Elem, 8> c1{Elem(1), Elem(1)};
+    std::inplace_vector<Elem, 8> c2{Elem(1), Elem(2)};
+    assert(testOrder(c1, c2, Order::less));
+  }
+  {
+    std::inplace_vector<Elem, 8> c1{Elem(1), Elem(3)};
+    std::inplace_vector<Elem, 8> c2{Elem(1), Elem(2)};
+    assert(testOrder(c1, c2, Order::greater));
+  }
+  {
+    std::inplace_vector<Elem, 8> c1{Elem(1)};
+    std::inplace_vector<Elem, 8> c2{Elem(1), Elem(2)};
+    assert(testOrder(c1, c2, Order::less));
+  }
+  {
+    std::inplace_vector<Elem, 8> c1{Elem(1), Elem(2)};
+    std::inplace_vector<Elem, 8> c2{Elem(1)};
+    assert(testOrder(c1, c2, Order::greater));
+  }
+
+  if constexpr (std::is_same_v<Elem, PartialOrder>) {
+    std::inplace_vector<Elem, 8> c1{Elem(1), Elem(std::numeric_limits<int>::min())};
+    std::inplace_vector<Elem, 8> c2{Elem(1), Elem(2)};
+    assert(testOrder(c1, c2, Order::unordered));
+  }
+}
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 8> c1{1, 2, 3};
+    std::inplace_vector<int, 8> c2{1, 2, 3};
+    std::inplace_vector<int, 8> c3{1, 2, 4};
+    std::inplace_vector<int, 8> c4{1, 2};
+
+    std::same_as<std::strong_ordering> decltype(auto) result = c1 <=> c2;
+    assert(result == std::strong_ordering::equal);
+    assert((c1 <=> c3) == std::strong_ordering::less);
+    assert((c3 <=> c1) == std::strong_ordering::greater);
+    assert((c4 <=> c1) == std::strong_ordering::less);
+    assert((c1 <=> c4) == std::strong_ordering::greater);
+  }
+
+  {
+    std::inplace_vector<int, 0> c1;
+    std::inplace_vector<int, 0> c2;
+    std::same_as<std::strong_ordering> decltype(auto) result = c1 <=> c2;
+    assert(result == std::strong_ordering::equal);
+  }
+
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    test_with_type<StrongOrder, std::strong_ordering>();
+    test_with_type<WeakOrder, std::weak_ordering>();
+    test_with_type<PartialOrder, std::partial_ordering>();
+    test_with_type<LessAndEqComp, std::weak_ordering>();
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/constant_initialization.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/constant_initialization.pass.cpp
new file mode 100644
index 0000000000000..36a30148e5920
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/constant_initialization.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "test_macros.h"
+
+TEST_CONSTINIT std::inplace_vector<int, 4> v1;
+TEST_CONSTINIT const std::inplace_vector<int, 4> v2;
+
+int main(int, char**) {
+  assert(v1.empty());
+  assert(v2.empty());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/contiguous.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/contiguous.pass.cpp
new file mode 100644
index 0000000000000..d748fbe1f86d5
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/contiguous.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+#include <cassert>
+#include <inplace_vector>
+#include <memory>
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 8> c{1, 2, 3};
+    assert(std::to_address(c.begin()) == c.data());
+    assert(std::to_address(c.begin() + 1) == c.data() + 1);
+    assert(std::to_address(c.end()) == c.data() + c.size());
+  }
+  {
+    const std::inplace_vector<int, 8> c{1, 2, 3};
+    assert(std::to_address(c.begin()) == c.data());
+    assert(std::to_address(c.begin() + 1) == c.data() + 1);
+    assert(std::to_address(c.end()) == c.data() + c.size());
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/capacity.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/capacity.pass.cpp
new file mode 100644
index 0000000000000..24f5732dd69a7
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/capacity.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// static constexpr size_type capacity() noexcept;
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    using C = std::inplace_vector<int, 0>;
+    ASSERT_SAME_TYPE(C::size_type, decltype(C::capacity()));
+    C c;
+    assert(c.capacity() == 0);
+    assert(C::capacity() == 0);
+  }
+  {
+    using C = std::inplace_vector<int, 42>;
+    ASSERT_SAME_TYPE(C::size_type, decltype(C::capacity()));
+    C c{1, 2, 3};
+    assert(c.capacity() == 42);
+    assert(C::capacity() == 42);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/empty.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/empty.pass.cpp
new file mode 100644
index 0000000000000..cbc7706965f36
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/empty.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr bool empty() const noexcept;
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 4> c;
+  ASSERT_SAME_TYPE(bool, decltype(c.empty()));
+  assert(c.empty());
+  c.push_back(1);
+  assert(!c.empty());
+  c.clear();
+  assert(c.empty());
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/max_size.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/max_size.pass.cpp
new file mode 100644
index 0000000000000..f756811b2e2aa
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/max_size.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// static constexpr size_type max_size() noexcept;
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    using C = std::inplace_vector<int, 0>;
+    ASSERT_SAME_TYPE(C::size_type, decltype(C::max_size()));
+    C c;
+    assert(c.max_size() == 0);
+    assert(C::max_size() == 0);
+  }
+  {
+    using C = std::inplace_vector<int, 42>;
+    ASSERT_SAME_TYPE(C::size_type, decltype(C::max_size()));
+    C c{1, 2, 3};
+    assert(c.max_size() == 42);
+    assert(C::max_size() == 42);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/reserve.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/reserve.pass.cpp
new file mode 100644
index 0000000000000..1aecd1e72e30b
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/reserve.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// static constexpr void reserve(size_type n);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  using C = std::inplace_vector<int, 4>;
+  C c{1, 2};
+  auto* data = c.data();
+  c.reserve(0);
+  c.reserve(4);
+  C::reserve(4);
+  assert(c.size() == 2);
+  assert(c.capacity() == 4);
+  assert(c.data() == data);
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  assert_throws_bad_alloc([] { std::inplace_vector<int, 4>::reserve(5); });
+  std::inplace_vector<int, 4> c{1, 2};
+  auto* data = c.data();
+  assert_throws_bad_alloc([&] { c.reserve(5); });
+  assert(c.size() == 2);
+  assert(c.data() == data);
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size.pass.cpp
new file mode 100644
index 0000000000000..379ad216afed3
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr void resize(size_type sz);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 5> c{1, 2, 3};
+  c.resize(5);
+  assert_inplace_vector_equal(c, {1, 2, 3, 0, 0});
+  c.resize(2);
+  assert_inplace_vector_equal(c, {1, 2});
+  c.resize(0);
+  assert(c.empty());
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 5> c{1, 2, 3};
+  assert_throws_bad_alloc([&] { c.resize(6); });
+  assert_inplace_vector_equal(c, {1, 2, 3});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_exceptions.pass.cpp
new file mode 100644
index 0000000000000..0102e003a87e2
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_exceptions.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// UNSUPPORTED: no-exceptions
+
+// <inplace_vector>
+
+// constexpr void resize(size_type sz);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+
+int main(int, char**) {
+  ThrowingValue::reset();
+  {
+    std::inplace_vector<ThrowingValue, 4> c;
+    c.emplace_back(1);
+    c.emplace_back(2);
+
+    ThrowingValue::throw_after = 1;
+    try {
+      c.resize(4);
+      assert(false);
+    } catch (int) {
+      assert(c.size() == 2);
+      assert(c[0].value == 1);
+      assert(c[1].value == 2);
+      assert(ThrowingValue::alive == 2);
+    }
+  }
+  assert(ThrowingValue::alive == 0);
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_value.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_value.pass.cpp
new file mode 100644
index 0000000000000..98b705a949a99
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_value.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr void resize(size_type sz, const T& c);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 5> c{1, 2, 3};
+  c.resize(5, 9);
+  assert_inplace_vector_equal(c, {1, 2, 3, 9, 9});
+  c.resize(2, 7);
+  assert_inplace_vector_equal(c, {1, 2});
+  c.resize(5, 8);
+  assert_inplace_vector_equal(c, {1, 2, 8, 8, 8});
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 5> c{1, 2, 3};
+  assert_throws_bad_alloc([&] { c.resize(6, 4); });
+  assert_inplace_vector_equal(c, {1, 2, 3});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_value_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_value_exceptions.pass.cpp
new file mode 100644
index 0000000000000..258bdd76f2188
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/resize_size_value_exceptions.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// UNSUPPORTED: no-exceptions
+
+// <inplace_vector>
+
+// constexpr void resize(size_type sz, const T& c);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+
+int main(int, char**) {
+  ThrowingValue::reset();
+  {
+    std::inplace_vector<ThrowingValue, 4> c;
+    c.emplace_back(1);
+    c.emplace_back(2);
+    ThrowingValue value(9);
+
+    ThrowingValue::throw_after = 1;
+    try {
+      c.resize(4, value);
+      assert(false);
+    } catch (int) {
+      assert(c.size() == 2);
+      assert(c[0].value == 1);
+      assert(c[1].value == 2);
+      assert(value.value == 9);
+      assert(ThrowingValue::alive == 3);
+    }
+  }
+  assert(ThrowingValue::alive == 0);
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/shrink_to_fit.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/shrink_to_fit.pass.cpp
new file mode 100644
index 0000000000000..88ae0db694ac5
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/shrink_to_fit.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// static constexpr void shrink_to_fit() noexcept;
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  using C = std::inplace_vector<int, 8>;
+  C c{1, 2, 3};
+  auto* data = c.data();
+  c.shrink_to_fit();
+  C::shrink_to_fit();
+  assert(c.size() == 3);
+  assert(c.capacity() == 8);
+  assert(c.data() == data);
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/size.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/size.pass.cpp
new file mode 100644
index 0000000000000..ddc3f4730cf40
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/size.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr size_type size() const noexcept;
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 4> c;
+  ASSERT_SAME_TYPE(std::inplace_vector<int, 4>::size_type, decltype(c.size()));
+  assert(c.size() == 0);
+  c.push_back(1);
+  assert(c.size() == 1);
+  c.push_back(2);
+  assert(c.size() == 2);
+  c.pop_back();
+  assert(c.size() == 1);
+  c.clear();
+  assert(c.size() == 0);
+
+  assert((std::inplace_vector<int, 0>().size() == 0));
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/swap.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/swap.pass.cpp
new file mode 100644
index 0000000000000..2b2cc6bc8fad7
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.capacity/swap.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr void swap(inplace_vector& x)
+//   noexcept(N == 0 || (is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<T>));
+
+#include <cassert>
+#include <inplace_vector>
+#include <utility>
+
+#include "../common.h"
+#include "test_macros.h"
+
+struct ThrowMove {
+  constexpr ThrowMove()                            = default;
+  constexpr ThrowMove(const ThrowMove&)            = default;
+  constexpr ThrowMove& operator=(const ThrowMove&) = default;
+  constexpr ThrowMove(ThrowMove&&) {}
+  constexpr ThrowMove& operator=(ThrowMove&&) = default;
+  constexpr ~ThrowMove()                      = default;
+};
+
+namespace MyNS {
+struct M {
+  M(M const&)            = delete;
+  M& operator=(M const&) = delete;
+};
+
+void swap(M&&, M&&) noexcept {}
+
+} // namespace MyNS
+
+constexpr bool test() {
+  std::inplace_vector<int, 8> c1{1, 2, 3};
+  std::inplace_vector<int, 8> c2{4, 5};
+  ASSERT_NOEXCEPT(c1.swap(c2));
+  c1.swap(c2);
+  assert(c1.capacity() == 8);
+  assert(c2.capacity() == 8);
+  assert_inplace_vector_equal(c1, {4, 5});
+  assert_inplace_vector_equal(c2, {1, 2, 3});
+
+  using namespace MyNS;
+  {
+    using C = std::inplace_vector<ThrowMove, 2>;
+    ASSERT_NOT_NOEXCEPT(std::declval<C&>().swap(std::declval<C&>()));
+  }
+
+  {
+    using C = std::inplace_vector<ThrowMove, 0>;
+    ASSERT_NOEXCEPT(std::declval<C&>().swap(std::declval<C&>()));
+  }
+
+  {
+    using C = std::inplace_vector<M, 4>;
+    ASSERT_NOT_NOEXCEPT(std::declval<C&>().swap(std::declval<C&>()));
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_copy.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_copy.pass.cpp
new file mode 100644
index 0000000000000..3710c383a6705
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_copy.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr inplace_vector& operator=(const inplace_vector& other);
+
+#include <cassert>
+#include <inplace_vector>
+#include <utility>
+
+#include "../common.h"
+#include "test_macros.h"
+
+struct ThrowCopyAssign {
+  ThrowCopyAssign(const ThrowCopyAssign&) = default;
+  ThrowCopyAssign& operator=(const ThrowCopyAssign&) { return *this; }
+};
+
+struct ThrowCopyCtor {
+  ThrowCopyCtor(const ThrowCopyCtor&) {}
+  ThrowCopyCtor& operator=(const ThrowCopyCtor&) = default;
+};
+
+constexpr bool test() {
+  {
+    using C = std::inplace_vector<int, 8>;
+    C c{1, 2, 3};
+    C other{4, 5};
+    ASSERT_SAME_TYPE(C&, decltype(c = other));
+    C& result = (c = other);
+    assert(&result == &c);
+    assert_inplace_vector_equal(c, {4, 5});
+    assert_inplace_vector_equal(other, {4, 5});
+
+    C& self = c;
+    c       = self;
+    assert_inplace_vector_equal(c, {4, 5});
+  }
+
+  {
+    using C = std::inplace_vector<ThrowCopyAssign, 4>;
+    ASSERT_NOT_NOEXCEPT(std::declval<C>() = std::declval<const C&>());
+  }
+
+  {
+    using C = std::inplace_vector<ThrowCopyCtor, 4>;
+    ASSERT_NOT_NOEXCEPT(std::declval<C>() = std::declval<const C&>());
+  }
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_initializer_list.pass.cpp
new file mode 100644
index 0000000000000..a30368f0dbf0e
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_initializer_list.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr void assign(initializer_list<T>);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 8> c{1, 2, 3};
+  c.assign({4, 5});
+  assert_inplace_vector_equal(c, {4, 5});
+  c.assign({});
+  assert(c.empty());
+  c.assign({6, 7, 8, 9});
+  assert_inplace_vector_equal(c, {6, 7, 8, 9});
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 3> c{1, 2};
+  assert_throws_bad_alloc([&] { c.assign({1, 2, 3, 4}); });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_iter_iter.pass.cpp
new file mode 100644
index 0000000000000..54d228173c143
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_iter_iter.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class InputIterator>
+//   constexpr void assign(InputIterator first, InputIterator last);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+template <class Iter>
+constexpr void test_iterators() {
+  int a[] = {1, 2, 3, 4};
+  std::inplace_vector<int, 8> c{9, 8, 7};
+  c.assign(Iter(a), Iter(a + 4));
+  assert_inplace_vector_equal(c, a);
+
+  int b[] = {5};
+  c.assign(Iter(b), Iter(b + 1));
+  assert_inplace_vector_equal(c, b);
+
+  c.assign(Iter(b), Iter(b));
+  assert(c.empty());
+}
+
+constexpr bool test() {
+  test_iterators<cpp17_input_iterator<int*> >();
+  test_iterators<forward_iterator<int*> >();
+  test_iterators<int*>();
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  int a[] = {1, 2, 3, 4, 5};
+  std::inplace_vector<int, 4> c{9, 8};
+  assert_throws_bad_alloc([&] { c.assign(a, a + 5); });
+  assert_inplace_vector_equal(c, {9, 8});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_move.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_move.pass.cpp
new file mode 100644
index 0000000000000..64d720ed68aa0
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_move.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr inplace_vector& operator=(inplace_vector&& other)
+//   noexcept(N == 0 || (is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>));
+
+#include <cassert>
+#include <inplace_vector>
+#include <type_traits>
+#include <utility>
+
+#include "../common.h"
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+struct ThrowingMoveAssign {
+  ThrowingMoveAssign() = default;
+  ThrowingMoveAssign(ThrowingMoveAssign&&) noexcept(false) {}
+  ThrowingMoveAssign& operator=(ThrowingMoveAssign&&) noexcept(false) { return *this; }
+};
+
+struct ThrowingMoveCtorOnly {
+  ThrowingMoveCtorOnly() = default;
+  ThrowingMoveCtorOnly(ThrowingMoveCtorOnly&&) noexcept(false) {}
+  ThrowingMoveCtorOnly& operator=(ThrowingMoveCtorOnly&&) noexcept { return *this; }
+};
+
+struct ThrowingMoveAssignOnly {
+  ThrowingMoveAssignOnly() = default;
+  ThrowingMoveAssignOnly(ThrowingMoveAssignOnly&&) noexcept = default;
+  ThrowingMoveAssignOnly& operator=(ThrowingMoveAssignOnly&&) noexcept(false) { return *this; }
+};
+
+constexpr bool test() {
+  {
+    using C = std::inplace_vector<int, 8>;
+    C c{1, 2, 3};
+    C other{4, 5};
+    ASSERT_SAME_TYPE(C&, decltype(c = std::move(other)));
+    C& result = (c = std::move(other));
+    assert(&result == &c);
+    assert_inplace_vector_equal(c, {4, 5});
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    using C = std::inplace_vector<MoveOnly, 8>;
+    C c;
+    c.emplace_back(1);
+    C other;
+    other.emplace_back(4);
+    other.emplace_back(5);
+    c = std::move(other);
+    assert(c.size() == 2);
+    assert(c[0].get() == 4);
+    assert(c[1].get() == 5);
+  }
+
+  { // self-move-assignment leaves the container in a valid state
+    std::inplace_vector<int, 8> c{1, 2, 3};
+    std::inplace_vector<int, 8>& ref = c;
+    c = std::move(ref);
+    LIBCPP_ASSERT(c == (std::inplace_vector<int, 8>{1, 2, 3}));
+  }
+
+  { // noexcept(N == 0 || (is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>))
+    ASSERT_NOEXCEPT(std::declval<std::inplace_vector<int, 8>&>() = std::declval<std::inplace_vector<int, 8>&&>());
+    ASSERT_NOEXCEPT(std::declval<std::inplace_vector<ThrowingMoveAssign, 0>&>() =
+                        std::declval<std::inplace_vector<ThrowingMoveAssign, 0>&&>());
+    ASSERT_NOT_NOEXCEPT(std::declval<std::inplace_vector<ThrowingMoveAssign, 8>&>() =
+                            std::declval<std::inplace_vector<ThrowingMoveAssign, 8>&&>());
+
+    // both the move constructor and the move assignment of T must be noexcept
+    static_assert(!std::is_nothrow_move_assignable_v<std::inplace_vector<ThrowingMoveCtorOnly, 8>>);
+    static_assert(!std::is_nothrow_move_assignable_v<std::inplace_vector<ThrowingMoveAssignOnly, 8>>);
+    static_assert(std::is_nothrow_move_assignable_v<std::inplace_vector<ThrowingMoveCtorOnly, 0>>);
+    static_assert(std::is_nothrow_move_assignable_v<std::inplace_vector<ThrowingMoveAssignOnly, 0>>);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_size_value.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_size_value.pass.cpp
new file mode 100644
index 0000000000000..6d68c134260f6
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_size_value.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr void assign(size_type n, const T& u);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 8> c{1, 2, 3};
+  c.assign(4, 7);
+  assert_inplace_vector_equal(c, {7, 7, 7, 7});
+  c.assign(1, 8);
+  assert_inplace_vector_equal(c, {8});
+  c.assign(0, 9);
+  assert(c.empty());
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 3> c{1, 2};
+  assert_throws_bad_alloc([&] { c.assign(4, 7); });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_default.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_default.pass.cpp
new file mode 100644
index 0000000000000..0f0d460c22e60
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_default.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr inplace_vector() noexcept;
+
+#include <cassert>
+#include <inplace_vector>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "../../../NotConstructible.h"
+#include "../common.h"
+
+struct ThrowDefault {
+  constexpr ThrowDefault() {}
+};
+
+struct NoDefault {
+  NoDefault() = delete;
+};
+
+template <class C>
+constexpr void test() {
+  ASSERT_NOEXCEPT(C{});
+  C c;
+  assert(c.empty());
+  assert(c.size() == 0);
+  assert(c.capacity() == C::capacity());
+
+  C c1 = {};
+  assert(c1.empty());
+}
+
+constexpr bool tests() {
+  test<std::inplace_vector<int, 0> >();
+  test<std::inplace_vector<int, 8> >();
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    test<std::inplace_vector<NotConstructible, 8> >();
+  }
+
+  {
+    ASSERT_NOEXCEPT(std::inplace_vector<int, 0>());
+    ASSERT_NOEXCEPT(std::inplace_vector<int, 8>());
+    ASSERT_NOEXCEPT(std::inplace_vector<ThrowDefault, 1>());
+    ASSERT_NOEXCEPT(std::inplace_vector<ThrowDefault, 0>());
+    static_assert(std::is_nothrow_default_constructible_v<std::inplace_vector<NoDefault, 8>>);
+    static_assert(std::is_nothrow_default_constructible_v<std::inplace_vector<NoDefault, 0>>);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  tests();
+  static_assert(tests());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_from_range.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_from_range.pass.cpp
new file mode 100644
index 0000000000000..fa0cf3f2eae2c
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_from_range.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<container-compatible-range<T> R>
+//   constexpr inplace_vector(from_range_t, R&& rg);
+
+#include <cassert>
+#include <inplace_vector>
+#include <ranges>
+
+#include "../common.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    int a[] = {1, 2, 3, 4};
+    std::inplace_vector<int, 8> c(std::from_range, a);
+    assert_inplace_vector_equal(c, a);
+  }
+  {
+    using Iter = cpp20_input_iterator<int*>;
+    int a[]    = {1, 2, 3, 4};
+    auto r     = std::views::counted(Iter(a), 4);
+    std::inplace_vector<int, 8> c(std::from_range, r);
+    assert_inplace_vector_equal(c, a);
+  }
+  {
+    int a[] = {1, 2, 3, 4};
+    auto r  = std::ranges::subrange(a, a + 4);
+    std::inplace_vector<int, 4> c(std::from_range, r);
+    assert_inplace_vector_equal(c, a);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_iter_iter.pass.cpp
new file mode 100644
index 0000000000000..7d27e06e9bcef
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_iter_iter.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class InputIterator>
+//   constexpr inplace_vector(InputIterator first, InputIterator last);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+template <class Iter>
+constexpr void test_iterators() {
+  int a[] = {1, 2, 3, 4};
+  std::inplace_vector<int, 8> c(Iter(a), Iter(a + 4));
+  assert_inplace_vector_equal(c, a);
+}
+
+constexpr bool test() {
+  test_iterators<cpp17_input_iterator<int*> >();
+  test_iterators<forward_iterator<int*> >();
+  test_iterators<int*>();
+
+  {
+    int a[] = {1, 2, 3, 4};
+    std::inplace_vector<int, 4> c(a, a + 4);
+    assert_inplace_vector_equal(c, a);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  int a[] = {1, 2, 3, 4, 5};
+  assert_throws_bad_alloc([&] { std::inplace_vector<int, 4> c(a, a + 5); });
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_size.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_size.pass.cpp
new file mode 100644
index 0000000000000..ff4aba7ca76e3
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_size.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr explicit inplace_vector(size_type n);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 5> c(0);
+    assert(c.empty());
+  }
+  {
+    std::inplace_vector<int, 5> c(3);
+    assert_inplace_vector_equal(c, {0, 0, 0});
+  }
+  {
+    std::inplace_vector<int, 5> c(5);
+    assert_inplace_vector_equal(c, {0, 0, 0, 0, 0});
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  assert_throws_bad_alloc([] { std::inplace_vector<int, 5> c(6); });
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_size_value.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_size_value.pass.cpp
new file mode 100644
index 0000000000000..8eaac0b9136b2
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/construct_size_value.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr inplace_vector(size_type n, const T& value);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 5> c(0, 7);
+    assert(c.empty());
+  }
+  {
+    std::inplace_vector<int, 5> c(3, 7);
+    assert_inplace_vector_equal(c, {7, 7, 7});
+  }
+  {
+    std::inplace_vector<int, 5> c(5, 7);
+    assert_inplace_vector_equal(c, {7, 7, 7, 7, 7});
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  assert_throws_bad_alloc([] { std::inplace_vector<int, 5> c(6, 7); });
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/copy.move_only.verify.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/copy.move_only.verify.cpp
new file mode 100644
index 0000000000000..33076f5a1c00f
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/copy.move_only.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr inplace_vector(const inplace_vector&);
+//
+// Make sure that a std::inplace_vector containing move-only types can't be copied.
+
+#include <inplace_vector>
+
+#include "MoveOnly.h"
+
+void f() {
+  std::inplace_vector<MoveOnly, 4> v;
+  std::inplace_vector<MoveOnly, 4> copy =
+      v; // expected-error-re@* {{{{(no matching function for call to '__construct_at')|(call to deleted constructor of 'MoveOnly')}}}}
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/copy.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/copy.pass.cpp
new file mode 100644
index 0000000000000..89efc70dc65d8
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/copy.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr inplace_vector(const inplace_vector&);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 8> c;
+    std::inplace_vector<int, 8> copy(c);
+    assert(copy.empty());
+  }
+  {
+    std::inplace_vector<int, 8> c{1, 2, 3};
+    std::inplace_vector<int, 8> copy(c);
+    assert_inplace_vector_equal(copy, {1, 2, 3});
+    assert_inplace_vector_equal(c, {1, 2, 3});
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/exceptions.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/exceptions.pass.cpp
new file mode 100644
index 0000000000000..b82629f84ab3d
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/exceptions.pass.cpp
@@ -0,0 +1,128 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// UNSUPPORTED: no-exceptions
+
+// <inplace_vector>
+
+// constexpr explicit inplace_vector(size_type n);
+// constexpr inplace_vector(size_type n, const T& value);
+// template<class InputIterator>
+//   constexpr inplace_vector(InputIterator first, InputIterator last);
+// constexpr inplace_vector(const inplace_vector&);
+// constexpr inplace_vector(initializer_list<T> il);
+
+#include <inplace_vector>
+
+#include "../common.h"
+
+void test_over_capacity_exceptions() {
+  assert_throws_bad_alloc([] { std::inplace_vector<int, 2> c(3); });
+  assert_throws_bad_alloc([] { std::inplace_vector<int, 2> c(3, 1); });
+  assert_throws_bad_alloc([] { std::inplace_vector<int, 2> c{1, 2, 3}; });
+
+  int a[] = {1, 2, 3};
+  assert_throws_bad_alloc([&] { std::inplace_vector<int, 2> c(a, a + 3); });
+}
+
+void test_element_constructor_exceptions() {
+  ThrowingValue::reset();
+  ThrowingValue::throw_after = 0;
+  try {
+    std::inplace_vector<ThrowingValue, 4> c(1);
+    assert(false);
+  } catch (int) {
+    assert(ThrowingValue::alive == 0);
+  }
+
+  ThrowingValue::reset();
+  {
+    ThrowingValue value(1);
+    ThrowingValue::throw_after = 0;
+    try {
+      std::inplace_vector<ThrowingValue, 4> c(1, value);
+      assert(false);
+    } catch (int) {
+      assert(ThrowingValue::alive == 1);
+    }
+  }
+  assert(ThrowingValue::alive == 0);
+}
+
+void test_iterator_constructor_exceptions() {
+  ThrowingValue::reset();
+  {
+    ThrowingValue values[] = {ThrowingValue(1), ThrowingValue(2)};
+    try {
+      std::inplace_vector<ThrowingValue, 4> c(
+          throwing_iterator<ThrowingValue, std::input_iterator_tag>(values),
+          throwing_iterator<ThrowingValue, std::input_iterator_tag>(values + 2, 2));
+      assert(false);
+    } catch (int) {
+      assert(ThrowingValue::alive == 2);
+    }
+  }
+  assert(ThrowingValue::alive == 0);
+
+  ThrowingValue::reset();
+  {
+    ThrowingValue values[] = {ThrowingValue(1), ThrowingValue(2)};
+    try {
+      std::inplace_vector<ThrowingValue, 4> c(
+          throwing_iterator<ThrowingValue, std::forward_iterator_tag>(values),
+          throwing_iterator<ThrowingValue, std::forward_iterator_tag>(values + 2, 2));
+      assert(false);
+    } catch (int) {
+      assert(ThrowingValue::alive == 2);
+    }
+  }
+  assert(ThrowingValue::alive == 0);
+}
+
+void test_copy_constructor_exceptions() {
+  ThrowingValue::reset();
+  {
+    std::inplace_vector<ThrowingValue, 4> source;
+    source.emplace_back(1);
+    source.emplace_back(2);
+
+    ThrowingValue::throw_after = 1;
+    try {
+      std::inplace_vector<ThrowingValue, 4> copy(source);
+      assert(false);
+    } catch (int) {
+      assert(source.size() == 2);
+      assert(source[0].value == 1);
+      assert(source[1].value == 2);
+      assert(ThrowingValue::alive == 2);
+    }
+  }
+  assert(ThrowingValue::alive == 0);
+}
+
+void test_initializer_list_constructor_exceptions() {
+  ThrowingValue::reset();
+  try {
+    ThrowingValue::throw_after = 3;
+    std::inplace_vector<ThrowingValue, 4> c{ThrowingValue(1), ThrowingValue(2)};
+    assert(false);
+  } catch (int) {
+    assert(ThrowingValue::alive == 0);
+  }
+}
+
+int main(int, char**) {
+  test_over_capacity_exceptions();
+  test_element_constructor_exceptions();
+  test_iterator_constructor_exceptions();
+  test_copy_constructor_exceptions();
+  test_initializer_list_constructor_exceptions();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/initializer_list.pass.cpp
new file mode 100644
index 0000000000000..f808778a733be
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/initializer_list.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr inplace_vector(initializer_list<T> il);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 8> c{1, 2, 3};
+  assert_inplace_vector_equal(c, {1, 2, 3});
+
+  std::inplace_vector<int, 0> empty{};
+  assert(empty.empty());
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  assert_throws_bad_alloc([] { std::inplace_vector<int, 2> c{1, 2, 3}; });
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/move.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/move.pass.cpp
new file mode 100644
index 0000000000000..64ca64f80fa0e
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/move.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr inplace_vector(inplace_vector&&)
+//   noexcept(N == 0 || is_nothrow_move_constructible_v<T>);
+
+#include <cassert>
+#include <inplace_vector>
+#include <type_traits>
+#include <utility>
+
+#include "../common.h"
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+struct ThrowingMove {
+  ThrowingMove() = default;
+  ThrowingMove(ThrowingMove&&) noexcept(false) {}
+};
+
+struct ThrowingCopyNothrowMove {
+  ThrowingCopyNothrowMove() = default;
+  ThrowingCopyNothrowMove(const ThrowingCopyNothrowMove&) noexcept(false) {}
+  ThrowingCopyNothrowMove(ThrowingCopyNothrowMove&&) noexcept {}
+};
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 8> c{1, 2, 3};
+    std::inplace_vector<int, 8> moved(std::move(c));
+    assert_inplace_vector_equal(moved, {1, 2, 3});
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    std::inplace_vector<MoveOnly, 8> c;
+    c.emplace_back(1);
+    c.emplace_back(2);
+    std::inplace_vector<MoveOnly, 8> moved(std::move(c));
+    assert(moved.size() == 2);
+    assert(moved[0].get() == 1);
+    assert(moved[1].get() == 2);
+  }
+
+  { // noexcept(N == 0 || is_nothrow_move_constructible_v<T>)
+    ASSERT_NOEXCEPT(std::inplace_vector<int, 8>(std::inplace_vector<int, 8>()));
+    ASSERT_NOEXCEPT(std::inplace_vector<ThrowingMove, 0>(std::inplace_vector<ThrowingMove, 0>()));
+    ASSERT_NOT_NOEXCEPT(std::inplace_vector<ThrowingMove, 8>(std::move(std::inplace_vector<ThrowingMove, 8>())));
+    static_assert(std::is_nothrow_move_constructible_v<std::inplace_vector<ThrowingCopyNothrowMove, 8>>);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/op_equal_initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/op_equal_initializer_list.pass.cpp
new file mode 100644
index 0000000000000..7e56944a81f67
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/op_equal_initializer_list.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr inplace_vector& operator=(initializer_list<T>);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  using C = std::inplace_vector<int, 8>;
+  C c{1, 2, 3};
+  ASSERT_SAME_TYPE(C&, decltype(c = {4, 5}));
+  C& result = (c = {4, 5});
+  assert(&result == &c);
+  assert_inplace_vector_equal(c, {4, 5});
+  c = {};
+  assert(c.empty());
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 3> c{1, 2};
+  assert_throws_bad_alloc([&] { c = {1, 2, 3, 4}; });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.data/data.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.data/data.pass.cpp
new file mode 100644
index 0000000000000..e84899b29d91c
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.data/data.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr T* data() noexcept;
+// constexpr const T* data() const noexcept;
+
+#include <cassert>
+#include <inplace_vector>
+#include <utility>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 4> c{1, 2, 3};
+  ASSERT_SAME_TYPE(decltype(c.data()), int*);
+  ASSERT_SAME_TYPE(decltype(std::as_const(c).data()), const int*);
+
+  assert(c.data() == &c.front());
+  assert(std::as_const(c).data() == &c.front());
+  assert(std::as_const(c).data() == &std::as_const(c).front());
+
+  c.data()[1] = 5;
+  assert(c[1] == 5);
+  assert(std::as_const(c)[1] == 5);
+  c.push_back(6);
+  assert(c.data()[3] == 6);
+  assert(std::as_const(c).data()[3] == 6);
+
+  std::inplace_vector<int, 0> empty;
+  assert(empty.data() == empty.data());
+  assert(std::as_const(empty).data() == std::as_const(empty).data());
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.data/data_const.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.data/data_const.pass.cpp
new file mode 100644
index 0000000000000..7f6a69f737a1d
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.data/data_const.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr T* inplace_vector<T,N>::data() const noexcept;
+// constexpr T* inplace_vector<T,0>::data() const noexcept;
+
+#include <cassert>
+#include <inplace_vector>
+#include <memory>
+
+#include "../common.h"
+#include "test_macros.h"
+
+struct Nasty {
+  constexpr Nasty() : i_(0) {}
+  constexpr Nasty(int i) : i_(i) {}
+  constexpr ~Nasty() {}
+  Nasty* operator&() const {
+    assert(false);
+    return nullptr;
+  }
+  int i_;
+};
+
+constexpr bool tests() {
+  {
+    const std::inplace_vector<int, 4> v;
+    ASSERT_SAME_TYPE(decltype(v.data()), const int*);
+    ASSERT_NOEXCEPT(v.data());
+    assert(v.data() == v.data());
+  }
+  {
+    const std::inplace_vector<int, 100> v(100);
+    assert(v.data() == std::addressof(v.front()));
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    const std::inplace_vector<Nasty, 100> v(100);
+    assert(v.data() == std::addressof(v.front()));
+  }
+  {
+    const std::inplace_vector<int, 0> v;
+    assert(v.data() == v.data());
+    assert(v.data() == nullptr);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  tests();
+  static_assert(tests());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase.pass.cpp
new file mode 100644
index 0000000000000..323626556bba9
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class T, size_t N, class U>
+//   constexpr typename inplace_vector<T, N>::size_type
+//     erase(inplace_vector<T, N>& c, const U& value);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 8> c{1, 2, 3, 2, 4, 2};
+  ASSERT_SAME_TYPE(std::inplace_vector<int, 8>::size_type, decltype(std::erase(c, 2)));
+  auto erased = std::erase(c, 2);
+  assert(erased == 3);
+  assert_inplace_vector_equal(c, {1, 3, 4});
+
+  erased = std::erase(c, 9);
+  assert(erased == 0);
+  assert_inplace_vector_equal(c, {1, 3, 4});
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase_if.pass.cpp
new file mode 100644
index 0000000000000..84d7ab0a3d401
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase_if.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class T, size_t N, class Predicate>
+//   constexpr typename inplace_vector<T, N>::size_type
+//     erase_if(inplace_vector<T, N>& c, Predicate pred);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 8> c{1, 2, 3, 4, 5, 6};
+  ASSERT_SAME_TYPE(std::inplace_vector<int, 8>::size_type, decltype(std::erase_if(c, [](int v) { return v % 2 == 0; })));
+  auto erased = std::erase_if(c, [](int v) { return v % 2 == 0; });
+  assert(erased == 3);
+  assert_inplace_vector_equal(c, {1, 3, 5});
+
+  erased = std::erase_if(c, [](int v) { return v > 10; });
+  assert(erased == 0);
+  assert_inplace_vector_equal(c, {1, 3, 5});
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/append_range.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/append_range.pass.cpp
new file mode 100644
index 0000000000000..b3b5cd455bd40
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/append_range.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000
+
+// <inplace_vector>
+
+// template<container-compatible-range<T> R>
+//   constexpr void append_range(R&& rg);
+
+#include <array>
+#include <cassert>
+#include <inplace_vector>
+
+#include "../../insert_range_sequence_containers.h"
+#include "../common.h"
+#include "test_macros.h"
+
+template <class Iter, class Sent>
+constexpr void test_iterators() {
+  test_sequence_append_range<InplaceVector<int>, Iter, Sent>([]([[maybe_unused]] auto&& c) {});
+}
+
+constexpr bool test() {
+  static_assert(test_constraints_append_range<InplaceVector, int, double>());
+
+  test_iterators<cpp20_input_iterator<const int*>, sentinel_wrapper<cpp20_input_iterator<const int*> > >();
+  test_iterators<forward_iterator<const int*>, sentinel_wrapper<forward_iterator<const int*> > >();
+  test_iterators<const int*, const int*>();
+
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    test_sequence_append_range_move_only<InplaceVector>();
+    test_sequence_append_range_emplace_constructible_and_move_insertable<InplaceVector>();
+  }
+
+  {
+    int in[] = {-1, -2, -3};
+    std::inplace_vector<int, 8> c{1, 2, 3};
+    auto* ptr = c.data();
+    c.append_range(in);
+    assert(c.data() == ptr);
+    assert_inplace_vector_equal(c, {1, 2, 3, -1, -2, -3});
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  test_append_range_exception_safety_throwing_copy<InplaceVector>();
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  int in[] = {3, 4};
+  std::inplace_vector<int, 3> c{1, 2};
+  assert_throws_bad_alloc([&] { c.append_range(in); });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/assign_range.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/assign_range.pass.cpp
new file mode 100644
index 0000000000000..ca76fb1bc7df3
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/assign_range.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000
+
+// <inplace_vector>
+
+// template<container-compatible-range<T> R>
+//   constexpr void assign_range(R&& rg);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../../insert_range_sequence_containers.h"
+#include "../common.h"
+#include "test_macros.h"
+
+template <class Iter, class Sent>
+constexpr void test_iterators() {
+  test_sequence_assign_range<InplaceVector<int>, Iter, Sent>([]([[maybe_unused]] auto&& c) {});
+}
+
+constexpr bool test() {
+  static_assert(test_constraints_assign_range<InplaceVector, int, double>());
+
+  test_iterators<cpp20_input_iterator<const int*>, sentinel_wrapper<cpp20_input_iterator<const int*> > >();
+  test_iterators<forward_iterator<const int*>, sentinel_wrapper<forward_iterator<const int*> > >();
+  test_iterators<const int*, const int*>();
+
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    test_sequence_assign_range_move_only<InplaceVector>();
+  }
+
+  {
+    int in[] = {-1, -2, -3};
+    std::inplace_vector<int, 8> c{1, 2, 3, 4, 5};
+    c.assign_range(in);
+    assert_inplace_vector_equal(c, in);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  test_assign_range_exception_safety_throwing_copy<InplaceVector>();
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  int in[] = {1, 2, 3, 4};
+  std::inplace_vector<int, 3> c{8, 9};
+  assert_throws_bad_alloc([&] { c.assign_range(in); });
+  assert_inplace_vector_equal(c, {8, 9});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/clear.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/clear.pass.cpp
new file mode 100644
index 0000000000000..175b471fd8e4e
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/clear.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr void clear() noexcept;
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 4> c{1, 2, 3};
+  ASSERT_NOEXCEPT(c.clear());
+  ASSERT_SAME_TYPE(decltype(c.clear()), void);
+  c.clear();
+  assert(c.empty());
+  assert(c.capacity() == 4);
+  c.clear();
+  assert(c.empty());
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/destroy_elements.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/destroy_elements.pass.cpp
new file mode 100644
index 0000000000000..d4ab65621ec49
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/destroy_elements.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr void pop_back();
+// constexpr iterator iterator erase(const_iterator position);
+// constexpr void clear() noexcept;
+// constexpr ~inplace_vector();
+
+#include <cassert>
+#include <inplace_vector>
+#include <type_traits>
+
+#include "../common.h"
+#include "test_macros.h"
+
+struct Tracker {
+  int* alive_;
+
+  constexpr explicit Tracker(int& alive) : alive_(&alive) { ++*alive_; }
+  constexpr Tracker(const Tracker& other) : alive_(other.alive_) { ++*alive_; }
+  constexpr Tracker& operator=(const Tracker&) = default;
+  constexpr ~Tracker() { --*alive_; }
+};
+
+struct NonTrivialDtor {
+  ~NonTrivialDtor() {}
+};
+
+static_assert(std::is_nothrow_destructible_v<std::inplace_vector<int, 0> >);
+static_assert(std::is_nothrow_destructible_v<std::inplace_vector<int, 8> >);
+static_assert(std::is_nothrow_destructible_v<std::inplace_vector<NonTrivialDtor, 0> >);
+static_assert(std::is_nothrow_destructible_v<std::inplace_vector<NonTrivialDtor, 8> >);
+
+constexpr bool test() {
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    int alive = 0;
+    {
+      std::inplace_vector<Tracker, 8> c;
+      c.emplace_back(alive);
+      c.emplace_back(alive);
+      c.emplace_back(alive);
+      assert(alive == 3);
+
+      c.pop_back();
+      assert(alive == 2);
+
+      c.erase(c.begin());
+      assert(alive == 1);
+
+      c.clear();
+      assert(alive == 0);
+    }
+    assert(alive == 0);
+  }
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/emplace.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/emplace.pass.cpp
new file mode 100644
index 0000000000000..7de27c47142eb
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/emplace.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class... Args>
+//   constexpr iterator emplace(const_iterator position, Args&&... args);
+
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+struct A {
+  int i;
+  int j;
+
+  constexpr A(int ii, int jj) : i(ii), j(jj) {}
+};
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 5> c{1, 2, 4};
+    std::same_as<std::inplace_vector<int, 5>::iterator> decltype(auto) i = c.emplace(c.begin() + 2, 3);
+    assert(i == c.begin() + 2);
+    assert_inplace_vector_equal(c, {1, 2, 3, 4});
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    std::inplace_vector<A, 5> c;
+    c.emplace_back(1, 2);
+    auto i = c.emplace(c.begin(), 3, 4);
+    assert(i == c.begin());
+    assert(c[0].i == 3);
+    assert(c[0].j == 4);
+    assert(c[1].i == 1);
+    assert(c[1].j == 2);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 2> c{1, 2};
+  assert_throws_bad_alloc([&] { c.emplace(c.begin(), 3); });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/emplace_back.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/emplace_back.pass.cpp
new file mode 100644
index 0000000000000..11dc1688dd4c8
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/emplace_back.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class... Args>
+//   constexpr reference emplace_back(Args&&... args);
+
+#include <cassert>
+#include <inplace_vector>
+#include <tuple>
+
+#include "../common.h"
+#include "test_macros.h"
+
+struct A {
+  int i;
+  int j;
+
+  constexpr A(int ii, int jj) : i(ii), j(jj) {}
+};
+
+constexpr bool test() {
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    std::inplace_vector<A, 3> c;
+    ASSERT_SAME_TYPE(A&, decltype(c.emplace_back(1, 2)));
+    A& r = c.emplace_back(1, 2);
+    assert(&r == &c.back());
+    assert(c.back().i == 1);
+    assert(c.back().j == 2);
+
+    c.emplace_back(3, 4);
+    assert(c.size() == 2);
+    assert(c[1].i == 3);
+    assert(c[1].j == 4);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 2> c{1, 2};
+  assert_throws_bad_alloc([&] { c.emplace_back(3); });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/erase_iter.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/erase_iter.pass.cpp
new file mode 100644
index 0000000000000..d011fc7013ea0
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/erase_iter.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr iterator erase(const_iterator position);
+
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 5> c{1, 2, 3, 4};
+    std::same_as<std::inplace_vector<int, 5>::iterator> decltype(auto) i = c.erase(c.begin());
+    assert(i == c.begin());
+    assert_inplace_vector_equal(c, {2, 3, 4});
+  }
+  {
+    std::inplace_vector<int, 5> c{1, 2, 3, 4};
+    auto i = c.erase(c.begin() + 1);
+    assert(i == c.begin() + 1);
+    assert_inplace_vector_equal(c, {1, 3, 4});
+  }
+  {
+    std::inplace_vector<int, 5> c{1, 2, 3, 4};
+    auto i = c.erase(c.end() - 1);
+    assert(i == c.end());
+    assert_inplace_vector_equal(c, {1, 2, 3});
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/erase_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/erase_iter_iter.pass.cpp
new file mode 100644
index 0000000000000..399741849d62d
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/erase_iter_iter.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr iterator erase(const_iterator first, const_iterator last);
+
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 8> c{1, 2, 3, 4, 5};
+    std::same_as<std::inplace_vector<int, 8>::iterator> decltype(auto) i = c.erase(c.begin(), c.begin() + 2);
+    assert(i == c.begin());
+    assert_inplace_vector_equal(c, {3, 4, 5});
+  }
+  {
+    std::inplace_vector<int, 8> c{1, 2, 3, 4, 5};
+    auto i = c.erase(c.begin() + 1, c.begin() + 4);
+    assert(i == c.begin() + 1);
+    assert_inplace_vector_equal(c, {1, 5});
+  }
+  {
+    std::inplace_vector<int, 8> c{1, 2, 3, 4, 5};
+    auto i = c.erase(c.end(), c.end());
+    assert(i == c.end());
+    assert_inplace_vector_equal(c, {1, 2, 3, 4, 5});
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_initializer_list.pass.cpp
new file mode 100644
index 0000000000000..c088fd8a0f984
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_initializer_list.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr iterator insert(const_iterator position, initializer_list<T> il);
+
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 8> c{1, 2, 5};
+  std::same_as<std::inplace_vector<int, 8>::iterator> decltype(auto) i = c.insert(c.begin() + 2, {3, 4});
+  assert(i == c.begin() + 2);
+  assert_inplace_vector_equal(c, {1, 2, 3, 4, 5});
+
+  i = c.insert(c.end(), {});
+  assert(i == c.end());
+  assert_inplace_vector_equal(c, {1, 2, 3, 4, 5});
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 4> c{1, 2, 3};
+  assert_throws_bad_alloc([&] { c.insert(c.begin(), {4, 5}); });
+  assert_inplace_vector_equal(c, {1, 2, 3});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_iter_iter.pass.cpp
new file mode 100644
index 0000000000000..5ed78169e2082
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_iter_iter.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class InputIterator>
+//   constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last);
+
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+namespace adl {
+struct S {};
+void make_move_iterator(S*) {}
+} // namespace adl
+
+template <class Iter>
+constexpr void test_iterators() {
+  int a[] = {3, 4};
+  std::inplace_vector<int, 8> c{1, 2, 5};
+  std::same_as<std::inplace_vector<int, 8>::iterator> decltype(auto) i = c.insert(c.begin() + 2, Iter(a), Iter(a + 2));
+  assert(i == c.begin() + 2);
+  assert_inplace_vector_equal(c, {1, 2, 3, 4, 5});
+
+  i = c.insert(c.end(), Iter(a), Iter(a));
+  assert(i == c.end());
+  assert_inplace_vector_equal(c, {1, 2, 3, 4, 5});
+}
+
+constexpr bool test() {
+  test_iterators<cpp17_input_iterator<int*> >();
+  test_iterators<forward_iterator<int*> >();
+  test_iterators<int*>();
+
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    struct Wrapper {
+      constexpr Wrapper(int n) : n_(n) {}
+      void operator=(int) = delete;
+      int n_;
+    };
+
+    int a[] = {1, 2, 3};
+    std::inplace_vector<Wrapper, 4> c;
+    c.insert(c.end(), a, a + 3);
+    assert(c.size() == 3);
+    assert(c[0].n_ == 1);
+    assert(c[1].n_ == 2);
+    assert(c[2].n_ == 3);
+  }
+  {
+    std::inplace_vector<adl::S, 4> s;
+    s.insert(s.end(), cpp17_input_iterator<adl::S*>(nullptr), cpp17_input_iterator<adl::S*>(nullptr));
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  int a[] = {3, 4};
+  std::inplace_vector<int, 4> c{1, 2, 5};
+  assert_throws_bad_alloc([&] { c.insert(c.begin() + 2, a, a + 2); });
+  assert_inplace_vector_equal(c, {1, 2, 5});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_lvalue.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_lvalue.pass.cpp
new file mode 100644
index 0000000000000..37fefc1981900
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_lvalue.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr iterator insert(const_iterator position, const T& x);
+
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 5> c{1, 2, 4};
+  int x = 3;
+  std::same_as<std::inplace_vector<int, 5>::iterator> decltype(auto) i = c.insert(c.begin() + 2, x);
+  assert(i == c.begin() + 2);
+  assert_inplace_vector_equal(c, {1, 2, 3, 4});
+
+  x = 5;
+  i = c.insert(c.end(), x);
+  assert(i == c.end() - 1);
+  assert_inplace_vector_equal(c, {1, 2, 3, 4, 5});
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 2> c{1, 2};
+  int x = 3;
+  assert_throws_bad_alloc([&] { c.insert(c.begin(), x); });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_rvalue.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_rvalue.pass.cpp
new file mode 100644
index 0000000000000..051b787d6b273
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_rvalue.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr iterator insert(const_iterator position, T&& x);
+
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 5> c{1, 2, 4};
+    std::same_as<std::inplace_vector<int, 5>::iterator> decltype(auto) i = c.insert(c.begin() + 2, 3);
+    assert(i == c.begin() + 2);
+    assert_inplace_vector_equal(c, {1, 2, 3, 4});
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    std::inplace_vector<MoveOnly, 5> c;
+    c.emplace_back(1);
+    c.emplace_back(3);
+    auto i = c.insert(c.begin() + 1, MoveOnly(2));
+    assert(i == c.begin() + 1);
+    assert(c[0].get() == 1);
+    assert(c[1].get() == 2);
+    assert(c[2].get() == 3);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 2> c{1, 2};
+  assert_throws_bad_alloc([&] { c.insert(c.begin(), 3); });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_size_value.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_size_value.pass.cpp
new file mode 100644
index 0000000000000..5e0d7bbb75c4d
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_size_value.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr iterator insert(const_iterator position, size_type n, const T& x);
+
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 8> c{1, 2, 5};
+  std::same_as<std::inplace_vector<int, 8>::iterator> decltype(auto) i = c.insert(c.begin() + 2, 2, 3);
+  assert(i == c.begin() + 2);
+  assert_inplace_vector_equal(c, {1, 2, 3, 3, 5});
+
+  i = c.insert(c.end(), 0, 9);
+  assert(i == c.end());
+  assert_inplace_vector_equal(c, {1, 2, 3, 3, 5});
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 4> c{1, 2, 3};
+  assert_throws_bad_alloc([&] { c.insert(c.begin() + 1, 2, 9); });
+  assert_inplace_vector_equal(c, {1, 2, 3});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_range.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_range.pass.cpp
new file mode 100644
index 0000000000000..a02378ffb8f32
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_range.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000
+
+// <inplace_vector>
+
+// template<container-compatible-range<T> R>
+//   constexpr iterator insert_range(const_iterator position, R&& rg);
+
+#include <array>
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+
+#include "../../insert_range_sequence_containers.h"
+#include "../common.h"
+#include "test_macros.h"
+
+template <class Iter, class Sent>
+constexpr void test_iterators() {
+  test_sequence_insert_range<InplaceVector<int>, Iter, Sent>([]([[maybe_unused]] auto&& c) {});
+}
+
+constexpr bool test() {
+  static_assert(test_constraints_insert_range<InplaceVector, int, double>());
+
+  test_iterators<cpp20_input_iterator<const int*>, sentinel_wrapper<cpp20_input_iterator<const int*> > >();
+  test_iterators<forward_iterator<const int*>, sentinel_wrapper<forward_iterator<const int*> > >();
+  test_iterators<const int*, const int*>();
+
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    test_sequence_insert_range_move_only<InplaceVector>();
+  }
+
+  {
+    int in[] = {-1, -2, -3};
+    std::inplace_vector<int, 8> c{1, 2, 6};
+    std::same_as<std::inplace_vector<int, 8>::iterator> decltype(auto) i = c.insert_range(c.begin() + 2, in);
+    assert(i == c.begin() + 2);
+    assert_inplace_vector_equal(c, {1, 2, -1, -2, -3, 6});
+  }
+
+  // Ensure that insert_range doesn't use unexpected assignment.
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    struct Wrapper {
+      constexpr Wrapper(int n) : n_(n) {}
+      void operator=(int) = delete;
+
+      int n_;
+    };
+
+    int a[]{1, 2, 3, 4, 5};
+    std::inplace_vector<Wrapper, 8> c;
+    c.insert_range(c.end(), a);
+    assert(c.size() == std::size(a));
+    for (std::size_t i = 0; i != std::size(a); ++i)
+      assert(c[i].n_ == a[i]);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  test_insert_range_exception_safety_throwing_copy<InplaceVector>();
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  int in[] = {3, 4};
+  std::inplace_vector<int, 3> c{1, 2};
+  assert_throws_bad_alloc([&] { c.insert_range(c.begin(), in); });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/pop_back.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/pop_back.pass.cpp
new file mode 100644
index 0000000000000..e21321f1cc6e3
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/pop_back.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr void pop_back();
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 4> c{1, 2, 3};
+  c.pop_back();
+  assert_inplace_vector_equal(c, {1, 2});
+  c.pop_back();
+  assert_inplace_vector_equal(c, {1});
+  c.pop_back();
+  assert(c.empty());
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back.pass.cpp
new file mode 100644
index 0000000000000..bb97c2fb6c8b6
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr reference push_back(const T& x);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  std::inplace_vector<int, 3> c;
+  int x = 1;
+  ASSERT_SAME_TYPE(int&, decltype(c.push_back(x)));
+  int& r1 = c.push_back(x);
+  assert(&r1 == &c.back());
+  assert(c.back() == 1);
+  x = 2;
+  int& r2 = c.push_back(x);
+  assert(&r2 == &c.back());
+  assert_inplace_vector_equal(c, {1, 2});
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 2> c{1, 2};
+  int x = 3;
+  assert_throws_bad_alloc([&] { c.push_back(x); });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_exception_safety.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_exception_safety.pass.cpp
new file mode 100644
index 0000000000000..75ff8a5cfcfa5
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_exception_safety.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// UNSUPPORTED: no-exceptions
+
+// <inplace_vector>
+
+// constexpr reference push_back(const T& x);
+// constexpr reference push_back(T&& x);
+// template<class... Args>
+//   constexpr reference emplace_back(Args&&... args);
+
+#include <cassert>
+#include <inplace_vector>
+
+struct ThrowingCopy {
+  int value_;
+  static bool throw_now_;
+
+  explicit ThrowingCopy(int value) : value_(value) {}
+  ThrowingCopy(const ThrowingCopy& other) : value_(other.value_) {
+    if (throw_now_)
+      throw 1;
+  }
+  ThrowingCopy(ThrowingCopy&& other) : value_(other.value_) {
+    if (throw_now_)
+      throw 1;
+  }
+  ThrowingCopy& operator=(const ThrowingCopy&) = default;
+  ThrowingCopy& operator=(ThrowingCopy&&)      = default;
+};
+
+bool ThrowingCopy::throw_now_ = false;
+
+struct ThrowingCtor {
+  explicit ThrowingCtor(int) { throw 1; }
+};
+
+int main(int, char**) {
+  {
+    std::inplace_vector<ThrowingCopy, 3> c;
+    c.emplace_back(1);
+    ThrowingCopy value(2);
+    ThrowingCopy::throw_now_ = true;
+    try {
+      c.push_back(value);
+      assert(false);
+    } catch (int) {
+      assert(c.size() == 1);
+      assert(c[0].value_ == 1);
+    }
+    ThrowingCopy::throw_now_ = false;
+  }
+  {
+    std::inplace_vector<ThrowingCtor, 3> c;
+    try {
+      c.emplace_back(1);
+      assert(false);
+    } catch (int) {
+      assert(c.empty());
+    }
+  }
+
+  return 0;
+}
+
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_rvalue.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_rvalue.pass.cpp
new file mode 100644
index 0000000000000..98cfe7902cd79
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_rvalue.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr reference push_back(T&& x);
+
+#include <cassert>
+#include <inplace_vector>
+
+#include "../common.h"
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 3> c;
+    ASSERT_SAME_TYPE(int&, decltype(c.push_back(1)));
+    int& r = c.push_back(1);
+    assert(&r == &c.back());
+    assert(c.back() == 1);
+    c.push_back(2);
+    assert_inplace_vector_equal(c, {1, 2});
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    std::inplace_vector<MoveOnly, 3> c;
+    MoveOnly m(1);
+    MoveOnly& r = c.push_back(std::move(m));
+    assert(&r == &c.back());
+    assert(c.back().get() == 1);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::inplace_vector<int, 2> c{1, 2};
+  assert_throws_bad_alloc([&] { c.push_back(3); });
+  assert_inplace_vector_equal(c, {1, 2});
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/try_push_back.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/try_push_back.pass.cpp
new file mode 100644
index 0000000000000..dbc4fac080368
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/try_push_back.pass.cpp
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class... Args>
+//   constexpr optional<reference> try_emplace_back(Args&&... args);
+// constexpr optional<reference> try_push_back(const T& x);
+// constexpr optional<reference> try_push_back(T&& x);
+
+#include <cassert>
+#include <concepts>
+#include <inplace_vector>
+#include <optional>
+#include <utility>
+
+#include "../common.h"
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+struct A {
+  int i;
+  int j;
+
+  constexpr A(int ii, int jj) : i(ii), j(jj) {}
+};
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 2> c;
+    int value = 1;
+    std::same_as<std::optional<int&>> decltype(auto) r1 = c.try_push_back(value);
+    assert(r1);
+    assert(&*r1 == &c.back());
+    assert_inplace_vector_equal(c, {1});
+
+    std::same_as<std::optional<int&>> decltype(auto) r2 = c.try_push_back(2);
+    assert(r2);
+    assert(&*r2 == &c.back());
+    assert_inplace_vector_equal(c, {1, 2});
+
+    auto r3 = c.try_push_back(3);
+    assert(!r3);
+    assert_inplace_vector_equal(c, {1, 2});
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    std::inplace_vector<A, 1> c;
+    std::same_as<std::optional<A&>> decltype(auto) r = c.try_emplace_back(1, 2);
+    assert(r);
+    assert(&*r == &c.back());
+    assert(r->i == 1);
+    assert(r->j == 2);
+
+    auto r2 = c.try_emplace_back(3, 4);
+    assert(!r2);
+    assert(c.size() == 1);
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    std::inplace_vector<MoveOnly, 1> c;
+    auto r = c.try_push_back(MoveOnly(1));
+    assert(r);
+    assert(r->get() == 1);
+    auto r2 = c.try_push_back(MoveOnly(2));
+    assert(!r2);
+    assert(c[0].get() == 1);
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    // when there is no effect, the argument is not moved from
+    std::inplace_vector<MoveOnly, 1> c;
+    (void)c.try_push_back(MoveOnly(1));
+    MoveOnly m(2);
+    auto r = c.try_push_back(std::move(m));
+    assert(!r);
+    assert(m.get() == 2);
+    assert(c[0].get() == 1);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  { // an exception thrown by T's constructor propagates and there are no effects
+    ThrowingValue::reset();
+    {
+      std::inplace_vector<ThrowingValue, 4> c;
+      (void)c.try_emplace_back(1);
+      assert(c.size() == 1);
+
+      ThrowingValue::throw_after = 0;
+      try {
+        (void)c.try_emplace_back(2);
+        assert(false);
+      } catch (int) {
+      }
+      ThrowingValue::throw_after = -1;
+      assert(c.size() == 1);
+      assert(c[0].value == 1);
+    }
+    assert(ThrowingValue::alive == 0);
+    ThrowingValue::reset();
+  }
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/unchecked_push_back.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/unchecked_push_back.pass.cpp
new file mode 100644
index 0000000000000..ecbfc335db5ca
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/unchecked_push_back.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class... Args>
+//   constexpr reference unchecked_emplace_back(Args&&... args);
+// constexpr reference unchecked_push_back(const T& x);
+// constexpr reference unchecked_push_back(T&& x);
+
+#include <cassert>
+#include <inplace_vector>
+#include <utility>
+
+#include "../common.h"
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+struct A {
+  int i;
+  int j;
+
+  constexpr A(int ii, int jj) : i(ii), j(jj) {}
+};
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 3> c;
+    int value = 1;
+    ASSERT_SAME_TYPE(int&, decltype(c.unchecked_push_back(value)));
+    ASSERT_SAME_TYPE(int&, decltype(c.unchecked_push_back(1)));
+    int& r1 = c.unchecked_push_back(value);
+    assert(&r1 == &c.back());
+    int& r2 = c.unchecked_push_back(2);
+    assert(&r2 == &c.back());
+    assert_inplace_vector_equal(c, {1, 2});
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    std::inplace_vector<A, 2> c;
+    ASSERT_SAME_TYPE(A&, decltype(c.unchecked_emplace_back(1, 2)));
+    A& r = c.unchecked_emplace_back(1, 2);
+    assert(&r == &c.back());
+    assert(c[0].i == 1);
+    assert(c[0].j == 2);
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED || TEST_INPLACE_VECTOR_NONTRIVIAL_CONSTEXPR) {
+    std::inplace_vector<MoveOnly, 1> c;
+    MoveOnly& r = c.unchecked_push_back(MoveOnly(1));
+    assert(&r == &c.back());
+    assert(c[0].get() == 1);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.special/swap.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.special/swap.pass.cpp
new file mode 100644
index 0000000000000..ed59a8a81bada
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.special/swap.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// constexpr void swap(inplace_vector& x)
+//   noexcept(N == 0 || (is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<T>));
+
+#include <cassert>
+#include <inplace_vector>
+#include <utility>
+
+#include "../common.h"
+#include "test_macros.h"
+
+struct ThrowingMove {
+  ThrowingMove() = default;
+  ThrowingMove(ThrowingMove&&) noexcept(false) {}
+  ThrowingMove& operator=(ThrowingMove&&) noexcept(false) { return *this; }
+};
+
+constexpr bool test() {
+  {
+    std::inplace_vector<int, 8> c1{1, 2, 3};
+    std::inplace_vector<int, 8> c2{4, 5};
+    c1.swap(c2);
+    assert_inplace_vector_equal(c1, {4, 5});
+    assert_inplace_vector_equal(c2, {1, 2, 3});
+  }
+  {
+    std::inplace_vector<int, 8> c1{1, 2, 3};
+    std::inplace_vector<int, 8> c2{4, 5};
+    swap(c1, c2);
+    assert_inplace_vector_equal(c1, {4, 5});
+    assert_inplace_vector_equal(c2, {1, 2, 3});
+  }
+
+  { // noexcept(N == 0 || (is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<T>))
+    using C0 = std::inplace_vector<ThrowingMove, 0>;
+    using C8 = std::inplace_vector<ThrowingMove, 8>;
+    std::inplace_vector<int, 8> c1;
+    std::inplace_vector<int, 8> c2;
+    ASSERT_NOEXCEPT(swap(c1, c2));
+    ASSERT_NOEXCEPT(swap(std::declval<C0&>(), std::declval<C0&>()));
+    ASSERT_NOT_NOEXCEPT(swap(std::declval<C8&>(), std::declval<C8&>()));
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/iterator_concept_conformance.compile.pass.cpp
new file mode 100644
index 0000000000000..70c4d593af0a2
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/iterator_concept_conformance.compile.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// inplace_vector<T,N>::iterator
+// inplace_vector<T,N>::const_iterator
+
+#include <inplace_vector>
+#include <iterator>
+
+template <class C>
+constexpr bool test() {
+  static_assert(std::contiguous_iterator<typename C::iterator>);
+  static_assert(std::contiguous_iterator<typename C::const_iterator>);
+  static_assert(std::sentinel_for<typename C::iterator, typename C::iterator>);
+  static_assert(std::sentinel_for<typename C::const_iterator, typename C::iterator>);
+  static_assert(std::sentinel_for<typename C::iterator, typename C::const_iterator>);
+  static_assert(std::sentinel_for<typename C::const_iterator, typename C::const_iterator>);
+
+  return true;
+}
+
+static_assert(test<std::inplace_vector<int, 0> >());
+static_assert(test<std::inplace_vector<int, 8> >());
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/iterators.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/iterators.pass.cpp
new file mode 100644
index 0000000000000..5377f55d75538
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/iterators.pass.cpp
@@ -0,0 +1,128 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// iterator       begin() noexcept;
+// iterator       end() noexcept;
+// const_iterator begin() const noexcept;
+// const_iterator end() const noexcept;
+// const_iterator cbegin() const noexcept;
+// const_iterator cend() const noexcept;
+
+#include <cassert>
+#include <compare>
+#include <concepts>
+#include <inplace_vector>
+#include <iterator>
+
+#include "test_macros.h"
+
+struct A {
+  int first;
+  int second;
+};
+
+constexpr bool test() {
+  {
+    using C = std::inplace_vector<int, 8>;
+    C c;
+    const C& cc = c;
+    ASSERT_SAME_TYPE(C::iterator, decltype(c.begin()));
+    ASSERT_SAME_TYPE(C::iterator, decltype(c.end()));
+    ASSERT_SAME_TYPE(C::const_iterator, decltype(cc.begin()));
+    ASSERT_SAME_TYPE(C::const_iterator, decltype(cc.end()));
+    ASSERT_SAME_TYPE(C::const_iterator, decltype(c.cbegin()));
+    ASSERT_SAME_TYPE(C::const_iterator, decltype(c.cend()));
+    C::iterator i = c.begin();
+    C::iterator j = c.end();
+    assert(std::distance(i, j) == 0);
+    assert(i == j);
+  }
+  {
+    using C = std::inplace_vector<int, 8>;
+    const C c;
+    C::const_iterator i = c.begin();
+    C::const_iterator j = c.end();
+    assert(std::distance(i, j) == 0);
+    assert(i == j);
+  }
+  {
+    using C = std::inplace_vector<int, 8>;
+    C c;
+    C::const_iterator i = c.cbegin();
+    C::const_iterator j = c.cend();
+    assert(std::distance(i, j) == 0);
+    assert(i == j);
+    assert(i == c.end());
+  }
+  {
+    using C = std::inplace_vector<int, 16>;
+    C c{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+    C::iterator i = c.begin();
+    assert(*i == 0);
+    ++i;
+    assert(*i == 1);
+    *i = 10;
+    assert(*i == 10);
+    assert(std::distance(c.begin(), c.end()) == 10);
+  }
+  {
+    using C = std::inplace_vector<int, 8>;
+    C::iterator i{};
+    C::const_iterator j{};
+    assert(i == i);
+    assert(j == j);
+  }
+  {
+    using C = std::inplace_vector<A, 4>;
+    C c                 = {A{1, 2}};
+    C::iterator i       = c.begin();
+    i->first            = 3;
+    C::const_iterator j = i;
+    assert(j->first == 3);
+  }
+  {
+    using C = std::inplace_vector<int, 8>;
+    C::iterator i{};
+    C::iterator j{};
+    C::const_iterator ci{};
+
+    assert(i == j);
+    assert(i == ci);
+    assert(ci == i);
+    assert(!(i != ci));
+    assert(!(ci != i));
+    assert(!(i < ci));
+    assert(!(ci < i));
+    assert(i <= ci);
+    assert(ci <= i);
+    assert(!(i > ci));
+    assert(!(ci > i));
+    assert(i >= ci);
+    assert(ci >= i);
+    assert(ci - i == 0);
+    assert(i - ci == 0);
+
+    std::same_as<std::strong_ordering> decltype(auto) r1 = i <=> j;
+    assert(r1 == std::strong_ordering::equal);
+    std::same_as<std::strong_ordering> decltype(auto) r2 = ci <=> j;
+    assert(r2 == std::strong_ordering::equal);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/range_concept_conformance.compile.pass.cpp
new file mode 100644
index 0000000000000..a3925db592927
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/range_concept_conformance.compile.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+#include <inplace_vector>
+#include <ranges>
+
+template <class C>
+constexpr bool test() {
+  static_assert(std::ranges::contiguous_range<C>);
+  static_assert(std::ranges::contiguous_range<const C>);
+  static_assert(std::ranges::sized_range<C>);
+  static_assert(std::ranges::sized_range<const C>);
+  static_assert(std::ranges::common_range<C>);
+  static_assert(std::ranges::common_range<const C>);
+  static_assert(!std::ranges::view<C>);
+  static_assert(!std::ranges::borrowed_range<C>);
+  return true;
+}
+
+static_assert(test<std::inplace_vector<int, 0> >());
+static_assert(test<std::inplace_vector<int, 8> >());
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/reverse_iterators.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/reverse_iterators.pass.cpp
new file mode 100644
index 0000000000000..7ae9c0dd34c73
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/reverse_iterators.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// reverse_iterator       rbegin() noexcept;
+// reverse_iterator       rend() noexcept;
+// const_reverse_iterator rbegin() const noexcept;
+// const_reverse_iterator rend() const noexcept;
+// const_reverse_iterator crbegin() const noexcept;
+// const_reverse_iterator crend() const noexcept;
+
+#include <cassert>
+#include <inplace_vector>
+#include <iterator>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    using C = std::inplace_vector<int, 8>;
+    C c;
+    const C& cc = c;
+    ASSERT_SAME_TYPE(C::reverse_iterator, decltype(c.rbegin()));
+    ASSERT_SAME_TYPE(C::reverse_iterator, decltype(c.rend()));
+    ASSERT_SAME_TYPE(C::const_reverse_iterator, decltype(cc.rbegin()));
+    ASSERT_SAME_TYPE(C::const_reverse_iterator, decltype(cc.rend()));
+    ASSERT_SAME_TYPE(C::const_reverse_iterator, decltype(c.crbegin()));
+    ASSERT_SAME_TYPE(C::const_reverse_iterator, decltype(c.crend()));
+    assert(c.rbegin() == c.rend());
+    assert(c.crbegin() == c.crend());
+  }
+  {
+    using C = std::inplace_vector<int, 8>;
+    C c{1, 2, 3};
+    C::reverse_iterator i = c.rbegin();
+    assert(*i == 3);
+    *i = 4;
+    assert(c.back() == 4);
+    ++i;
+    assert(*i == 2);
+    assert(std::distance(c.rbegin(), c.rend()) == 3);
+  }
+  {
+    using C = std::inplace_vector<int, 8>;
+    const C c{1, 2, 3};
+    C::const_reverse_iterator i = c.rbegin();
+    assert(*i == 3);
+    assert(c.crbegin() == c.rbegin());
+    assert(c.crend() == c.rend());
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/triviality.compile.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/triviality.compile.pass.cpp
new file mode 100644
index 0000000000000..01cee8651c027
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/triviality.compile.pass.cpp
@@ -0,0 +1,141 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+#include <inplace_vector>
+#include <type_traits>
+
+struct Trivial {
+  int value;
+};
+
+struct NonTrivialDtor {
+  NonTrivialDtor()                                 = default;
+  NonTrivialDtor(const NonTrivialDtor&)            = default;
+  NonTrivialDtor(NonTrivialDtor&&)                 = default;
+  NonTrivialDtor& operator=(const NonTrivialDtor&) = default;
+  NonTrivialDtor& operator=(NonTrivialDtor&&)      = default;
+  ~NonTrivialDtor() {}
+};
+
+struct NonTrivialCopyCtor {
+  NonTrivialCopyCtor() = default;
+  NonTrivialCopyCtor(const NonTrivialCopyCtor&) {}
+  NonTrivialCopyCtor(NonTrivialCopyCtor&&)                 = default;
+  NonTrivialCopyCtor& operator=(const NonTrivialCopyCtor&) = default;
+  NonTrivialCopyCtor& operator=(NonTrivialCopyCtor&&)      = default;
+  ~NonTrivialCopyCtor()                                    = default;
+};
+
+struct NonTrivialMoveCtor {
+  NonTrivialMoveCtor()                          = default;
+  NonTrivialMoveCtor(const NonTrivialMoveCtor&) = default;
+  NonTrivialMoveCtor(NonTrivialMoveCtor&&) {}
+  NonTrivialMoveCtor& operator=(const NonTrivialMoveCtor&) = default;
+  NonTrivialMoveCtor& operator=(NonTrivialMoveCtor&&)      = default;
+  ~NonTrivialMoveCtor()                                    = default;
+};
+
+struct NonTrivialCopyAssign {
+  NonTrivialCopyAssign()                            = default;
+  NonTrivialCopyAssign(const NonTrivialCopyAssign&) = default;
+  NonTrivialCopyAssign(NonTrivialCopyAssign&&)      = default;
+  NonTrivialCopyAssign& operator=(const NonTrivialCopyAssign&) { return *this; }
+  NonTrivialCopyAssign& operator=(NonTrivialCopyAssign&&) = default;
+  ~NonTrivialCopyAssign()                                 = default;
+};
+
+struct NonTrivialMoveAssign {
+  NonTrivialMoveAssign()                                       = default;
+  NonTrivialMoveAssign(const NonTrivialMoveAssign&)            = default;
+  NonTrivialMoveAssign(NonTrivialMoveAssign&&)                 = default;
+  NonTrivialMoveAssign& operator=(const NonTrivialMoveAssign&) = default;
+  NonTrivialMoveAssign& operator=(NonTrivialMoveAssign&&) { return *this; }
+  ~NonTrivialMoveAssign() = default;
+};
+
+struct MoveOnlyTrivial {
+  MoveOnlyTrivial()                                  = default;
+  MoveOnlyTrivial(const MoveOnlyTrivial&)            = delete;
+  MoveOnlyTrivial(MoveOnlyTrivial&&)                 = default;
+  MoveOnlyTrivial& operator=(const MoveOnlyTrivial&) = delete;
+  MoveOnlyTrivial& operator=(MoveOnlyTrivial&&)      = default;
+  ~MoveOnlyTrivial()                                 = default;
+};
+
+struct NonTrivialAll {
+  NonTrivialAll() {}
+  NonTrivialAll(const NonTrivialAll&) {}
+  NonTrivialAll(NonTrivialAll&&) {}
+  NonTrivialAll& operator=(const NonTrivialAll&) { return *this; }
+  NonTrivialAll& operator=(NonTrivialAll&&) { return *this; }
+  ~NonTrivialAll() {}
+};
+
+struct NoDefaultCtor {
+  explicit NoDefaultCtor(int);
+};
+
+template <class T, unsigned long long _Size>
+constexpr bool check() {
+  using V = std::inplace_vector<T, _Size>;
+
+  static_assert(std::is_trivially_copy_constructible_v<V> == std::is_trivially_copy_constructible_v<T>);
+  static_assert(std::is_trivially_move_constructible_v<V> == std::is_trivially_move_constructible_v<T>);
+  static_assert(std::is_trivially_destructible_v<V> == std::is_trivially_destructible_v<T>);
+  static_assert(std::is_trivially_copy_assignable_v<V> ==
+                (std::is_trivially_destructible_v<T> && std::is_trivially_copy_constructible_v<T> &&
+                 std::is_trivially_copy_assignable_v<T>));
+  static_assert(std::is_trivially_move_assignable_v<V> ==
+                (std::is_trivially_destructible_v<T> && std::is_trivially_move_constructible_v<T> &&
+                 std::is_trivially_move_assignable_v<T>));
+
+  static_assert(!std::is_trivially_default_constructible_v<V>);
+
+  return true;
+}
+
+// N == 0 always trivial
+template <class T>
+constexpr bool zero_capacity() {
+  using V = std::inplace_vector<T, 0>;
+
+  static_assert(std::is_trivially_copyable_v<V>);
+  static_assert(std::is_trivially_default_constructible_v<V>);
+  static_assert(std::is_trivially_copy_constructible_v<V>);
+  static_assert(std::is_trivially_move_constructible_v<V>);
+  static_assert(std::is_trivially_copy_assignable_v<V>);
+  static_assert(std::is_trivially_move_assignable_v<V>);
+  static_assert(std::is_trivially_destructible_v<V>);
+
+  return true;
+}
+
+static_assert(check<int, 4>());
+static_assert(check<Trivial, 4>());
+static_assert(check<NonTrivialDtor, 4>());
+static_assert(check<NonTrivialCopyCtor, 4>());
+static_assert(check<NonTrivialMoveCtor, 4>());
+static_assert(check<NonTrivialCopyAssign, 4>());
+static_assert(check<NonTrivialMoveAssign, 4>());
+static_assert(check<MoveOnlyTrivial, 4>());
+static_assert(check<NonTrivialAll, 4>());
+
+static_assert(zero_capacity<int>());
+static_assert(zero_capacity<Trivial>());
+static_assert(zero_capacity<NonTrivialDtor>());
+static_assert(zero_capacity<NonTrivialCopyCtor>());
+static_assert(zero_capacity<NonTrivialMoveCtor>());
+static_assert(zero_capacity<NonTrivialCopyAssign>());
+static_assert(zero_capacity<NonTrivialMoveAssign>());
+static_assert(zero_capacity<MoveOnlyTrivial>());
+static_assert(zero_capacity<NonTrivialAll>());
+static_assert(zero_capacity<NoDefaultCtor>());
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/types.compile.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/types.compile.pass.cpp
new file mode 100644
index 0000000000000..320bb0d6fde74
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/types.compile.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <inplace_vector>
+
+// template<class T, size_t N> class inplace_vector;
+
+#include <concepts>
+#include <cstddef>
+#include <inplace_vector>
+#include <iterator>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "../../Copyable.h"
+
+template <class T, std::size_t _Cap>
+void test() {
+  using C = std::inplace_vector<T, _Cap>;
+
+  static_assert(std::is_same_v<typename C::value_type, T>);
+  static_assert(std::is_same_v<typename C::reference, T&>);
+  static_assert(std::is_same_v<typename C::const_reference, const T&>);
+  static_assert(std::is_same_v<typename C::pointer, T*>);
+  static_assert(std::is_same_v<typename C::const_pointer, const T*>);
+  static_assert(std::is_same_v<typename C::size_type, std::size_t>);
+  static_assert(std::is_same_v<typename C::difference_type, std::ptrdiff_t>);
+  static_assert(std::is_same_v<typename C::reverse_iterator, std::reverse_iterator<typename C::iterator> >);
+  static_assert(std::is_same_v<typename C::const_reverse_iterator, std::reverse_iterator<typename C::const_iterator> >);
+
+  static_assert(std::contiguous_iterator<typename C::iterator>);
+  static_assert(std::contiguous_iterator<typename C::const_iterator>);
+  static_assert(std::same_as<typename std::iterator_traits<typename C::iterator>::iterator_category,
+                             std::random_access_iterator_tag>);
+  static_assert(std::same_as<typename std::iterator_traits<typename C::const_iterator>::iterator_category,
+                             std::random_access_iterator_tag>);
+}
+
+int main(int, char**) {
+  test<int, 0>();
+  test<int, 42>();
+  test<int*, 42>();
+  test<Copyable, 42>();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/zero_capacity.exceptions.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/zero_capacity.exceptions.pass.cpp
new file mode 100644
index 0000000000000..8a552f5bf5709
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/inplace_vector/zero_capacity.exceptions.pass.cpp
@@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// UNSUPPORTED: no-exceptions
+
+// Clang's -Wunreachable-code does not model exceptional exits from [[noreturn]] members
+// (e.g. at() in this specialization), flagging the catch handlers below.
+// ADDITIONAL_COMPILE_FLAGS: -Wno-unreachable-code
+
+// <inplace_vector>
+
+#include <cassert>
+#include <inplace_vector>
+#include <new>
+#include <stdexcept>
+#include <utility>
+
+#include "common.h"
+#include "test_macros.h"
+
+using C = std::inplace_vector<int, 0>;
+
+void test_throwing_members() {
+  int a[] = {1, 2};
+
+  assert_throws_bad_alloc([] { C c(1); });
+  assert_throws_bad_alloc([] { C c(1, 42); });
+  assert_throws_bad_alloc([&] { C c(a, a + 2); });
+  assert_throws_bad_alloc([&] { C c(std::from_range, a); });
+  assert_throws_bad_alloc([] { C c{1, 2}; });
+
+  C c;
+  assert_throws_bad_alloc([&] { c = {1, 2}; });
+  assert_throws_bad_alloc([&] { c.assign(a, a + 2); });
+  assert_throws_bad_alloc([&] { c.assign_range(a); });
+  assert_throws_bad_alloc([&] { c.assign(2, 42); });
+  assert_throws_bad_alloc([&] { c.assign({1, 2}); });
+
+  assert_throws_bad_alloc([&] { c.resize(1); });
+  assert_throws_bad_alloc([&] { c.resize(1, 42); });
+  assert_throws_bad_alloc([&] { c.reserve(1); });
+  assert_throws_bad_alloc([&] { C::reserve(1); });
+
+  int value = 42;
+  assert_throws_bad_alloc([&] { c.emplace_back(42); });
+  assert_throws_bad_alloc([&] { c.push_back(value); });
+  assert_throws_bad_alloc([&] { c.push_back(42); });
+  assert_throws_bad_alloc([&] { c.append_range(a); });
+
+  assert_throws_bad_alloc([&] { c.emplace(c.begin(), 42); });
+  assert_throws_bad_alloc([&] { c.insert(c.begin(), value); });
+  assert_throws_bad_alloc([&] { c.insert(c.begin(), 42); });
+  assert_throws_bad_alloc([&] { c.insert(c.begin(), 2, 42); });
+  assert_throws_bad_alloc([&] { c.insert(c.begin(), a, a + 2); });
+  assert_throws_bad_alloc([&] { c.insert_range(c.begin(), a); });
+  assert_throws_bad_alloc([&] { c.insert(c.begin(), {1, 2}); });
+
+  assert(c.empty());
+
+  bool threw = false;
+  try {
+    (void)c.at(0);
+  } catch (const std::out_of_range&) {
+    threw = true;
+  }
+  assert(threw);
+
+  threw = false;
+  try {
+    (void)std::as_const(c).at(0);
+  } catch (const std::out_of_range&) {
+    threw = true;
+  }
+  assert(threw);
+}
+
+constexpr bool test_non_throwing_members() {
+  int a[] = {1, 2};
+
+  // Requests for zero elements and empty inputs must not throw.
+  C c(0);
+  C c2(0, 42);
+  C c3(a, a);
+  C c4{};
+  assert(c2.empty() && c3.empty() && c4.empty());
+  c = {};
+  c.assign(a, a);
+  c.assign(0, 42);
+  c.assign(std::initializer_list<int>{});
+  c.resize(0);
+  c.resize(0, 42);
+  c.reserve(0);
+  c.shrink_to_fit();
+
+  assert(c.insert(c.begin(), 0, 42) == c.begin());
+  assert(c.insert(c.begin(), a, a) == c.begin());
+  assert(c.insert(c.begin(), std::initializer_list<int>{}) == c.begin());
+  assert(c.erase(c.begin(), c.begin()) == c.begin());
+
+  // The try_* forms report a full container instead of throwing.
+  int value = 42;
+  assert(!c.try_emplace_back(42).has_value());
+  assert(!c.try_push_back(value).has_value());
+  assert(!c.try_push_back(42).has_value());
+
+  assert(c.empty());
+
+  return true;
+}
+
+int main(int, char**) {
+  test_throwing_members();
+
+  test_non_throwing_members();
+  static_assert(test_non_throwing_members());
+
+  return 0;
+}
diff --git a/libcxx/utils/libcxx/test/features/libcxx_macros.py b/libcxx/utils/libcxx/test/features/libcxx_macros.py
index aeb4696501a83..e6c461979dcd5 100644
--- a/libcxx/utils/libcxx/test/features/libcxx_macros.py
+++ b/libcxx/utils/libcxx/test/features/libcxx_macros.py
@@ -29,6 +29,7 @@
     "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL": "libcpp-has-abi-bounded-iterators-in-optional",
     "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR": "libcpp-has-abi-bounded-iterators-in-vector",
     "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY": "libcpp-has-abi-bounded-iterators-in-std-array",
+    "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_INPLACE_VECTOR": "libcpp-has-abi-bounded-iterators-in-inplace-vector",
     "_LIBCPP_ABI_BOUNDED_UNIQUE_PTR": "libcpp-has-abi-bounded-unique_ptr",
     "_LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE": "libcpp-has-abi-fix-unordered-container-size-type",
     "_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR": "libcpp-deprecated-abi-disable-pair-trivial-copy-ctor",

>From 2d8271c6a00d52d034a28a2d46287e0dd4f98530 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Fri, 12 Jun 2026 22:51:08 -0400
Subject: [PATCH 03/11] Clang treats string literals as a variable in constant
 expression

---
 libcxx/include/inplace_vector | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/inplace_vector b/libcxx/include/inplace_vector
index 0d0f0418274dd..b06ce41ca4f50 100644
--- a/libcxx/include/inplace_vector
+++ b/libcxx/include/inplace_vector
@@ -247,7 +247,9 @@ private:
         }
       } else {
 #    if !defined(__cpp_trivial_union)
-        _LIBCPP_VERBOSE_ABORT("std::inplace_vector<T,N> currently cannot be used in constant expressions for "
+        // TODO: Clang emits a -Wformat-security warning for this when it's in a consteval block. File bug for this
+        _LIBCPP_VERBOSE_ABORT("%s",
+                              "std::inplace_vector<T,N> currently cannot be used in constant expressions for "
                               "non-trivial T on compilers where P3074 is not implemented.");
 #    endif
       }

>From 5cbb5257877ba837d7f0907ae65f2e59f9029bab Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Mon, 15 Jun 2026 18:35:07 -0400
Subject: [PATCH 04/11] Formatting and pop macros at right place

---
 libcxx/include/inplace_vector                 |  4 +-
 libcxx/modules/std/inplace_vector.inc         |  2 +-
 .../inplace_vector/nodiscard.verify.cpp       | 60 +++++++++----------
 .../inplace_vector/addressof.compile.pass.cpp |  9 ++-
 .../inplace.vector.cons/assign_move.pass.cpp  |  4 +-
 .../inplace.vector.cons/exceptions.pass.cpp   |  5 +-
 .../inplace.vector.erasure/erase_if.pass.cpp  |  3 +-
 .../insert_iter_lvalue.pass.cpp               |  1 +
 .../push_back.pass.cpp                        |  2 +
 .../push_back_exception_safety.pass.cpp       |  1 -
 .../try_push_back.pass.cpp                    |  1 +
 .../inplace_vector/iterators.pass.cpp         |  2 +-
 12 files changed, 48 insertions(+), 46 deletions(-)

diff --git a/libcxx/include/inplace_vector b/libcxx/include/inplace_vector
index b06ce41ca4f50..a2e857e738e29 100644
--- a/libcxx/include/inplace_vector
+++ b/libcxx/include/inplace_vector
@@ -1123,10 +1123,10 @@ erase(std::inplace_vector<_Tp, _Cap>& __c, const _Up& __value) {
 
 _LIBCPP_END_NAMESPACE_STD
 
-_LIBCPP_POP_MACROS
-
 #  endif // _LIBCPP_STD_VER >= 26
 
+_LIBCPP_POP_MACROS
+
 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
 
 #endif // _LIBCPP_INPLACE_VECTOR
diff --git a/libcxx/modules/std/inplace_vector.inc b/libcxx/modules/std/inplace_vector.inc
index 458ca4488fb46..d213d4d43c624 100644
--- a/libcxx/modules/std/inplace_vector.inc
+++ b/libcxx/modules/std/inplace_vector.inc
@@ -12,4 +12,4 @@ export namespace std {
   using std::inplace_vector;
 #endif
 
-}
+} // namespace std
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/nodiscard.verify.cpp
index 4144f3be5d25c..67e6cfc7629d8 100644
--- a/libcxx/test/libcxx/containers/sequences/inplace_vector/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/nodiscard.verify.cpp
@@ -13,40 +13,40 @@
 void test() {
   std::inplace_vector<int, 4> v;
 
-  v.at(0);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.back();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.begin();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.capacity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.cbegin();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.cend();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.crbegin();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.crend();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.data();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.empty();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.end();      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.front();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.rbegin();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.rend();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v.size();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v[0];         // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.at(0);               // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.back();              // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.begin();             // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.capacity();          // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.cbegin();            // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.cend();              // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.crbegin();           // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.crend();             // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.data();              // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.empty();             // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.end();               // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.front();             // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.max_size();          // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.rbegin();            // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.rend();              // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.size();              // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v[0];                  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   v.try_emplace_back(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   v.try_push_back(1);    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
 
   std::inplace_vector<int, 0> v0;
-  v0.begin();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.capacity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.cbegin();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.cend();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.crbegin();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.crend();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.data();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.empty();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.end();      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.rbegin();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.rend();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  v0.size();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.begin();             // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.capacity();          // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.cbegin();            // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.cend();              // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.crbegin();           // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.crend();             // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.data();              // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.empty();             // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.end();               // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.max_size();          // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.rbegin();            // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.rend();              // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v0.size();              // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   v0.try_emplace_back(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   v0.try_push_back(1);    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
 
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/addressof.compile.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/addressof.compile.pass.cpp
index 94a722eea6d04..986e6a131a3fa 100644
--- a/libcxx/test/std/containers/sequences/inplace_vector/addressof.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/inplace_vector/addressof.compile.pass.cpp
@@ -20,11 +20,10 @@
 
 using InplaceVector = std::inplace_vector<operator_hijacker, 16>;
 
-void test(
-    InplaceVector v,
-    InplaceVector::const_iterator it,
-    cpp17_input_iterator<operator_hijacker*> other_it,
-    operator_hijacker val) {
+void test(InplaceVector v,
+          InplaceVector::const_iterator it,
+          cpp17_input_iterator<operator_hijacker*> other_it,
+          operator_hijacker val) {
   // emplace / insert
   v.emplace(it);
   v.insert(it, it, it);
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_move.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_move.pass.cpp
index 64d720ed68aa0..02554a06e7683 100644
--- a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_move.pass.cpp
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/assign_move.pass.cpp
@@ -35,7 +35,7 @@ struct ThrowingMoveCtorOnly {
 };
 
 struct ThrowingMoveAssignOnly {
-  ThrowingMoveAssignOnly() = default;
+  ThrowingMoveAssignOnly()                                  = default;
   ThrowingMoveAssignOnly(ThrowingMoveAssignOnly&&) noexcept = default;
   ThrowingMoveAssignOnly& operator=(ThrowingMoveAssignOnly&&) noexcept(false) { return *this; }
 };
@@ -66,7 +66,7 @@ constexpr bool test() {
   { // self-move-assignment leaves the container in a valid state
     std::inplace_vector<int, 8> c{1, 2, 3};
     std::inplace_vector<int, 8>& ref = c;
-    c = std::move(ref);
+    c                                = std::move(ref);
     LIBCPP_ASSERT(c == (std::inplace_vector<int, 8>{1, 2, 3}));
   }
 
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/exceptions.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/exceptions.pass.cpp
index b82629f84ab3d..1257c14ad8dc7 100644
--- a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.cons/exceptions.pass.cpp
@@ -60,9 +60,8 @@ void test_iterator_constructor_exceptions() {
   {
     ThrowingValue values[] = {ThrowingValue(1), ThrowingValue(2)};
     try {
-      std::inplace_vector<ThrowingValue, 4> c(
-          throwing_iterator<ThrowingValue, std::input_iterator_tag>(values),
-          throwing_iterator<ThrowingValue, std::input_iterator_tag>(values + 2, 2));
+      std::inplace_vector<ThrowingValue, 4> c(throwing_iterator<ThrowingValue, std::input_iterator_tag>(values),
+                                              throwing_iterator<ThrowingValue, std::input_iterator_tag>(values + 2, 2));
       assert(false);
     } catch (int) {
       assert(ThrowingValue::alive == 2);
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase_if.pass.cpp
index 84d7ab0a3d401..65beb5711a084 100644
--- a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase_if.pass.cpp
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.erasure/erase_if.pass.cpp
@@ -22,7 +22,8 @@
 
 constexpr bool test() {
   std::inplace_vector<int, 8> c{1, 2, 3, 4, 5, 6};
-  ASSERT_SAME_TYPE(std::inplace_vector<int, 8>::size_type, decltype(std::erase_if(c, [](int v) { return v % 2 == 0; })));
+  ASSERT_SAME_TYPE(
+      std::inplace_vector<int, 8>::size_type, decltype(std::erase_if(c, [](int v) { return v % 2 == 0; })));
   auto erased = std::erase_if(c, [](int v) { return v % 2 == 0; });
   assert(erased == 3);
   assert_inplace_vector_equal(c, {1, 3, 5});
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_lvalue.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_lvalue.pass.cpp
index 37fefc1981900..698662d24dc93 100644
--- a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_lvalue.pass.cpp
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/insert_iter_lvalue.pass.cpp
@@ -22,6 +22,7 @@
 constexpr bool test() {
   std::inplace_vector<int, 5> c{1, 2, 4};
   int x = 3;
+
   std::same_as<std::inplace_vector<int, 5>::iterator> decltype(auto) i = c.insert(c.begin() + 2, x);
   assert(i == c.begin() + 2);
   assert_inplace_vector_equal(c, {1, 2, 3, 4});
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back.pass.cpp
index bb97c2fb6c8b6..8d4bb8a7304cd 100644
--- a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back.pass.cpp
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back.pass.cpp
@@ -25,7 +25,9 @@ constexpr bool test() {
   int& r1 = c.push_back(x);
   assert(&r1 == &c.back());
   assert(c.back() == 1);
+
   x = 2;
+
   int& r2 = c.push_back(x);
   assert(&r2 == &c.back());
   assert_inplace_vector_equal(c, {1, 2});
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_exception_safety.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_exception_safety.pass.cpp
index 75ff8a5cfcfa5..8b9fb3cff4f4a 100644
--- a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_exception_safety.pass.cpp
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/push_back_exception_safety.pass.cpp
@@ -69,4 +69,3 @@ int main(int, char**) {
 
   return 0;
 }
-
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/try_push_back.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/try_push_back.pass.cpp
index dbc4fac080368..46882cc405bc0 100644
--- a/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/try_push_back.pass.cpp
+++ b/libcxx/test/std/containers/sequences/inplace_vector/inplace.vector.modifiers/try_push_back.pass.cpp
@@ -36,6 +36,7 @@ constexpr bool test() {
   {
     std::inplace_vector<int, 2> c;
     int value = 1;
+
     std::same_as<std::optional<int&>> decltype(auto) r1 = c.try_push_back(value);
     assert(r1);
     assert(&*r1 == &c.back());
diff --git a/libcxx/test/std/containers/sequences/inplace_vector/iterators.pass.cpp b/libcxx/test/std/containers/sequences/inplace_vector/iterators.pass.cpp
index 5377f55d75538..5030cb5dca46d 100644
--- a/libcxx/test/std/containers/sequences/inplace_vector/iterators.pass.cpp
+++ b/libcxx/test/std/containers/sequences/inplace_vector/iterators.pass.cpp
@@ -82,7 +82,7 @@ constexpr bool test() {
     assert(j == j);
   }
   {
-    using C = std::inplace_vector<A, 4>;
+    using C             = std::inplace_vector<A, 4>;
     C c                 = {A{1, 2}};
     C::iterator i       = c.begin();
     i->first            = 3;

>From 514b7209e45a3bf3933966d511b51022ada5f680 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Mon, 15 Jun 2026 21:29:13 -0400
Subject: [PATCH 05/11] check_assertion.h doesn't compile on llvm-libc

---
 .../sequences/inplace_vector/assert.zero_capacity.pass.cpp     | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
index fefe61e1eef53..7a1419c27c79c 100644
--- a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
@@ -10,6 +10,9 @@
 
 // <inplace_vector>
 
+// No member named 'regex'.
+// XFAIL: LLVM-LIBC-FIXME
+
 #include <inplace_vector>
 #include <utility>
 

>From 42aa1bc7cb3350734871f36a16589d08a86f5031 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Mon, 15 Jun 2026 22:32:29 -0400
Subject: [PATCH 06/11] Code-related comments

---
 libcxx/include/inplace_vector | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libcxx/include/inplace_vector b/libcxx/include/inplace_vector
index a2e857e738e29..f9ad3022c8654 100644
--- a/libcxx/include/inplace_vector
+++ b/libcxx/include/inplace_vector
@@ -231,7 +231,7 @@ private:
       return static_cast<std::size_t>(0);
   }
 
-  using __size_type = decltype(__get_size_type());
+  using __size_type _LIBCPP_NODEBUG = decltype(__get_size_type());
 
   union {
     _Tp __elems_[_Cap];
@@ -254,7 +254,6 @@ private:
 #    endif
       }
     }
-    // std::start_lifetime_as_array?
   }
 
 public:

>From f04094ad429c4a98c4f6bf85f7724b7621fc8c12 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Wed, 17 Jun 2026 22:26:57 -0400
Subject: [PATCH 07/11] Resolve more issues

---
 libcxx/docs/Status/Cxx2cIssues.csv | 6 +++---
 libcxx/docs/Status/Cxx2cPapers.csv | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 6a836c0491bb6..ce57d21f9aed8 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -102,7 +102,7 @@
 "`LWG4141 <https://wg21.link/LWG4141>`__","Improve prohibitions on ""additional storage""","2024-11 (Wrocław)","","","`#118357 <https://github.com/llvm/llvm-project/issues/118357>`__",""
 "`LWG4142 <https://wg21.link/LWG4142>`__","``format_parse_context::check_dynamic_spec`` should require at least one type","2024-11 (Wrocław)","","","`#118358 <https://github.com/llvm/llvm-project/issues/118358>`__",""
 "`LWG4144 <https://wg21.link/LWG4144>`__","Disallow ``unique_ptr<T&, D>``","2024-11 (Wrocław)","","","`#118359 <https://github.com/llvm/llvm-project/issues/118359>`__",""
-"`LWG4147 <https://wg21.link/LWG4147>`__","Precondition on ``inplace_vector::emplace``","2024-11 (Wrocław)","","","`#118361 <https://github.com/llvm/llvm-project/issues/118361>`__",""
+"`LWG4147 <https://wg21.link/LWG4147>`__","Precondition on ``inplace_vector::emplace``","2024-11 (Wrocław)","|Complete|","23","`#118361 <https://github.com/llvm/llvm-project/issues/118361>`__",""
 "`LWG4148 <https://wg21.link/LWG4148>`__","``unique_ptr::operator*`` should not allow dangling references","2024-11 (Wrocław)","","","`#118362 <https://github.com/llvm/llvm-project/issues/118362>`__",""
 "`LWG4153 <https://wg21.link/LWG4153>`__","Fix extra ""-1"" for ``philox_engine::max()``","2024-11 (Wrocław)","","","`#118363 <https://github.com/llvm/llvm-project/issues/118363>`__",""
 "`LWG4154 <https://wg21.link/LWG4154>`__","The Mandates for ``std::packaged_task``'s constructor from a callable entity should consider decaying","2024-11 (Wrocław)","","","`#118364 <https://github.com/llvm/llvm-project/issues/118364>`__",""
@@ -271,11 +271,11 @@
 "`LWG3891 <https://wg21.link/LWG3891>`__","LWG3870 breaks ``std::expected<cv T, E>``","2026-03 (Croydon)","","","`#189813 <https://github.com/llvm/llvm-project/issues/189813>`__",""
 "`LWG4026 <https://wg21.link/LWG4026>`__","Assignment operators of ``std::expected`` should propagate triviality","2026-03 (Croydon)","","","`#189814 <https://github.com/llvm/llvm-project/issues/189814>`__",""
 "`LWG4090 <https://wg21.link/LWG4090>`__","Underspecified use of locale facets for locale-dependent ``std::format``","2026-03 (Croydon)","","","`#189815 <https://github.com/llvm/llvm-project/issues/189815>`__",""
-"`LWG4122 <https://wg21.link/LWG4122>`__","Ill-formed ``operator<=>`` can cause hard error when instantiating ``std::inplace_vector``","2026-03 (Croydon)","","","`#189816 <https://github.com/llvm/llvm-project/issues/189816>`__",""
+"`LWG4122 <https://wg21.link/LWG4122>`__","Ill-formed ``operator<=>`` can cause hard error when instantiating ``std::inplace_vector``","2026-03 (Croydon)","|Complete|","23","`#189816 <https://github.com/llvm/llvm-project/issues/189816>`__",""
 "`LWG4130 <https://wg21.link/LWG4130>`__","Preconditions for ``std::launder`` might be overly strict","2026-03 (Croydon)","","","`#189817 <https://github.com/llvm/llvm-project/issues/189817>`__",""
 "`LWG4133 <https://wg21.link/LWG4133>`__","``awaitable-receiver``'s members are potentially throwing","2026-03 (Croydon)","","","`#189818 <https://github.com/llvm/llvm-project/issues/189818>`__",""
 "`LWG4143 <https://wg21.link/LWG4143>`__","``execution::set_value/set_error/set_stopped/start`` should always return void","2026-03 (Croydon)","","","`#189819 <https://github.com/llvm/llvm-project/issues/189819>`__",""
-"`LWG4151 <https://wg21.link/LWG4151>`__","Precondition of ``inplace_vector::swap``","2026-03 (Croydon)","","","`#189820 <https://github.com/llvm/llvm-project/issues/189820>`__",""
+"`LWG4151 <https://wg21.link/LWG4151>`__","Precondition of ``inplace_vector::swap``","2026-03 (Croydon)","|Complete|","23","`#189820 <https://github.com/llvm/llvm-project/issues/189820>`__",""
 "`LWG4223 <https://wg21.link/LWG4223>`__","Deduction guides for maps are mishandling tuples and references","2026-03 (Croydon)","","","`#189821 <https://github.com/llvm/llvm-project/issues/189821>`__",""
 "`LWG4259 <https://wg21.link/LWG4259>`__","P1148R0 changed the return values of searching functions of ``std::basic_string`` on some platforms","2026-03 (Croydon)","","","`#189822 <https://github.com/llvm/llvm-project/issues/189822>`__",""
 "`LWG4290 <https://wg21.link/LWG4290>`__","Missing *Mandates* clauses on ``is_sufficiently_aligned``","2026-03 (Croydon)","","","`#189823 <https://github.com/llvm/llvm-project/issues/189823>`__",""
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 337a28eae5889..886ec17b167cd 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -69,7 +69,7 @@
 "`P3168R2 <https://wg21.link/P3168R2>`__","Give ``std::optional`` Range Support","2024-06 (St. Louis)","|Complete|","22","`#105430 <https://github.com/llvm/llvm-project/issues/105430>`__",""
 "`P3217R0 <https://wg21.link/P3217R0>`__","Adjoints to 'Enabling list-initialization for algorithms': find_last","2024-06 (St. Louis)","","","`#105431 <https://github.com/llvm/llvm-project/issues/105431>`__",""
 "`P2985R0 <https://wg21.link/P2985R0>`__","A type trait for detecting virtual base classes","2024-06 (St. Louis)","|Complete|","20","`#105432 <https://github.com/llvm/llvm-project/issues/105432>`__",""
-"`P0843R14 <https://wg21.link/P0843R14>`__","``inplace_vector``","2024-06 (St. Louis)","|Partial|","23","`#105433 <https://github.com/llvm/llvm-project/issues/105433>`__","inplace_vector<T,N> where T is not a trivial type cannot be used in a constant expression."
+"`P0843R14 <https://wg21.link/P0843R14>`__","``inplace_vector``","2024-06 (St. Louis)","|Complete|","23","`#105433 <https://github.com/llvm/llvm-project/issues/105433>`__",""
 "`P3235R3 <https://wg21.link/P3235R3>`__","``std::print`` more types faster with less memory","2024-06 (St. Louis)","","","`#105435 <https://github.com/llvm/llvm-project/issues/105435>`__",""
 "`P2968R2 <https://wg21.link/P2968R2>`__","Make ``std::ignore`` a first-class object","2024-06 (St. Louis)","|Complete|","19","`#105436 <https://github.com/llvm/llvm-project/issues/105436>`__",""
 "`P2075R6 <https://wg21.link/P2075R6>`__","Philox as an extension of the C++ RNG engines","2024-06 (St. Louis)","","","`#105437 <https://github.com/llvm/llvm-project/issues/105437>`__",""

>From 5b497f3c240609548428e90dca47fa3364c63354 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Wed, 17 Jun 2026 23:21:03 -0400
Subject: [PATCH 08/11] Address more code-related comments

---
 libcxx/include/inplace_vector                 | 148 +++++++-----------
 .../assert.zero_capacity.pass.cpp             |  26 +--
 2 files changed, 72 insertions(+), 102 deletions(-)

diff --git a/libcxx/include/inplace_vector b/libcxx/include/inplace_vector
index f9ad3022c8654..1c792c9dc8c4c 100644
--- a/libcxx/include/inplace_vector
+++ b/libcxx/include/inplace_vector
@@ -163,11 +163,11 @@ _LIBCPP_PUSH_MACROS
 #  include <__undef_macros>
 
 #  if _LIBCPP_STD_VER >= 26
+#    include <__algorithm/equal.h>
 #    include <__algorithm/fill_n.h>
 #    include <__algorithm/lexicographical_compare_three_way.h>
 #    include <__algorithm/min.h>
 #    include <__algorithm/move.h>
-#    include <__algorithm/move_backward.h>
 #    include <__algorithm/ranges_copy.h>
 #    include <__algorithm/ranges_copy_n.h>
 #    include <__algorithm/remove.h>
@@ -217,7 +217,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Tp, size_t _Cap>
 class inplace_vector {
 private:
-  static constexpr decltype(auto) __get_size_type() {
+  static constexpr auto __get_size_type() {
     if constexpr (_Cap <= std::numeric_limits<unsigned char>::max() && sizeof(unsigned char) < sizeof(std::size_t))
       return static_cast<unsigned char>(0);
     else if constexpr (_Cap <= std::numeric_limits<unsigned short>::max() &&
@@ -238,24 +238,6 @@ private:
   };
   __size_type __size_{0};
 
-  constexpr void __init() {
-    if consteval {
-      if constexpr (is_trivially_copyable_v<_Tp> && is_trivially_default_constructible_v<_Tp> &&
-                    is_trivially_assignable_v<_Tp&, _Tp>) {
-        for (size_t __i{0}; __i < _Cap; ++__i) {
-          __elems_[__i] = _Tp();
-        }
-      } else {
-#    if !defined(__cpp_trivial_union)
-        // TODO: Clang emits a -Wformat-security warning for this when it's in a consteval block. File bug for this
-        _LIBCPP_VERBOSE_ABORT("%s",
-                              "std::inplace_vector<T,N> currently cannot be used in constant expressions for "
-                              "non-trivial T on compilers where P3074 is not implemented.");
-#    endif
-      }
-    }
-  }
-
 public:
   using value_type      = _Tp;
   using pointer         = _Tp*;
@@ -275,33 +257,6 @@ public:
   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
 private:
-  struct _ConstructTransaction {
-    constexpr explicit _ConstructTransaction(inplace_vector& __v, size_type __n)
-        : __v_(__v), __pos_(__v.data() + __v.__size_), __new_end_(__v.data() + __v.__size_ + __n) {}
-
-    constexpr ~_ConstructTransaction() { __v_.__size_ = __pos_ - __v_.data(); }
-
-    inplace_vector& __v_;
-    pointer __pos_;
-    const_pointer const __new_end_;
-
-    _ConstructTransaction(_ConstructTransaction const&)            = delete;
-    _ConstructTransaction& operator=(_ConstructTransaction const&) = delete;
-  };
-
-  constexpr void __move_range(pointer __from_s, pointer __from_e, pointer __to) {
-    pointer __old_last  = data() + __size_;
-    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, ++__pos, __tx.__pos_ = __pos) {
-        std::construct_at(__pos, std::move(*__i));
-      }
-    }
-    std::move_backward(__from_s, __from_s + __n, __old_last);
-  }
-
   template <class _It, class _Sentinel>
   constexpr void __assign(_It __first, _Sentinel __last) {
     if constexpr (std::sized_sentinel_for<_Sentinel, _It>) {
@@ -317,7 +272,7 @@ private:
       }
       __size_ = __d;
     } else {
-      size_t __d = 0;
+      size_type __d = 0;
       for (; __first != __last && __d < __size_; (void)++__first, ++__d) {
         data()[__d] = *__first;
       }
@@ -385,17 +340,31 @@ private:
 
 public:
   // [inplace.vector.cons], construct/copy/destroy
-  constexpr inplace_vector() noexcept { __init(); }
+  constexpr inplace_vector() noexcept {
+    if consteval {
+      if constexpr (is_trivially_copyable_v<_Tp> && is_trivially_default_constructible_v<_Tp> &&
+                    is_trivially_assignable_v<_Tp&, _Tp>) {
+        for (size_t __i{0}; __i < _Cap; ++__i) {
+          __elems_[__i] = _Tp();
+        }
+      } else {
+#    if !defined(__cpp_trivial_union)
+        // TODO: Clang emits a -Wformat-security warning for this when it's in a consteval block. File bug for this
+        _LIBCPP_VERBOSE_ABORT("%s",
+                              "std::inplace_vector<T,N> currently cannot be used in constant expressions for "
+                              "non-trivial T on compilers where P3074 is not implemented.");
+#    endif
+      }
+    }
+  }
 
-  constexpr explicit inplace_vector(size_type __n) {
-    __init();
+  constexpr explicit inplace_vector(size_type __n) : inplace_vector() {
     reserve(__n);
     std::uninitialized_value_construct_n(data(), __n);
     __size_ = __n;
   }
 
-  constexpr inplace_vector(size_type __n, const _Tp& __c) {
-    __init();
+  constexpr inplace_vector(size_type __n, const _Tp& __c) : inplace_vector() {
     reserve(__n);
     std::uninitialized_fill_n(data(), __n, __c);
     __size_ = __n;
@@ -403,8 +372,7 @@ public:
 
   template <class _InputIterator>
     requires __has_input_iterator_category<_InputIterator>::value
-  constexpr inplace_vector(_InputIterator __first, _InputIterator __last) {
-    __init();
+  constexpr inplace_vector(_InputIterator __first, _InputIterator __last) : inplace_vector() {
     if constexpr (std::sized_sentinel_for<_InputIterator, _InputIterator>) {
       auto __n = std::ranges::distance(__first, __last);
       reserve(__n);
@@ -423,8 +391,7 @@ public:
   }
 
   template <_ContainerCompatibleRange<_Tp> _Range>
-  constexpr inplace_vector(from_range_t, _Range&& __rg) {
-    __init();
+  constexpr inplace_vector(from_range_t, _Range&& __rg) : inplace_vector() {
     append_range(__rg);
   }
 
@@ -432,8 +399,8 @@ public:
     requires is_trivially_copy_constructible_v<_Tp>
   = default;
 
-  constexpr inplace_vector(const inplace_vector& __x) noexcept(is_nothrow_copy_constructible_v<_Tp>) {
-    __init();
+  constexpr inplace_vector(const inplace_vector& __x) noexcept(is_nothrow_copy_constructible_v<_Tp>)
+      : inplace_vector() {
     std::uninitialized_copy(__x.begin(), __x.end(), data());
     __size_ = __x.size();
   }
@@ -442,14 +409,12 @@ public:
     requires is_trivially_move_constructible_v<_Tp>
   = default;
 
-  constexpr inplace_vector(inplace_vector&& __x) noexcept(is_nothrow_move_constructible_v<_Tp>) {
-    __init();
+  constexpr inplace_vector(inplace_vector&& __x) noexcept(is_nothrow_move_constructible_v<_Tp>) : inplace_vector() {
     std::uninitialized_move(__x.begin(), __x.end(), data());
     __size_ = __x.size();
   }
 
-  constexpr inplace_vector(std::initializer_list<_Tp> __il) {
-    __init();
+  constexpr inplace_vector(std::initializer_list<_Tp> __il) : inplace_vector() {
     reserve(__il.size());
     std::uninitialized_copy(__il.begin(), __il.end(), data());
     __size_ = __il.size();
@@ -690,11 +655,9 @@ public:
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
         size() < capacity(),
         "inplace_vector<T,N>::unchecked_emplace_back(Args...): Adding element when size() >= capacity()");
-    {
-      _ConstructTransaction __tx(*this, 1);
-      std::construct_at(data() + __size_, std::forward<_Args>(__args)...);
-      __tx.__pos_++;
-    }
+
+    std::construct_at(data() + __size_, std::forward<_Args>(__args)...);
+    ++__size_;
 
     return back();
   }
@@ -713,9 +676,9 @@ public:
     if (__position == end()) {
       emplace_back(std::forward<_Args>(__args)...);
     } else {
-      _Tp __temp_value = _Tp(std::forward<_Args>(__args)...);
-      __move_range(__p, data() + __size_, __p + 1);
-      *__p = std::move(__temp_value);
+      std::construct_at(data() + __size_, std::forward<_Args>(__args)...);
+      __size_++;
+      std::rotate(__p, data() + __size_ - 1, data() + __size_);
     }
 
     return __make_iter(__p);
@@ -757,7 +720,7 @@ public:
   }
 
   constexpr iterator insert(const_iterator __position, std::initializer_list<_Tp> __il) {
-    return __insert(__position, __il.begin(), __il.end());
+    return insert(__position, __il.begin(), __il.end());
   }
 
   constexpr iterator erase(const_iterator __position) {
@@ -809,16 +772,7 @@ public:
   }
 
   friend constexpr bool operator==(const inplace_vector& __x, const inplace_vector& __y) {
-    if (__x.size() != __y.size()) {
-      return false;
-    }
-
-    for (size_type __i{0}; __i < __x.size(); __i++) {
-      if (__x[__i] != __y[__i]) {
-        return false;
-      }
-    }
-    return true;
+    return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin(), __y.end());
   }
 
   friend constexpr auto operator<=>(const inplace_vector& __x, const inplace_vector& __y)
@@ -967,11 +921,13 @@ public:
 
   // element access
   [[nodiscard, noreturn]] constexpr reference operator[](size_type) {
-    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::operator[]: access with N == 0");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "inplace_vector<T,0>::operator[]: access with N == 0");
+    __libcpp_unreachable();
   }
 
   [[nodiscard, noreturn]] constexpr const_reference operator[](size_type) const {
-    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::operator[] const: access with N == 0");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "inplace_vector<T,0>::operator[] const: access with N == 0");
+    __libcpp_unreachable();
   }
 
   [[nodiscard, noreturn]] constexpr reference at(size_type) {
@@ -983,19 +939,23 @@ public:
   }
 
   [[nodiscard, noreturn]] constexpr reference front() {
-    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::front(): access with N == 0");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "inplace_vector<T,0>::front(): access with N == 0");
+    __libcpp_unreachable();
   }
 
   [[nodiscard, noreturn]] constexpr const_reference front() const {
-    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::front() const: access with N == 0");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "inplace_vector<T,0>::front() const: access with N == 0");
+    __libcpp_unreachable();
   }
 
   [[nodiscard, noreturn]] constexpr reference back() {
-    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::back(): access with N == 0");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "inplace_vector<T,0>::back(): access with N == 0");
+    __libcpp_unreachable();
   }
 
   [[nodiscard, noreturn]] constexpr const_reference back() const {
-    _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::back() const: access with N == 0");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "inplace_vector<T,0>::back() const: access with N == 0");
+    __libcpp_unreachable();
   }
 
   // [inplace.vector.data], data access
@@ -1019,7 +979,10 @@ public:
     }
   }
 
-  constexpr void pop_back() { _LIBCPP_VERBOSE_ABORT("inplace_vector<T,0>::pop_back(): use with N == 0"); }
+  constexpr void pop_back() {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "inplace_vector<T,0>::pop_back(): use with N == 0");
+    __libcpp_unreachable();
+  }
 
   template <class... _Args>
   [[nodiscard]] constexpr optional<reference> try_emplace_back(_Args&&...) {
@@ -1073,12 +1036,15 @@ public:
   }
 
   [[noreturn]] constexpr iterator erase(const_iterator) {
-    _LIBCPP_VERBOSE_ABORT("std::inplace_vector<T,0>::erase(const_iterator): use with N == 0");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "inplace_vector<T,0>::erase(): use with N == 0");
+    __libcpp_unreachable();
   }
 
   constexpr iterator erase(const_iterator __f, const_iterator __l) {
     if (__f != __l) {
-      _LIBCPP_VERBOSE_ABORT("std::inplace_vector<T,0>::erase(const_iterator, const_iterator): use with N == 0");
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+          false, "inplace_vector<T,0>::erase(const_iterator, const_iterator): use with N == 0");
+      __libcpp_unreachable();
     }
 
     return begin();
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
index 7a1419c27c79c..25947cf4c0040 100644
--- a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
@@ -7,12 +7,11 @@
 //===----------------------------------------------------------------------===//
 
 // REQUIRES: has-unix-headers, std-at-least-c++26
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
 
 // <inplace_vector>
 
-// No member named 'regex'.
-// XFAIL: LLVM-LIBC-FIXME
-
 #include <inplace_vector>
 #include <utility>
 
@@ -21,14 +20,19 @@
 int main(int, char**) {
   std::inplace_vector<int, 0> c;
 
-  EXPECT_ANY_DEATH((void)c[0]);
-  EXPECT_ANY_DEATH((void)c.front());
-  EXPECT_ANY_DEATH((void)c.back());
-  EXPECT_ANY_DEATH(c.pop_back());
-  EXPECT_ANY_DEATH(c.erase(c.begin()));
-  EXPECT_ANY_DEATH((void)std::as_const(c)[0]);
-  EXPECT_ANY_DEATH((void)std::as_const(c).front());
-  EXPECT_ANY_DEATH((void)std::as_const(c).back());
+  TEST_LIBCPP_ASSERT_FAILURE((void)c[0], "inplace_vector<T,0>::operator[]: access with N == 0");
+  TEST_LIBCPP_ASSERT_FAILURE((void)std::as_const(c)[0], "inplace_vector<T,0>::operator[] const: access with N == 0");
+  TEST_LIBCPP_ASSERT_FAILURE((void)c.at(0), "inplace_vector<T,0>::at(size_type n): access with N == 0");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      (void)std::as_const(c).at(0), "inplace_vector<T,0>::at(size_type n) const: access with N == 0");
+  TEST_LIBCPP_ASSERT_FAILURE((void)c.front(), "inplace_vector<T,0>::front(): access with N == 0");
+  TEST_LIBCPP_ASSERT_FAILURE((void)std::as_const(c).front(), "inplace_vector<T,0>::front() const: access with N == 0");
+  TEST_LIBCPP_ASSERT_FAILURE((void)c.back(), "inplace_vector<T,0>::back(): access with N == 0");
+  TEST_LIBCPP_ASSERT_FAILURE((void)std::as_const(c).back(), "inplace_vector<T,0>::back() const: access with N == 0");
+  TEST_LIBCPP_ASSERT_FAILURE(c.pop_back(), "inplace_vector<T,0>::erase(): use with N == 0");
+  TEST_LIBCPP_ASSERT_FAILURE(c.erase(c.begin()), "inplace_vector<T,0>::erase(): use with N == 0");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      c.erase(c.begin(), c.begin() + 1), "inplace_vector<T,0>::erase(const_iterator, const_iterator): use with N == 0");
 
   return 0;
 }

>From ed7c23997de81dfe6d94028eed4d3ffc39418323 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Thu, 18 Jun 2026 00:11:08 -0400
Subject: [PATCH 09/11] Clean up unused std::swap

---
 libcxx/include/inplace_vector | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libcxx/include/inplace_vector b/libcxx/include/inplace_vector
index 1c792c9dc8c4c..e5d54b0c64bcc 100644
--- a/libcxx/include/inplace_vector
+++ b/libcxx/include/inplace_vector
@@ -758,7 +758,6 @@ public:
     std::swap_ranges(__smaller.begin(), __smaller.end(), __bigger.begin());
 
     if (__n1 != __n2) {
-      using std::swap;
       std::uninitialized_move(__bigger.data() + __n1, __bigger.data() + __n2, __smaller.data() + __n1);
       __smaller.__size_ = __n2;
       std::destroy(__bigger.data() + __n1, __bigger.data() + __n2);

>From 8bac69d3d514b8e234a1c25f16907f4eb7152bea Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Thu, 18 Jun 2026 00:16:17 -0400
Subject: [PATCH 10/11] Add hardening asserts for erase() like in vector

---
 libcxx/include/inplace_vector                 |  5 ++++
 .../inplace_vector/assert.erase.pass.cpp      | 28 +++++++++++++++++++
 2 files changed, 33 insertions(+)
 create mode 100644 libcxx/test/libcxx/containers/sequences/inplace_vector/assert.erase.pass.cpp

diff --git a/libcxx/include/inplace_vector b/libcxx/include/inplace_vector
index e5d54b0c64bcc..160265fd06a8c 100644
--- a/libcxx/include/inplace_vector
+++ b/libcxx/include/inplace_vector
@@ -724,6 +724,9 @@ public:
   }
 
   constexpr iterator erase(const_iterator __position) {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __position != end(), "inplace_vector<T,N>::erase(iterator) called with a non-dereferenceable iterator");
+
     pointer __pos = data() + (__position - cbegin());
 
     std::move(__pos + 1, data() + __size_, __pos);
@@ -733,6 +736,8 @@ public:
   }
 
   constexpr iterator erase(const_iterator __first, const_iterator __last) {
+    _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+        __first <= __last, "inplace_vector<T,N>::erase(first, last) called with invalid range");
     __size_type __x = __last - __first;
     pointer __pos   = data() + (__first - cbegin());
 
diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.erase.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.erase.pass.cpp
new file mode 100644
index 0000000000000..87df7d8fc2464
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.erase.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers, std-at-least-c++26
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <inplace_vector>
+
+#include <inplace_vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::inplace_vector<int, 2> v{1, 2};
+
+  TEST_LIBCPP_ASSERT_FAILURE(
+      v.erase(v.end()), "inplace_vector<T,N>::erase(iterator) called with a non-dereferenceable iterator");
+  TEST_LIBCPP_ASSERT_FAILURE(
+      v.erase(v.end(), v.begin()), "inplace_vector<T,N>::erase(first, last) called with invalid range");
+
+  return 0;
+}

>From 7eff88b82d385af0dd46f31ccac312fd773f6313 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Thu, 18 Jun 2026 01:55:24 -0400
Subject: [PATCH 11/11] Remove at from assert test

---
 .../sequences/inplace_vector/assert.zero_capacity.pass.cpp     | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
index 25947cf4c0040..b765a0d367a96 100644
--- a/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
+++ b/libcxx/test/libcxx/containers/sequences/inplace_vector/assert.zero_capacity.pass.cpp
@@ -22,9 +22,6 @@ int main(int, char**) {
 
   TEST_LIBCPP_ASSERT_FAILURE((void)c[0], "inplace_vector<T,0>::operator[]: access with N == 0");
   TEST_LIBCPP_ASSERT_FAILURE((void)std::as_const(c)[0], "inplace_vector<T,0>::operator[] const: access with N == 0");
-  TEST_LIBCPP_ASSERT_FAILURE((void)c.at(0), "inplace_vector<T,0>::at(size_type n): access with N == 0");
-  TEST_LIBCPP_ASSERT_FAILURE(
-      (void)std::as_const(c).at(0), "inplace_vector<T,0>::at(size_type n) const: access with N == 0");
   TEST_LIBCPP_ASSERT_FAILURE((void)c.front(), "inplace_vector<T,0>::front(): access with N == 0");
   TEST_LIBCPP_ASSERT_FAILURE((void)std::as_const(c).front(), "inplace_vector<T,0>::front() const: access with N == 0");
   TEST_LIBCPP_ASSERT_FAILURE((void)c.back(), "inplace_vector<T,0>::back(): access with N == 0");



More information about the libcxx-commits mailing list