summaryrefslogtreecommitdiff
path: root/absl/container/internal/common_policy_traits.h
diff options
context:
space:
mode:
authorGravatar Evan Brown <ezb@google.com>2022-10-03 10:51:40 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2022-10-03 10:52:25 -0700
commitf8e0ff7f33338c2874b75e45e4ea5abbfafb954c (patch)
tree343d800108e96f67e578ebc3f614055a2d997065 /absl/container/internal/common_policy_traits.h
parentd277a48d4cd998a9d8937b99fe6ee28f7adb0484 (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.h15
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);
}