summaryrefslogtreecommitdiff
path: root/absl/container
diff options
context:
space:
mode:
Diffstat (limited to 'absl/container')
-rw-r--r--absl/container/BUILD.bazel3
-rw-r--r--absl/container/CMakeLists.txt3
-rw-r--r--absl/container/internal/common_policy_traits.h15
-rw-r--r--absl/container/internal/common_policy_traits_test.cc9
-rw-r--r--absl/container/internal/container_memory.h13
-rw-r--r--absl/container/internal/raw_hash_set_test.cc27
6 files changed, 57 insertions, 13 deletions
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index 71afe9d2..15162f28 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -637,6 +637,8 @@ cc_test(
],
deps = [
":container_memory",
+ ":flat_hash_map",
+ ":flat_hash_set",
":hash_function_defaults",
":hash_policy_testing",
":hashtable_debug",
@@ -646,6 +648,7 @@ cc_test(
"//absl/base:core_headers",
"//absl/base:prefetch",
"//absl/base:raw_logging_internal",
+ "//absl/log",
"//absl/strings",
"@com_google_googletest//:gtest_main",
],
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index a3fdb969..6c2931b6 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -722,12 +722,15 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::container_memory
+ absl::flat_hash_map
+ absl::flat_hash_set
absl::hash_function_defaults
absl::hash_policy_testing
absl::hashtable_debug
absl::raw_hash_set
absl::base
absl::config
+ absl::log
absl::core_headers
absl::prefetch
absl::raw_logging_internal
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);
}
diff --git a/absl/container/internal/common_policy_traits_test.cc b/absl/container/internal/common_policy_traits_test.cc
index 768d870e..5eaa4aae 100644
--- a/absl/container/internal/common_policy_traits_test.cc
+++ b/absl/container/internal/common_policy_traits_test.cc
@@ -27,7 +27,7 @@ namespace container_internal {
namespace {
using ::testing::MockFunction;
-using ::testing::Return;
+using ::testing::AnyNumber;
using ::testing::ReturnRef;
using Slot = int;
@@ -101,9 +101,10 @@ TEST_F(Test, element) {
TEST_F(Test, without_transfer) {
int b = 42;
- EXPECT_CALL(element, Call(&b)).WillOnce(::testing::ReturnRef(b));
- EXPECT_CALL(construct, Call(&alloc, &a, b));
- EXPECT_CALL(destroy, Call(&alloc, &b));
+ EXPECT_CALL(element, Call(&a)).Times(AnyNumber()).WillOnce(ReturnRef(a));
+ EXPECT_CALL(element, Call(&b)).WillOnce(ReturnRef(b));
+ EXPECT_CALL(construct, Call(&alloc, &a, b)).Times(AnyNumber());
+ EXPECT_CALL(destroy, Call(&alloc, &b)).Times(AnyNumber());
common_policy_traits<PolicyWithoutOptionalOps>::transfer(&alloc, &a, &b);
}
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));
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index f77ffbc1..eec9da43 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -14,17 +14,25 @@
#include "absl/container/internal/raw_hash_set.h"
+#include <algorithm>
#include <atomic>
#include <cmath>
#include <cstdint>
#include <deque>
#include <functional>
+#include <iterator>
+#include <list>
+#include <map>
#include <memory>
#include <numeric>
+#include <ostream>
#include <random>
#include <string>
+#include <type_traits>
#include <unordered_map>
#include <unordered_set>
+#include <utility>
+#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -33,10 +41,13 @@
#include "absl/base/internal/cycleclock.h"
#include "absl/base/internal/prefetch.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hash_function_defaults.h"
#include "absl/container/internal/hash_policy_testing.h"
#include "absl/container/internal/hashtable_debug.h"
+#include "absl/log/log.h"
#include "absl/strings/string_view.h"
namespace absl {
@@ -339,7 +350,7 @@ class StringPolicy {
struct ctor {};
template <class... Ts>
- slot_type(ctor, Ts&&... ts) : pair(std::forward<Ts>(ts)...) {}
+ explicit slot_type(ctor, Ts&&... ts) : pair(std::forward<Ts>(ts)...) {}
std::pair<std::string, std::string> pair;
};
@@ -411,7 +422,7 @@ struct CustomAlloc : std::allocator<T> {
CustomAlloc() {}
template <typename U>
- CustomAlloc(const CustomAlloc<U>& other) {}
+ explicit CustomAlloc(const CustomAlloc<U>& /*other*/) {}
template<class U> struct rebind {
using other = CustomAlloc<U>;
@@ -1275,6 +1286,7 @@ TEST(Table, DISABLED_EnsureNonQuadraticTopNXorSeedByProbeSeqLength) {
for (size_t size : sizes) {
auto& stat = stats[size];
VerifyStats(size, expected, stat);
+ LOG(INFO) << size << " " << stat;
}
}
@@ -1370,6 +1382,7 @@ TEST(Table, DISABLED_EnsureNonQuadraticTopNLinearTransformByProbeSeqLength) {
for (size_t size : sizes) {
auto& stat = stats[size];
VerifyStats(size, expected, stat);
+ LOG(INFO) << size << " " << stat;
}
}
@@ -1504,7 +1517,7 @@ TEST(Table, RehashZeroForcesRehash) {
TEST(Table, ConstructFromInitList) {
using P = std::pair<std::string, std::string>;
struct Q {
- operator P() const { return {}; }
+ operator P() const { return {}; } // NOLINT
};
StringTable t = {P(), Q(), {}, {{}, {}}};
}
@@ -2027,7 +2040,7 @@ TEST(Table, UnstablePointers) {
TEST(TableDeathTest, EraseOfEndAsserts) {
// Use an assert with side-effects to figure out if they are actually enabled.
bool assert_enabled = false;
- assert([&]() {
+ assert([&]() { // NOLINT
assert_enabled = true;
return true;
}());
@@ -2047,7 +2060,7 @@ TEST(RawHashSamplerTest, Sample) {
auto& sampler = GlobalHashtablezSampler();
size_t start_size = 0;
- std::unordered_set<const HashtablezInfo*> preexisting_info;
+ absl::flat_hash_set<const HashtablezInfo*> preexisting_info;
start_size += sampler.Iterate([&](const HashtablezInfo& info) {
preexisting_info.insert(&info);
++start_size;
@@ -2074,8 +2087,8 @@ TEST(RawHashSamplerTest, Sample) {
}
}
size_t end_size = 0;
- std::unordered_map<size_t, int> observed_checksums;
- std::unordered_map<ssize_t, int> reservations;
+ absl::flat_hash_map<size_t, int> observed_checksums;
+ absl::flat_hash_map<ssize_t, int> reservations;
end_size += sampler.Iterate([&](const HashtablezInfo& info) {
if (preexisting_info.count(&info) == 0) {
observed_checksums[info.hashes_bitwise_xor.load(