[libcxx-commits] [libcxx] [libc++] Use relocation in vector::emplace_back (PR #159365)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Sep 29 01:50:05 PDT 2025
================
@@ -469,15 +487,60 @@ class vector {
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x) { emplace_back(std::move(__x)); }
template <class... _Args>
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference __emplace_back(_Args&&... __args) {
+ if constexpr (__libcpp_is_trivially_relocatable<value_type>::value &&
+ __allocator_has_trivial_move_construct_v<allocator_type, value_type> &&
+ __allocator_has_trivial_destroy_v<allocator_type, value_type>) {
+ // This path is written in a way to have the fast path as compact as possible. Specifically,
+ // there is a branch in case there isn't enough capacity left over, which will return to the same location within
+ // the function after growing the vector. This ensures that the relocation code exists only once and the
+ // reallocation path is common across all `vector` instantiations of trivially relocatable types.
+ union _Tmp {
+ _LIBCPP_DIAGNOSTIC_PUSH
+ // Clang complains about __exclude_from_explicit_instantiation__ on a local class member.
+ _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wignored-attributes")
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tmp() {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~_Tmp() {}
+ _LIBCPP_DIAGNOSTIC_POP
+ value_type __val_;
+ };
+ _Tmp __tmp;
+
+ __alloc_traits::construct(__alloc_, std::addressof(__tmp.__val_), std::forward<_Args>(__args)...);
----------------
philnik777 wrote:
If the construction throws we have to roll back to the old allocation, since iterators have to stay valid. This is essentially what the other branch does.
https://github.com/llvm/llvm-project/pull/159365
More information about the libcxx-commits
mailing list