Add a workaround for std::pair not being trivially copyable in C++23 in some standard library versions PiperOrigin-RevId: 736979189 Change-Id: I652fa421bfa6c63f37b22dd0e1e09cce6809075a
diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index 10cddcf..5c83c94 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc
@@ -115,23 +115,29 @@ } TEST(FlatHashMap, Relocatability) { - static_assert(absl::is_trivially_relocatable<int>::value, ""); + static_assert(absl::is_trivially_relocatable<int>::value); +#if ABSL_INTERNAL_CPLUSPLUS_LANG <= 202002L + // std::pair is not trivially copyable in C++23 in some standard + // library versions. + // See https://github.com/llvm/llvm-project/pull/95444 for instance. + // container_memory.h contains a workaround so what really matters + // is the transfer test below. static_assert( - absl::is_trivially_relocatable<std::pair<const int, int>>::value, ""); + absl::is_trivially_relocatable<std::pair<const int, int>>::value); +#endif static_assert( std::is_same<decltype(absl::container_internal::FlatHashMapPolicy< int, int>::transfer<std::allocator<char>>(nullptr, nullptr, nullptr)), - std::true_type>::value, - ""); + std::true_type>::value); - struct NonRelocatable { - NonRelocatable() = default; - NonRelocatable(NonRelocatable&&) {} - NonRelocatable& operator=(NonRelocatable&&) { return *this; } - void* self = nullptr; - }; + struct NonRelocatable { + NonRelocatable() = default; + NonRelocatable(NonRelocatable&&) {} + NonRelocatable& operator=(NonRelocatable&&) { return *this; } + void* self = nullptr; + }; EXPECT_FALSE(absl::is_trivially_relocatable<NonRelocatable>::value); EXPECT_TRUE(
diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h index 8df5c8e..e7ac1db 100644 --- a/absl/container/internal/container_memory.h +++ b/absl/container/internal/container_memory.h
@@ -433,8 +433,15 @@ template <class Allocator> static auto transfer(Allocator* alloc, slot_type* new_slot, slot_type* old_slot) { - auto is_relocatable = - typename absl::is_trivially_relocatable<value_type>::type(); + // This should really just be + // typename absl::is_trivially_relocatable<value_type>::type() + // but std::pair is not trivially copyable in C++23 in some standard + // library versions. + // See https://github.com/llvm/llvm-project/pull/95444 for instance. + auto is_relocatable = typename std::conjunction< + absl::is_trivially_relocatable<typename value_type::first_type>, + absl::is_trivially_relocatable<typename value_type::second_type>>:: + type(); emplace(new_slot); if (is_relocatable) {