[libcxx-commits] [libcxx] [libc++] Optimize vector::erase (PR #213916)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Aug 12 07:48:24 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

<details>
<summary>Changes</summary>



---

Patch is 31.19 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/213916.diff


21 Files Affected:

- (modified) libcxx/include/CMakeLists.txt (+1-1) 
- (modified) libcxx/include/__expected/expected.h (+1-1) 
- (modified) libcxx/include/__memory/uninitialized_algorithms.h (+41-3) 
- (modified) libcxx/include/__memory/unique_ptr.h (+1-1) 
- (modified) libcxx/include/__optional/optional.h (+1-1) 
- (modified) libcxx/include/__optional/optional_ref.h (+1-1) 
- (modified) libcxx/include/__split_buffer (+1-1) 
- (renamed) libcxx/include/__type_traits/is_relocatable.h (+10-3) 
- (modified) libcxx/include/__utility/pair.h (+1-1) 
- (modified) libcxx/include/__vector/layout.h (+20-6) 
- (modified) libcxx/include/__vector/vector.h (+53-28) 
- (modified) libcxx/include/array (+1-1) 
- (modified) libcxx/include/deque (+1-1) 
- (modified) libcxx/include/module.modulemap.in (+4-4) 
- (modified) libcxx/include/string (+1-1) 
- (modified) libcxx/include/tuple (+1-1) 
- (modified) libcxx/include/variant (+1-1) 
- (modified) libcxx/test/libcxx/type_traits/is_trivially_relocatable.compile.pass.cpp (+1-1) 
- (modified) libcxx/test/std/containers/sequences/vector/vector.modifiers/common.h (+13-4) 
- (modified) libcxx/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp (+44-25) 
- (modified) libcxx/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp (+45-26) 


``````````diff
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index dc1d8bb26bac4..1d81578a3c56d 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -895,6 +895,7 @@ set(files
   __type_traits/is_polymorphic.h
   __type_traits/is_reference.h
   __type_traits/is_reference_wrapper.h
+  __type_traits/is_relocatable.h
   __type_traits/is_same.h
   __type_traits/is_scalar.h
   __type_traits/is_signed.h
@@ -907,7 +908,6 @@ set(files
   __type_traits/is_trivially_copyable.h
   __type_traits/is_trivially_destructible.h
   __type_traits/is_trivially_lexicographically_comparable.h
-  __type_traits/is_trivially_relocatable.h
   __type_traits/is_union.h
   __type_traits/is_unqualified.h
   __type_traits/is_unsigned.h
diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h
index 987ccf628c814..5588196939738 100644
--- a/libcxx/include/__expected/expected.h
+++ b/libcxx/include/__expected/expected.h
@@ -31,11 +31,11 @@
 #include <__type_traits/is_nothrow_assignable.h>
 #include <__type_traits/is_nothrow_constructible.h>
 #include <__type_traits/is_reference.h>
+#include <__type_traits/is_relocatable.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/is_swappable.h>
 #include <__type_traits/is_trivially_constructible.h>
 #include <__type_traits/is_trivially_destructible.h>
-#include <__type_traits/is_trivially_relocatable.h>
 #include <__type_traits/is_void.h>
 #include <__type_traits/negation.h>
 #include <__type_traits/remove_cv.h>
diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h
index e1c6fe25040ea..ad44dea679f98 100644
--- a/libcxx/include/__memory/uninitialized_algorithms.h
+++ b/libcxx/include/__memory/uninitialized_algorithms.h
@@ -26,10 +26,10 @@
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_constant_evaluated.h>
 #include <__type_traits/is_reference.h>
+#include <__type_traits/is_relocatable.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/is_trivially_assignable.h>
 #include <__type_traits/is_trivially_constructible.h>
-#include <__type_traits/is_trivially_relocatable.h>
 #include <__type_traits/remove_const.h>
 #include <__utility/exception_guard.h>
 #include <__utility/move.h>
@@ -176,7 +176,7 @@ uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __las
 template <class _ValueType, class _ForwardIterator, class _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
 __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
-  auto __idx = __first;
+  auto __idx   = __first;
   auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
   for (; __n > 0; ++__idx, (void)--__n)
     ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType;
@@ -218,7 +218,7 @@ uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last)
 template <class _ValueType, class _ForwardIterator, class _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
 __uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
-  auto __idx = __first;
+  auto __idx   = __first;
   auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
   for (; __n > 0; ++__idx, (void)--__n)
     ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType();
@@ -431,6 +431,44 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __uninitialized_allocat
   }
 }
 
+// __uninitialized_allocator_relocate_forward relocates the objects in [__first, __last) into __result
+// element-by-element from __first to __last. Relocation means that the objects in [__first, __last) are placed into
+// __result as-if by move-construct and destroy, except that the move constructor and destructor may never be called if
+// they are known to be equivalent to a memcpy.
+//
+// Preconditions:  At __result there is no object and [__first, __last) contains objects
+// Postconditions: __result contains the objects from [__first, __last) and
+//                 [__first, __last) doesn't contain any objects
+//
+// The strong exception guarantee is provided.
+template <class _Alloc, class _ContiguousIterator>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __uninitialized_allocator_relocate_forward(
+    _Alloc& __alloc, _ContiguousIterator __first, _ContiguousIterator __last, _ContiguousIterator __result) {
+  static_assert(__libcpp_is_contiguous_iterator<_ContiguousIterator>::value, "");
+  using _ValueType = typename iterator_traits<_ContiguousIterator>::value_type;
+  static_assert(
+      __is_nothrow_relocatable_v<_ValueType> && __allocator_has_trivial_move_construct_v<_Alloc, _ValueType> &&
+      __allocator_has_trivial_destroy_v<_Alloc, _ValueType>);
+  if (__libcpp_is_constant_evaluated() || !__is_trivially_relocatable_v<_ValueType>) {
+    auto __iter = __first;
+    while (__iter != __last) {
+#if _LIBCPP_HAS_EXCEPTIONS
+      allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__result), std::move_if_noexcept(*__iter));
+#else
+      allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__result), std::move(*__iter));
+#endif
+      std::__destroy_at(std::__to_address(__iter));
+      ++__iter;
+      ++__result;
+    }
+  } else {
+    // Casting to void* to suppress clang complaining that this is technically UB.
+    __builtin_memmove(static_cast<void*>(std::__to_address(__result)),
+                      std::__to_address(__first),
+                      sizeof(_ValueType) * (__last - __first));
+  }
+}
+
 _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 63f62137ed8a2..acece3ae61f1d 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -37,9 +37,9 @@
 #include <__type_traits/is_function.h>
 #include <__type_traits/is_pointer.h>
 #include <__type_traits/is_reference.h>
+#include <__type_traits/is_relocatable.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/is_swappable.h>
-#include <__type_traits/is_trivially_relocatable.h>
 #include <__type_traits/is_void.h>
 #include <__type_traits/remove_extent.h>
 #include <__type_traits/remove_reference.h>
diff --git a/libcxx/include/__optional/optional.h b/libcxx/include/__optional/optional.h
index 8d6a9fbed8599..101db832023f1 100644
--- a/libcxx/include/__optional/optional.h
+++ b/libcxx/include/__optional/optional.h
@@ -40,13 +40,13 @@
 #include <__type_traits/is_nothrow_constructible.h>
 #include <__type_traits/is_object.h>
 #include <__type_traits/is_reference.h>
+#include <__type_traits/is_relocatable.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/is_scalar.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_destructible.h>
-#include <__type_traits/is_trivially_relocatable.h>
 #include <__type_traits/negation.h>
 #include <__type_traits/remove_cv.h>
 #include <__type_traits/remove_cvref.h>
diff --git a/libcxx/include/__optional/optional_ref.h b/libcxx/include/__optional/optional_ref.h
index d137b3c40c7e6..c1bbe622891d5 100644
--- a/libcxx/include/__optional/optional_ref.h
+++ b/libcxx/include/__optional/optional_ref.h
@@ -31,8 +31,8 @@
 #include <__type_traits/is_nothrow_constructible.h>
 #include <__type_traits/is_object.h>
 #include <__type_traits/is_reference.h>
+#include <__type_traits/is_relocatable.h>
 #include <__type_traits/is_same.h>
-#include <__type_traits/is_trivially_relocatable.h>
 #include <__type_traits/reference_constructs_from_temporary.h>
 #include <__type_traits/remove_cv.h>
 #include <__type_traits/remove_cvref.h>
diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer
index 59cee84536069..d89264186d77e 100644
--- a/libcxx/include/__split_buffer
+++ b/libcxx/include/__split_buffer
@@ -31,9 +31,9 @@
 #include <__type_traits/integral_constant.h>
 #include <__type_traits/is_nothrow_assignable.h>
 #include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_relocatable.h>
 #include <__type_traits/is_swappable.h>
 #include <__type_traits/is_trivially_destructible.h>
-#include <__type_traits/is_trivially_relocatable.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
 
diff --git a/libcxx/include/__type_traits/is_trivially_relocatable.h b/libcxx/include/__type_traits/is_relocatable.h
similarity index 80%
rename from libcxx/include/__type_traits/is_trivially_relocatable.h
rename to libcxx/include/__type_traits/is_relocatable.h
index 11d7d5c153678..e9b6ab53e9047 100644
--- a/libcxx/include/__type_traits/is_trivially_relocatable.h
+++ b/libcxx/include/__type_traits/is_relocatable.h
@@ -6,11 +6,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_RELOCATABLE_H
-#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_RELOCATABLE_H
+#ifndef _LIBCPP___TYPE_TRAITS_IS_RELOCATABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_RELOCATABLE_H
 
 #include <__config>
 #include <__type_traits/enable_if.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_nothrow_destructible.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/is_trivially_copyable.h>
 
@@ -43,6 +45,11 @@ inline const bool
         true;
 #endif
 
+template <class _Tp>
+inline const bool __is_nothrow_relocatable_v =
+    __is_trivially_relocatable_v<_Tp> ||
+    (is_nothrow_move_constructible<_Tp>::value && is_nothrow_destructible<_Tp>::value);
+
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_RELOCATABLE_H
+#endif // _LIBCPP___TYPE_TRAITS_IS_RELOCATABLE_H
diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h
index f9d4599a5068d..a65c178a9f036 100644
--- a/libcxx/include/__utility/pair.h
+++ b/libcxx/include/__utility/pair.h
@@ -31,8 +31,8 @@
 #include <__type_traits/is_implicitly_default_constructible.h>
 #include <__type_traits/is_nothrow_assignable.h>
 #include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_relocatable.h>
 #include <__type_traits/is_swappable.h>
-#include <__type_traits/is_trivially_relocatable.h>
 #include <__type_traits/nat.h>
 #include <__type_traits/unwrap_ref.h>
 #include <__utility/declval.h>
diff --git a/libcxx/include/__vector/layout.h b/libcxx/include/__vector/layout.h
index af03556dc2636..2d1a5f1be54d2 100644
--- a/libcxx/include/__vector/layout.h
+++ b/libcxx/include/__vector/layout.h
@@ -114,12 +114,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Tp, class _Allocator>
 class __vector_layout {
 public:
-  using value_type _LIBCPP_NODEBUG     = _Tp;
-  using allocator_type _LIBCPP_NODEBUG = _Allocator;
-  using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
-  using size_type _LIBCPP_NODEBUG      = typename __alloc_traits::size_type;
-  using pointer _LIBCPP_NODEBUG        = typename __alloc_traits::pointer;
-  using const_pointer _LIBCPP_NODEBUG  = typename __alloc_traits::const_pointer;
+  using value_type _LIBCPP_NODEBUG      = _Tp;
+  using allocator_type _LIBCPP_NODEBUG  = _Allocator;
+  using __alloc_traits _LIBCPP_NODEBUG  = allocator_traits<allocator_type>;
+  using size_type _LIBCPP_NODEBUG       = typename __alloc_traits::size_type;
+  using difference_type _LIBCPP_NODEBUG = typename __alloc_traits::difference_type;
+  using pointer _LIBCPP_NODEBUG         = typename __alloc_traits::pointer;
+  using const_pointer _LIBCPP_NODEBUG   = typename __alloc_traits::const_pointer;
 #ifdef _LIBCPP_ABI_VECTOR_LAYOUT_SIZE_BASED
   using _SplitBuffer _LIBCPP_NODEBUG = __split_buffer<_Tp, _Allocator, __split_buffer_size_layout>;
   using __bound_type _LIBCPP_NODEBUG = size_type;
@@ -206,6 +207,8 @@ class __vector_layout {
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer __capacity_ptr() const _NOEXCEPT;
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const _NOEXCEPT;
 
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 void __offset_size(difference_type __offset) _NOEXCEPT;
+
 private:
   pointer __begin_ = nullptr;
 
@@ -349,6 +352,11 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __vector_layout<_Tp, _Alloc>::__invariants()
     return __size_ == 0 && __capacity_ == 0;
   return __size_ <= __capacity_;
 }
+
+template <class _Tp, class _Alloc>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void __vector_layout<_Tp, _Alloc>::__offset_size(difference_type __offset) _NOEXCEPT {
+  __size_ += __offset;
+}
 #else  // !defined(_LIBCPP_ABI_VECTOR_LAYOUT_SIZE_BASED)
 template <class _Tp, class _Alloc>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 __vector_layout<_Tp, _Alloc>::__vector_layout(__vector_layout&& __other)
@@ -470,6 +478,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __vector_layout<_Tp, _Alloc>::__invariants()
     return false;
   return __end_ <= __capacity_;
 }
+
+template <class _Tp, class _Alloc>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void __vector_layout<_Tp, _Alloc>::__offset_size(difference_type __offset) _NOEXCEPT {
+  __end_ += __offset;
+}
+
 #endif // _LIBCPP_ABI_VECTOR_LAYOUT_SIZE_BASED
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 6297d1952e3c6..9f489c2b6c575 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -36,6 +36,7 @@
 #include <__memory/allocator.h>
 #include <__memory/allocator_traits.h>
 #include <__memory/compressed_pair.h>
+#include <__memory/construct_at.h>
 #include <__memory/noexcept_move_assign_container.h>
 #include <__memory/pointer_traits.h>
 #include <__memory/swap_allocator.h>
@@ -55,9 +56,9 @@
 #include <__type_traits/is_nothrow_assignable.h>
 #include <__type_traits/is_nothrow_constructible.h>
 #include <__type_traits/is_pointer.h>
+#include <__type_traits/is_relocatable.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/is_swappable.h>
-#include <__type_traits/is_trivially_relocatable.h>
 #include <__type_traits/type_identity.h>
 #include <__utility/declval.h>
 #include <__utility/exception_guard.h>
@@ -552,8 +553,32 @@ class vector {
   }
 #endif
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position);
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position) {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator");
+    return erase(__position, __position + 1);
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last) {
+    _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range");
+    pointer __pos    = this->__layout_.__begin_ptr() + (__first - begin());
+    auto __hole_size = __last - __first;
+    if (__first != __last) {
+#ifndef _LIBCPP_CXX03_LANG
+      if constexpr (__is_nothrow_relocatable_v<value_type> &&
+                    __allocator_has_trivial_move_construct_v<allocator_type, value_type> &&
+                    __allocator_has_trivial_destroy_v<allocator_type, value_type>) {
+        auto __raw_pos = std::__to_address(__pos);
+        std::__destroy_at(__raw_pos);
+        std::__uninitialized_allocator_relocate_forward(
+            __layout_.__alloc(), __raw_pos + __hole_size, std::__to_address(__layout_.__end_ptr()), __raw_pos);
+        __layout_.__offset_size(-__hole_size);
+      } else
+#endif
+        this->__destruct_at_end(std::move(__pos + __hole_size, __layout_.__end_ptr(), __pos));
+    }
+    return __make_iter(__pos);
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
     size_type __old_size = size();
@@ -1014,9 +1039,31 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::assign(size_type __n
 
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::reserve(size_type __n) {
-  if (__n > capacity()) {
-    if (__n > max_size())
-      this->__throw_length_error();
+  if (__n <= capacity())
+    return;
+
+  if (__n > max_size())
+    this->__throw_length_error();
+
+#ifndef _LIBCPP_CXX03_LANG
+  if constexpr (__is_nothrow_relocatable_v<_Tp>) {
+    auto& __alloc     = __layout_.__alloc();
+    auto __allocation = std::__allocate_at_least(__alloc, __n);
+    auto __old_alloc  = __layout_.__begin_ptr();
+    auto __size       = size();
+    auto __old_cap    = capacity();
+
+    __layout_.__set_layout(__allocation.ptr, __size, __allocation.count);
+    std::__uninitialized_allocator_relocate(
+        __alloc,
+        std::__to_address(__old_alloc),
+        std::__to_address(__old_alloc) + __size,
+        std::__to_address(__allocation.ptr));
+    if (__old_alloc)
+      __alloc_traits::deallocate(__alloc, __old_alloc, __old_cap);
+  } else
+#endif
+  {
     _SplitBuffer __v(__n, size(), this->__layout_.__alloc());
     __layout_.__relocate(__v);
   }
@@ -1091,28 +1138,6 @@ vector<_Tp, _Alloc>::emplace_back(_Args&&... __args) {
 #endif
 }
 
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
-vector<_Tp, _Allocator>::erase(const_iterator __position) {
-  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
-      __position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator");
-  difference_type __ps = __position - cbegin();
-  pointer __p          = this->__layout_.__begin_ptr() + __ps;
-  this->__destruct_at_end(std::move(__p + 1, __layout_.__end_ptr(), __p));
-  return __make_iter(__p);
-}
-
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
-vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) {
-  _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range");
-  pointer __p = this->__layout_.__begin_ptr() + (__first - begin());
-  if (__first != __last) {
-    this->__destruct_at_end(std::move(__p + (__last - __first), __layout_.__end_ptr(), __p));
-  }
-  return __make_iter(__p);
-}
-
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to) {
diff --git a/libcxx/include/array b/libcxx/include/array
index 851a220e87398..470e268e75466 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -134,9 +134,9 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
 #  include <__type_traits/is_const.h>
 #  include <__type_traits/is_constructible.h>
 #  include <__type_traits/is_nothrow_constructible.h>
+#  include <__type_traits/is_relocatable.h>
 #  include <__type_traits/is_same.h>
 #  include <__type_traits/is_swappable.h>
-#  include <__type_traits/is_trivially_relocatable.h>
 #  include <__type_traits/remove_cv.h>
 #  include <__utility/empty.h>
 #  include <__utility/integer_sequence.h>
diff --git a/libcxx/include/deque b/libcxx/include/deque
index 5ef019e0c65f3..9fef85240fd25 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -228,9 +228,9 @@ template <class T, class Allocator, class Predicate>
 #  include <__type_traits/is_convertible.h>
 #  include <__type_traits/is_nothrow_assignable.h>
 #  include <__type_traits/is_nothrow_constructible.h>
+#  include <__type_traits/is_relocatable.h>
 #  include <__type_traits/is_same.h>
 #  include <__type_traits/is_swappable.h>
-#  include <__type_traits/is_trivially_relocatable.h>
 #  include <__type_traits/type_identity.h>
 #  include <__utility/exception_guard.h>
 #  include <__utility/forward.h>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index f56d48784737b..03725562a5c68 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -263,6 +263,10 @@ module std_core {
       header "__type_traits/is_reference.h"
       export std_core.type_traits.integral_constant
     }
+    module is_relocatable {
+      header "__type_traits/is_relocatable.h"
+      export s...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/213916


More information about the libcxx-commits mailing list