diff options
author | Evan Brown <ezb@google.com> | 2022-10-03 10:51:40 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2022-10-03 10:52:25 -0700 |
commit | f8e0ff7f33338c2874b75e45e4ea5abbfafb954c (patch) | |
tree | 343d800108e96f67e578ebc3f614055a2d997065 /absl/container/internal/common_policy_traits.h | |
parent | d277a48d4cd998a9d8937b99fe6ee28f7adb0484 (diff) |
Use trivial relocation for transfers in swisstable and b-tree.
PiperOrigin-RevId: 478547898
Change-Id: Ie20cd0a49df042be912888ee238333a5f5fa0404
Diffstat (limited to 'absl/container/internal/common_policy_traits.h')
-rw-r--r-- | absl/container/internal/common_policy_traits.h | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/absl/container/internal/common_policy_traits.h b/absl/container/internal/common_policy_traits.h index cc2e89ba..c99e68f4 100644 --- a/absl/container/internal/common_policy_traits.h +++ b/absl/container/internal/common_policy_traits.h @@ -16,6 +16,7 @@ #define ABSL_CONTAINER_INTERNAL_COMMON_POLICY_TRAITS_H_ #include <cstddef> +#include <cstring> #include <memory> #include <new> #include <type_traits> @@ -32,7 +33,8 @@ template <class Policy, class = void> struct common_policy_traits { // The actual object stored in the container. using slot_type = typename Policy::slot_type; - + using reference = decltype(Policy::element(std::declval<slot_type*>())); + using value_type = typename std::remove_reference<reference>::type; // PRECONDITION: `slot` is UNINITIALIZED // POSTCONDITION: `slot` is INITIALIZED @@ -89,6 +91,17 @@ struct common_policy_traits { template <class Alloc> static void transfer_impl(Alloc* alloc, slot_type* new_slot, slot_type* old_slot, char) { +#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 + if (absl::is_trivially_relocatable<value_type>()) { + // TODO(b/247130232): remove cast after fixing class-memaccess warning. + std::memcpy(static_cast<void*>( + std::launder(const_cast<std::remove_const_t<value_type>*>( + &element(new_slot)))), + &element(old_slot), sizeof(value_type)); + return; + } +#endif + construct(alloc, new_slot, std::move(element(old_slot))); destroy(alloc, old_slot); } |