[libcxx-commits] [libcxx] 7a1f6ad - [libc++] Simplify allocator propagation in vector assignments (#217635)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Sep 2 07:22:53 PDT 2026
Author: Nikolas Klauser
Date: 2026-09-02T16:22:46+02:00
New Revision: 7a1f6ad89e574d638e4618f41f243c63da76ce7b
URL: https://github.com/llvm/llvm-project/commit/7a1f6ad89e574d638e4618f41f243c63da76ce7b
DIFF: https://github.com/llvm/llvm-project/commit/7a1f6ad89e574d638e4618f41f243c63da76ce7b.diff
LOG: [libc++] Simplify allocator propagation in vector assignments (#217635)
We can just use `if constexpr` instead of dispatching based on type
traits. This will cause some more code generation in C++03, but I don't
think we should care at this point.
Added:
Modified:
libcxx/include/__vector/vector.h
Removed:
################################################################################
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 42c571ccbe323..99d86fbb63e90 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -270,7 +270,24 @@ class _LIBCPP_WARN_UNUSED vector {
: __layout_(__a) {
__init_with_size(__x.__layout_.__begin_ptr(), __x.__layout_.__end_ptr(), __x.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector& operator=(const vector& __x);
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector& operator=(const vector& __other) {
+ if (this == std::addressof(__other))
+ return *this;
+
+ if _LIBCPP_CONSTEXPR (__alloc_traits::propagate_on_container_copy_assignment::value) {
+ if (this->__layout_.__alloc() != __other.__layout_.__alloc()) {
+ clear();
+ __annotate_delete();
+ __alloc_traits::deallocate(this->__layout_.__alloc(), this->__layout_.__begin_ptr(), capacity());
+ __layout_.__reset_without_allocator();
+ }
+ this->__layout_.__alloc() = __other.__layout_.__alloc();
+ }
+
+ assign(__other.__layout_.__begin_ptr(), __other.__layout_.__end_ptr());
+ return *this;
+ }
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(initializer_list<value_type> __il) {
@@ -298,9 +315,22 @@ class _LIBCPP_WARN_UNUSED vector {
_LIBCPP_CONSTEXPR_SINCE_CXX20
_LIBCPP_HIDE_FROM_ABI vector(vector&& __x, const __type_identity_t<allocator_type>& __a);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector& operator=(vector&& __x)
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector& operator=(vector&& __other)
_NOEXCEPT_(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value) {
- __move_assign(__x, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
+ if _LIBCPP_CONSTEXPR (__alloc_traits::propagate_on_container_move_assignment::value) {
+ __vdeallocate();
+ __layout_.__alloc() = std::move(__other.__layout_.__alloc());
+ } else {
+ if (__layout_.__alloc() != __other.__layout_.__alloc()) {
+ typedef move_iterator<iterator> _Ip;
+ assign(_Ip(__other.begin()), _Ip(__other.end()));
+ return *this;
+ }
+ __vdeallocate();
+ }
+
+ __layout_.__move_assign_without_allocator(__other.__layout_);
return *this;
}
@@ -742,10 +772,6 @@ class _LIBCPP_WARN_UNUSED vector {
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__move_range(pointer __from_s, pointer __from_e, pointer __to);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, true_type)
- _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, false_type)
- _NOEXCEPT_(__alloc_traits::is_always_equal::value);
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last) _NOEXCEPT {
size_type __old_size = size();
@@ -807,39 +833,10 @@ class _LIBCPP_WARN_UNUSED vector {
_ConstructTransaction& operator=(_ConstructTransaction const&) = delete;
};
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector& __c) {
- __copy_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>());
- }
-
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
- is_nothrow_move_assignable<allocator_type>::value) {
- __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
- }
-
[[__noreturn__]] _LIBCPP_HIDE_FROM_ABI static void __throw_length_error() { std::__throw_length_error("vector"); }
[[__noreturn__]] _LIBCPP_HIDE_FROM_ABI static void __throw_out_of_range() { std::__throw_out_of_range("vector"); }
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector& __c, true_type) {
- if (this->__layout_.__alloc() != __c.__layout_.__alloc()) {
- clear();
- __annotate_delete();
- __alloc_traits::deallocate(this->__layout_.__alloc(), this->__layout_.__begin_ptr(), capacity());
- __layout_.__reset_without_allocator();
- }
- this->__layout_.__alloc() = __c.__layout_.__alloc();
- }
-
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector&, false_type) {}
-
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c, true_type)
- _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
- this->__layout_.__alloc() = std::move(__c.__layout_.__alloc());
- }
-
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector&, false_type) _NOEXCEPT {}
-
template <class _Ptr = pointer, __enable_if_t<is_pointer<_Ptr>::value, int> = 0>
static _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Ptr
__add_alignment_assumption(_Ptr __p) _NOEXCEPT {
@@ -961,34 +958,6 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_
}
}
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type)
- _NOEXCEPT_(__alloc_traits::is_always_equal::value) {
- if (this->__layout_.__alloc() != __c.__layout_.__alloc()) {
- typedef move_iterator<iterator> _Ip;
- assign(_Ip(__c.begin()), _Ip(__c.end()));
- } else
- __move_assign(__c, true_type());
-}
-
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
- _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
- __vdeallocate();
- __move_assign_alloc(__c); // this can throw
- __layout_.__move_assign_without_allocator(__c.__layout_);
-}
-
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocator>&
-vector<_Tp, _Allocator>::operator=(const vector& __x) {
- if (this != std::addressof(__x)) {
- __copy_assign_alloc(__x);
- assign(__x.__layout_.__begin_ptr(), __x.__layout_.__end_ptr());
- }
- return *this;
-}
-
template <class _Tp, class _Allocator>
template <class _Iterator, class _Sentinel>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
More information about the libcxx-commits
mailing list