[libcxx-commits] [libcxx] [libc++] Optimize vector growing of trivially relocatable types (PR #76657)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jan 11 09:59:26 PST 2024


================
@@ -646,6 +647,25 @@ __uninitialized_allocator_move_if_noexcept(_Alloc&, _Iter1 __first1, _Iter1 __la
 }
 #endif // _LIBCPP_COMPILER_GCC
 
+template <class _Alloc, class _Tp>
+struct __allocator_has_trivial_destroy : _Not<__has_destroy<_Alloc, _Tp*>> {};
+
+template <class _Tp, class _Up>
+struct __allocator_has_trivial_destroy<allocator<_Tp>, _Up> : true_type {};
+
+template <class _Alloc, class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
+__uninitialized_allocator_relocate(_Alloc& __alloc, _Tp* __first, _Tp* __last, _Tp* __out) {
+  if (__libcpp_is_constant_evaluated() || !__libcpp_is_trivially_relocatable<_Tp>::value ||
+      !__allocator_has_trivial_move_construct<_Alloc, _Tp>::value ||
+      !__allocator_has_trivial_destroy<_Alloc, _Tp>::value) {
+    std::__uninitialized_allocator_move_if_noexcept(__alloc, __first, __last, __out);
+    std::__allocator_destroy(__alloc, __first, __last);
+  } else {
+    __builtin_memcpy(__out, __first, sizeof(_Tp) * (__last - __first));
----------------
ldionne wrote:

@mordante The semantics of `std::copy` are to copy the objects and create disjoint copies. That's not what we are after here. What we want is to copy the bytes directly because we know that will have the right behavior. For example, if we have `std::string`, `std::copy` will create a copy of the string, when really all we need is to copy the bytes of the string representation.

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


More information about the libcxx-commits mailing list