summaryrefslogtreecommitdiff
path: root/absl/container/internal
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2023-11-20 14:57:43 -0800
committerGravatar Copybara-Service <copybara-worker@google.com>2023-11-20 14:58:49 -0800
commitdb5c79932e16e97e8b2f9ecd0e74f99f0e74e0d7 (patch)
treef97c66bd57931a32ba1cb4c7a222f7003d9f359d /absl/container/internal
parentf393335cb7410fc3a88f41dc5dd878c020213e0b (diff)
Make `FlatHashMapPolicy` return `std::true_type` for relocatable objects.
This reduces produced binary size and can trigger even more optimizations in the future. PiperOrigin-RevId: 584136517 Change-Id: I3854833799f88f28b755ec53132925f0c3d468ab
Diffstat (limited to 'absl/container/internal')
-rw-r--r--absl/container/internal/container_memory.h22
-rw-r--r--absl/container/internal/container_memory_test.cc32
2 files changed, 43 insertions, 11 deletions
diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h
index f59ca4ee..3262d4eb 100644
--- a/absl/container/internal/container_memory.h
+++ b/absl/container/internal/container_memory.h
@@ -122,10 +122,10 @@ auto TupleRefImpl(T&& t, absl::index_sequence<Is...>)
// Returns a tuple of references to the elements of the input tuple. T must be a
// tuple.
template <class T>
-auto TupleRef(T&& t) -> decltype(
- TupleRefImpl(std::forward<T>(t),
- absl::make_index_sequence<
- std::tuple_size<typename std::decay<T>::type>::value>())) {
+auto TupleRef(T&& t) -> decltype(TupleRefImpl(
+ std::forward<T>(t),
+ absl::make_index_sequence<
+ std::tuple_size<typename std::decay<T>::type>::value>())) {
return TupleRefImpl(
std::forward<T>(t),
absl::make_index_sequence<
@@ -156,8 +156,8 @@ void ConstructFromTuple(Alloc* alloc, T* ptr, Tuple&& t) {
// Constructs T using the args specified in the tuple and calls F with the
// constructed value.
template <class T, class Tuple, class F>
-decltype(std::declval<F>()(std::declval<T>())) WithConstructed(
- Tuple&& t, F&& f) {
+decltype(std::declval<F>()(std::declval<T>())) WithConstructed(Tuple&& t,
+ F&& f) {
return memory_internal::WithConstructedImpl<T>(
std::forward<Tuple>(t),
absl::make_index_sequence<
@@ -423,16 +423,19 @@ struct map_slot_policy {
}
template <class Allocator>
- static void transfer(Allocator* alloc, slot_type* new_slot,
+ static auto transfer(Allocator* alloc, slot_type* new_slot,
slot_type* old_slot) {
+ auto is_relocatable =
+ typename absl::is_trivially_relocatable<value_type>::type();
+
emplace(new_slot);
#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
- if (absl::is_trivially_relocatable<value_type>()) {
+ if (is_relocatable) {
// TODO(b/247130232,b/251814870): remove casts after fixing warnings.
std::memcpy(static_cast<void*>(std::launder(&new_slot->value)),
static_cast<const void*>(&old_slot->value),
sizeof(value_type));
- return;
+ return is_relocatable;
}
#endif
@@ -444,6 +447,7 @@ struct map_slot_policy {
std::move(old_slot->value));
}
destroy(alloc, old_slot);
+ return is_relocatable;
}
};
diff --git a/absl/container/internal/container_memory_test.cc b/absl/container/internal/container_memory_test.cc
index fb9c4dde..c1e57834 100644
--- a/absl/container/internal/container_memory_test.cc
+++ b/absl/container/internal/container_memory_test.cc
@@ -14,8 +14,11 @@
#include "absl/container/internal/container_memory.h"
+#include <cstddef>
#include <cstdint>
+#include <memory>
#include <tuple>
+#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <utility>
@@ -23,6 +26,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/container/internal/test_instance_tracker.h"
+#include "absl/meta/type_traits.h"
#include "absl/strings/string_view.h"
namespace absl {
@@ -219,8 +223,7 @@ TEST(DecomposePair, NotDecomposable) {
ADD_FAILURE() << "Must not be called";
return 'A';
};
- EXPECT_STREQ("not decomposable",
- TryDecomposePair(f));
+ EXPECT_STREQ("not decomposable", TryDecomposePair(f));
EXPECT_STREQ("not decomposable",
TryDecomposePair(f, std::piecewise_construct, std::make_tuple(),
std::make_tuple(0.5)));
@@ -251,6 +254,31 @@ TEST(MapSlotPolicy, ConstKeyAndValue) {
EXPECT_EQ(tracker.copies(), 0);
}
+TEST(MapSlotPolicy, TransferReturnsTrue) {
+ {
+ using slot_policy = map_slot_policy<int, float>;
+ EXPECT_TRUE(
+ (std::is_same<decltype(slot_policy::transfer<std::allocator<char>>(
+ nullptr, nullptr, nullptr)),
+ std::true_type>::value));
+ }
+ {
+ struct NonRelocatable {
+ NonRelocatable() = default;
+ NonRelocatable(NonRelocatable&&) {}
+ NonRelocatable& operator=(NonRelocatable&&) { return *this; }
+ void* self = nullptr;
+ };
+
+ EXPECT_FALSE(absl::is_trivially_relocatable<NonRelocatable>::value);
+ using slot_policy = map_slot_policy<int, NonRelocatable>;
+ EXPECT_TRUE(
+ (std::is_same<decltype(slot_policy::transfer<std::allocator<char>>(
+ nullptr, nullptr, nullptr)),
+ std::false_type>::value));
+ }
+}
+
} // namespace
} // namespace container_internal
ABSL_NAMESPACE_END