summaryrefslogtreecommitdiff
path: root/absl/container/internal/container_memory.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/container/internal/container_memory.h')
-rw-r--r--absl/container/internal/container_memory.h13
1 files changed, 12 insertions, 1 deletions
diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h
index 00e9f6d7..c29c533b 100644
--- a/absl/container/internal/container_memory.h
+++ b/absl/container/internal/container_memory.h
@@ -17,6 +17,7 @@
#include <cassert>
#include <cstddef>
+#include <cstring>
#include <memory>
#include <new>
#include <tuple>
@@ -340,7 +341,8 @@ template <class K, class V>
struct map_slot_policy {
using slot_type = map_slot_type<K, V>;
using value_type = std::pair<const K, V>;
- using mutable_value_type = std::pair<K, V>;
+ using mutable_value_type =
+ std::pair<absl::remove_const_t<K>, absl::remove_const_t<V>>;
private:
static void emplace(slot_type* slot) {
@@ -424,6 +426,15 @@ struct map_slot_policy {
static void transfer(Allocator* alloc, slot_type* new_slot,
slot_type* old_slot) {
emplace(new_slot);
+#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(&new_slot->value)),
+ &old_slot->value, sizeof(value_type));
+ return;
+ }
+#endif
+
if (kMutableKeys::value) {
absl::allocator_traits<Allocator>::construct(
*alloc, &new_slot->mutable_value, std::move(old_slot->mutable_value));