[libcxx-commits] [PATCH] D147741: [libc++, std::vector] call the optimized version of __uninitialized_allocator_copy for trivial types
Aditya Kumar via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Apr 20 15:27:45 PDT 2023
hiraditya updated this revision to Diff 515506.
hiraditya retitled this revision from "[libc++] unwrap iterator parameters to __uninitialized_allocator_copy before calling std::copy" to "[libc++, std::vector] call the optimized version of __uninitialized_allocator_copy for trivial types".
hiraditya edited the summary of this revision.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D147741/new/
https://reviews.llvm.org/D147741
Files:
libcxx/include/__memory/uninitialized_algorithms.h
libcxx/include/vector
Index: libcxx/include/vector
===================================================================
--- libcxx/include/vector
+++ libcxx/include/vector
@@ -310,7 +310,10 @@
#include <__type_traits/is_allocator.h>
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_trivially_copy_assignable.h>
+#include <__type_traits/is_trivially_copy_constructible.h>
#include <__type_traits/noexcept_move_assign_container.h>
+#include <__type_traits/remove_const.h>
#include <__type_traits/type_identity.h>
#include <__utility/exception_guard.h>
#include <__utility/forward.h>
@@ -1028,7 +1031,19 @@
vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n)
{
_ConstructTransaction __tx(*this, __n);
+#if _LIBCPP_STD_VER >= 17
+ using _RawType = __remove_const_t<_Tp>;
+ if constexpr(is_trivially_copy_constructible<_RawType>::value && is_trivially_copy_assignable<_RawType>::value &&
+ __allocator_has_trivial_copy_construct<_Allocator, _RawType>::value &&
+ is_same<pointer, _ForwardIterator>::value &&
+ is_same<std::allocator<_Tp>, _Allocator>::value)
+ __tx.__pos_ = std::__uninitialized_allocator_copy_opt(__alloc(), __first, __last, __tx.__pos_);
+ else
+ __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_);
+
+#else
__tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_);
+#endif
}
// Default constructs __n objects starting at __end_
Index: libcxx/include/__memory/uninitialized_algorithms.h
===================================================================
--- libcxx/include/__memory/uninitialized_algorithms.h
+++ libcxx/include/__memory/uninitialized_algorithms.h
@@ -586,6 +586,50 @@
}
}
+template <class _Alloc,
+ class _Type,
+ class _RawType = __remove_const_t<_Type>,
+ __enable_if_t<
+ // using _RawType because of the allocator<T const> extension
+ is_trivially_copy_constructible<_RawType>::value && is_trivially_copy_assignable<_RawType>::value &&
+ __allocator_has_trivial_copy_construct<_Alloc, _RawType>::value>* = nullptr>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type*
+__uninitialized_allocator_copy_opt(_Alloc&, const _Type* __first1, const _Type* __last1, _Type* __first2) {
+ // TODO: Remove the const_cast once we drop support for std::allocator<T const>
+ if (__libcpp_is_constant_evaluated()) {
+ while (__first1 != __last1) {
+ std::__construct_at(std::__to_address(__first2), *__first1);
+ ++__first1;
+ ++__first2;
+ }
+ return __first2;
+ } else {
+ return std::copy(__first1, __last1, const_cast<_RawType*>(__first2));
+ }
+}
+
+template <class _Alloc,
+ class _Type,
+ class _RawType = __remove_const_t<_Type>,
+ __enable_if_t<
+ // using _RawType because of the allocator<T const> extension
+ is_trivially_copy_constructible<_RawType>::value && is_trivially_copy_assignable<_RawType>::value &&
+ __allocator_has_trivial_copy_construct<_Alloc, _RawType>::value>* = nullptr>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type*
+__uninitialized_allocator_copy_opt(_Alloc&, _Type* __first1, _Type* __last1, _Type* __first2) {
+ // TODO: Remove the const_cast once we drop support for std::allocator<T const>
+ if (__libcpp_is_constant_evaluated()) {
+ while (__first1 != __last1) {
+ std::__construct_at(std::__to_address(__first2), *__first1);
+ ++__first1;
+ ++__first2;
+ }
+ return __first2;
+ } else {
+ return std::copy(__first1, __last1, const_cast<_RawType*>(__first2));
+ }
+}
+
// Move-construct the elements [__first1, __last1) into [__first2, __first2 + N)
// if the move constructor is noexcept, where N is distance(__first1, __last1).
//
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D147741.515506.patch
Type: text/x-patch
Size: 3979 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20230420/803f13e4/attachment-0001.bin>
More information about the libcxx-commits
mailing list