summaryrefslogtreecommitdiff
path: root/absl/container/internal/common_policy_traits.h
diff options
context:
space:
mode:
authorGravatar Randolf J <34705014+jun-sheaf@users.noreply.github.com>2022-10-05 22:51:24 +0200
committerGravatar GitHub <noreply@github.com>2022-10-05 22:51:24 +0200
commitbeaec233795725fea58fd88b2f9271aa7decabce (patch)
tree73a75125b0787d3b47f32ae29b079bec864b9102 /absl/container/internal/common_policy_traits.h
parentbf2bf60a3e29f159c8aa513d58cbe65f3f633bb6 (diff)
parent1fd600dc490db4db0ebf7bcc629d8914e828467e (diff)
Merge branch 'abseil:master' into patch-1
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);
}