diff options
author | Benjamin Barenblat <bbaren@google.com> | 2023-09-07 13:26:18 -0400 |
---|---|---|
committer | Benjamin Barenblat <bbaren@google.com> | 2023-09-07 13:26:18 -0400 |
commit | 94b8e998a4c04e3bd78202d429c1b804f77198ea (patch) | |
tree | 69b8340d932695bae9b8ff6e006e656a448307be /debian/patches/split-hash-tests.diff | |
parent | 494211f47140be3ff09f70843b111e23dbcfad5e (diff) | |
download | abseil-94b8e998a4c04e3bd78202d429c1b804f77198ea.tar.gz abseil-94b8e998a4c04e3bd78202d429c1b804f77198ea.tar.bz2 abseil-94b8e998a4c04e3bd78202d429c1b804f77198ea.zip |
Update patches and bump internal namespace
Diffstat (limited to 'debian/patches/split-hash-tests.diff')
-rw-r--r-- | debian/patches/split-hash-tests.diff | 677 |
1 files changed, 0 insertions, 677 deletions
diff --git a/debian/patches/split-hash-tests.diff b/debian/patches/split-hash-tests.diff deleted file mode 100644 index ae0d066f..00000000 --- a/debian/patches/split-hash-tests.diff +++ /dev/null @@ -1,677 +0,0 @@ -From: Benjamin Barenblat <bbaren@google.com> -Subject: Split absl/hash/hash_test.cc into two files -Origin: backport, https://github.com/abseil/abseil-cpp/commit/c154d20abce2f1ae6bd35bd774313e351493219b - -hash_test.cc leans heavily on INSTANTIATE_TYPED_TEST_SUITE_P, which is quite -memory- and CPU-hungry. Split a few heavyweight tests into a new -hash_instantiated_test.cc, reducing peak RAM consumption (or, on multicore -systems, compilation time). - ---- a/absl/hash/BUILD.bazel -+++ b/absl/hash/BUILD.bazel -@@ -68,13 +68,17 @@ - - cc_test( - name = "hash_test", -- srcs = ["hash_test.cc"], -+ srcs = [ -+ "hash_test.cc", -+ "internal/hash_test.h", -+ ], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":hash", - ":hash_testing", - ":spy_hash_state", -+ "//absl/base:config", - "//absl/base:core_headers", - "//absl/container:btree", - "//absl/container:flat_hash_map", -@@ -87,6 +91,27 @@ - "@com_google_googletest//:gtest_main", - ], - ) -+ -+cc_test( -+ name = "hash_instantiated_test", -+ srcs = [ -+ "hash_instantiated_test.cc", -+ "internal/hash_test.h", -+ ], -+ copts = ABSL_TEST_COPTS, -+ linkopts = ABSL_DEFAULT_LINKOPTS, -+ deps = [ -+ ":hash", -+ ":hash_testing", -+ "//absl/base:config", -+ "//absl/container:btree", -+ "//absl/container:flat_hash_map", -+ "//absl/container:flat_hash_set", -+ "//absl/container:node_hash_map", -+ "//absl/container:node_hash_set", -+ "@com_google_googletest//:gtest_main", -+ ], -+) - - cc_binary( - name = "hash_benchmark", ---- a/absl/hash/CMakeLists.txt -+++ b/absl/hash/CMakeLists.txt -@@ -64,6 +64,7 @@ - hash_test - SRCS - "hash_test.cc" -+ "internal/hash_test.h" - COPTS - ${ABSL_TEST_COPTS} - DEPS -@@ -82,6 +83,26 @@ - GTest::gmock_main - ) - -+absl_cc_test( -+ NAME -+ hash_instantiated_test -+ SRCS -+ "hash_test.cc" -+ "internal/hash_test.h" -+ COPTS -+ ${ABSL_TEST_COPTS} -+ DEPS -+ absl::hash -+ absl::hash_testing -+ absl::config -+ absl::btree -+ absl::flat_hash_map -+ absl::flat_hash_set -+ absl::node_hash_map -+ absl::node_hash_set -+ GTest::gtest_main -+) -+ - # Internal-only target, do not depend on directly. - # - # Note: Even though external code should not depend on this target ---- /dev/null -+++ b/absl/hash/hash_instantiated_test.cc -@@ -0,0 +1,224 @@ -+// Copyright 2018 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+ -+// This file contains a few select absl::Hash tests that, due to their reliance -+// on INSTANTIATE_TYPED_TEST_SUITE_P, require a large amount of memory to -+// compile. Put new tests in hash_test.cc, not this file. -+ -+#include "absl/hash/hash.h" -+ -+#include <stddef.h> -+ -+#include <algorithm> -+#include <deque> -+#include <forward_list> -+#include <initializer_list> -+#include <list> -+#include <map> -+#include <set> -+#include <string> -+#include <type_traits> -+#include <unordered_map> -+#include <unordered_set> -+#include <utility> -+#include <vector> -+ -+#include "gtest/gtest.h" -+#include "absl/container/btree_map.h" -+#include "absl/container/btree_set.h" -+#include "absl/container/flat_hash_map.h" -+#include "absl/container/flat_hash_set.h" -+#include "absl/container/node_hash_map.h" -+#include "absl/container/node_hash_set.h" -+#include "absl/hash/hash_testing.h" -+#include "absl/hash/internal/hash_test.h" -+ -+namespace { -+ -+using ::absl::hash_test_internal::is_hashable; -+using ::absl::hash_test_internal::TypeErasedContainer; -+ -+// Dummy type with unordered equality and hashing semantics. This preserves -+// input order internally, and is used below to ensure we get test coverage -+// for equal sequences with different iteraton orders. -+template <typename T> -+class UnorderedSequence { -+ public: -+ UnorderedSequence() = default; -+ template <typename TT> -+ UnorderedSequence(std::initializer_list<TT> l) -+ : values_(l.begin(), l.end()) {} -+ template <typename ForwardIterator, -+ typename std::enable_if<!std::is_integral<ForwardIterator>::value, -+ bool>::type = true> -+ UnorderedSequence(ForwardIterator begin, ForwardIterator end) -+ : values_(begin, end) {} -+ // one-argument constructor of value type T, to appease older toolchains that -+ // get confused by one-element initializer lists in some contexts -+ explicit UnorderedSequence(const T& v) : values_(&v, &v + 1) {} -+ -+ using value_type = T; -+ -+ size_t size() const { return values_.size(); } -+ typename std::vector<T>::const_iterator begin() const { -+ return values_.begin(); -+ } -+ typename std::vector<T>::const_iterator end() const { return values_.end(); } -+ -+ friend bool operator==(const UnorderedSequence& lhs, -+ const UnorderedSequence& rhs) { -+ return lhs.size() == rhs.size() && -+ std::is_permutation(lhs.begin(), lhs.end(), rhs.begin()); -+ } -+ friend bool operator!=(const UnorderedSequence& lhs, -+ const UnorderedSequence& rhs) { -+ return !(lhs == rhs); -+ } -+ template <typename H> -+ friend H AbslHashValue(H h, const UnorderedSequence& u) { -+ return H::combine(H::combine_unordered(std::move(h), u.begin(), u.end()), -+ u.size()); -+ } -+ -+ private: -+ std::vector<T> values_; -+}; -+ -+template <typename T> -+class HashValueSequenceTest : public testing::Test {}; -+TYPED_TEST_SUITE_P(HashValueSequenceTest); -+ -+TYPED_TEST_P(HashValueSequenceTest, BasicUsage) { -+ EXPECT_TRUE((is_hashable<TypeParam>::value)); -+ -+ using IntType = typename TypeParam::value_type; -+ auto a = static_cast<IntType>(0); -+ auto b = static_cast<IntType>(23); -+ auto c = static_cast<IntType>(42); -+ -+ std::vector<TypeParam> exemplars = { -+ TypeParam(), TypeParam(), TypeParam{a, b, c}, -+ TypeParam{a, c, b}, TypeParam{c, a, b}, TypeParam{a}, -+ TypeParam{a, a}, TypeParam{a, a, a}, TypeParam{a, a, b}, -+ TypeParam{a, b, a}, TypeParam{b, a, a}, TypeParam{a, b}, -+ TypeParam{b, c}}; -+ EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); -+} -+ -+REGISTER_TYPED_TEST_SUITE_P(HashValueSequenceTest, BasicUsage); -+using IntSequenceTypes = testing::Types< -+ std::deque<int>, std::forward_list<int>, std::list<int>, std::vector<int>, -+ std::vector<bool>, TypeErasedContainer<std::vector<int>>, std::set<int>, -+ std::multiset<int>, UnorderedSequence<int>, -+ TypeErasedContainer<UnorderedSequence<int>>, std::unordered_set<int>, -+ std::unordered_multiset<int>, absl::flat_hash_set<int>, -+ absl::node_hash_set<int>, absl::btree_set<int>>; -+INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueSequenceTest, IntSequenceTypes); -+ -+template <typename T> -+class HashValueNestedSequenceTest : public testing::Test {}; -+TYPED_TEST_SUITE_P(HashValueNestedSequenceTest); -+ -+TYPED_TEST_P(HashValueNestedSequenceTest, BasicUsage) { -+ using T = TypeParam; -+ using V = typename T::value_type; -+ std::vector<T> exemplars = { -+ // empty case -+ T{}, -+ // sets of empty sets -+ T{V{}}, T{V{}, V{}}, T{V{}, V{}, V{}}, -+ // multisets of different values -+ T{V{1}}, T{V{1, 1}, V{1, 1}}, T{V{1, 1, 1}, V{1, 1, 1}, V{1, 1, 1}}, -+ // various orderings of same nested sets -+ T{V{}, V{1, 2}}, T{V{}, V{2, 1}}, T{V{1, 2}, V{}}, T{V{2, 1}, V{}}, -+ // various orderings of various nested sets, case 2 -+ T{V{1, 2}, V{3, 4}}, T{V{1, 2}, V{4, 3}}, T{V{1, 3}, V{2, 4}}, -+ T{V{1, 3}, V{4, 2}}, T{V{1, 4}, V{2, 3}}, T{V{1, 4}, V{3, 2}}, -+ T{V{2, 3}, V{1, 4}}, T{V{2, 3}, V{4, 1}}, T{V{2, 4}, V{1, 3}}, -+ T{V{2, 4}, V{3, 1}}, T{V{3, 4}, V{1, 2}}, T{V{3, 4}, V{2, 1}}}; -+ EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); -+} -+ -+REGISTER_TYPED_TEST_SUITE_P(HashValueNestedSequenceTest, BasicUsage); -+template <typename T> -+using TypeErasedSet = TypeErasedContainer<UnorderedSequence<T>>; -+ -+using NestedIntSequenceTypes = testing::Types< -+ std::vector<std::vector<int>>, std::vector<UnorderedSequence<int>>, -+ std::vector<TypeErasedSet<int>>, UnorderedSequence<std::vector<int>>, -+ UnorderedSequence<UnorderedSequence<int>>, -+ UnorderedSequence<TypeErasedSet<int>>, TypeErasedSet<std::vector<int>>, -+ TypeErasedSet<UnorderedSequence<int>>, TypeErasedSet<TypeErasedSet<int>>>; -+INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueNestedSequenceTest, -+ NestedIntSequenceTypes); -+ -+template <typename T> -+class HashValueAssociativeMapTest : public testing::Test {}; -+TYPED_TEST_SUITE_P(HashValueAssociativeMapTest); -+ -+TYPED_TEST_P(HashValueAssociativeMapTest, BasicUsage) { -+ using M = TypeParam; -+ using V = typename M::value_type; -+ std::vector<M> exemplars{M{}, -+ M{V{0, "foo"}}, -+ M{V{1, "foo"}}, -+ M{V{0, "bar"}}, -+ M{V{1, "bar"}}, -+ M{V{0, "foo"}, V{42, "bar"}}, -+ M{V{42, "bar"}, V{0, "foo"}}, -+ M{V{1, "foo"}, V{42, "bar"}}, -+ M{V{1, "foo"}, V{43, "bar"}}, -+ M{V{1, "foo"}, V{43, "baz"}}}; -+ EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); -+} -+ -+REGISTER_TYPED_TEST_SUITE_P(HashValueAssociativeMapTest, BasicUsage); -+using AssociativeMapTypes = testing::Types< -+ std::map<int, std::string>, std::unordered_map<int, std::string>, -+ absl::flat_hash_map<int, std::string>, -+ absl::node_hash_map<int, std::string>, absl::btree_map<int, std::string>, -+ UnorderedSequence<std::pair<const int, std::string>>>; -+INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueAssociativeMapTest, -+ AssociativeMapTypes); -+ -+template <typename T> -+class HashValueAssociativeMultimapTest : public testing::Test {}; -+TYPED_TEST_SUITE_P(HashValueAssociativeMultimapTest); -+ -+TYPED_TEST_P(HashValueAssociativeMultimapTest, BasicUsage) { -+ using MM = TypeParam; -+ using V = typename MM::value_type; -+ std::vector<MM> exemplars{MM{}, -+ MM{V{0, "foo"}}, -+ MM{V{1, "foo"}}, -+ MM{V{0, "bar"}}, -+ MM{V{1, "bar"}}, -+ MM{V{0, "foo"}, V{0, "bar"}}, -+ MM{V{0, "bar"}, V{0, "foo"}}, -+ MM{V{0, "foo"}, V{42, "bar"}}, -+ MM{V{1, "foo"}, V{42, "bar"}}, -+ MM{V{1, "foo"}, V{1, "foo"}, V{43, "bar"}}, -+ MM{V{1, "foo"}, V{43, "bar"}, V{1, "foo"}}, -+ MM{V{1, "foo"}, V{43, "baz"}}}; -+ EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); -+} -+ -+REGISTER_TYPED_TEST_SUITE_P(HashValueAssociativeMultimapTest, BasicUsage); -+using AssociativeMultimapTypes = -+ testing::Types<std::multimap<int, std::string>, -+ std::unordered_multimap<int, std::string>>; -+INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueAssociativeMultimapTest, -+ AssociativeMultimapTypes); -+ -+} // namespace ---- a/absl/hash/hash_test.cc -+++ b/absl/hash/hash_test.cc -@@ -47,6 +47,7 @@ - #include "absl/container/node_hash_map.h" - #include "absl/container/node_hash_set.h" - #include "absl/hash/hash_testing.h" -+#include "absl/hash/internal/hash_test.h" - #include "absl/hash/internal/spy_hash_state.h" - #include "absl/meta/type_traits.h" - #include "absl/numeric/int128.h" -@@ -54,52 +55,9 @@ - - namespace { - --// Utility wrapper of T for the purposes of testing the `AbslHash` type erasure --// mechanism. `TypeErasedValue<T>` can be constructed with a `T`, and can --// be compared and hashed. However, all hashing goes through the hashing --// type-erasure framework. --template <typename T> --class TypeErasedValue { -- public: -- TypeErasedValue() = default; -- TypeErasedValue(const TypeErasedValue&) = default; -- TypeErasedValue(TypeErasedValue&&) = default; -- explicit TypeErasedValue(const T& n) : n_(n) {} -- -- template <typename H> -- friend H AbslHashValue(H hash_state, const TypeErasedValue& v) { -- v.HashValue(absl::HashState::Create(&hash_state)); -- return hash_state; -- } -- -- void HashValue(absl::HashState state) const { -- absl::HashState::combine(std::move(state), n_); -- } -- -- bool operator==(const TypeErasedValue& rhs) const { return n_ == rhs.n_; } -- bool operator!=(const TypeErasedValue& rhs) const { return !(*this == rhs); } -- -- private: -- T n_; --}; -- --// A TypeErasedValue refinement, for containers. It exposes the wrapped --// `value_type` and is constructible from an initializer list. --template <typename T> --class TypeErasedContainer : public TypeErasedValue<T> { -- public: -- using value_type = typename T::value_type; -- TypeErasedContainer() = default; -- TypeErasedContainer(const TypeErasedContainer&) = default; -- TypeErasedContainer(TypeErasedContainer&&) = default; -- explicit TypeErasedContainer(const T& n) : TypeErasedValue<T>(n) {} -- TypeErasedContainer(std::initializer_list<value_type> init_list) -- : TypeErasedContainer(T(init_list.begin(), init_list.end())) {} -- // one-argument constructor of value type T, to appease older toolchains that -- // get confused by one-element initializer lists in some contexts -- explicit TypeErasedContainer(const value_type& v) -- : TypeErasedContainer(T(&v, &v + 1)) {} --}; -+using ::absl::hash_test_internal::is_hashable; -+using ::absl::hash_test_internal::TypeErasedContainer; -+using ::absl::hash_test_internal::TypeErasedValue; - - template <typename T> - using TypeErasedVector = TypeErasedContainer<std::vector<T>>; -@@ -117,11 +75,6 @@ - return SpyHashState::combine(SpyHashState(), value); - } - --// Helper trait to verify if T is hashable. We use absl::Hash's poison status to --// detect it. --template <typename T> --using is_hashable = std::is_default_constructible<absl::Hash<T>>; -- - TYPED_TEST_P(HashValueIntTest, BasicUsage) { - EXPECT_TRUE((is_hashable<TypeParam>::value)); - -@@ -520,121 +473,6 @@ - std::bitset<kNumBits>(bit_strings[5].c_str())})); - } // namespace - --// Dummy type with unordered equality and hashing semantics. This preserves --// input order internally, and is used below to ensure we get test coverage --// for equal sequences with different iteraton orders. --template <typename T> --class UnorderedSequence { -- public: -- UnorderedSequence() = default; -- template <typename TT> -- UnorderedSequence(std::initializer_list<TT> l) -- : values_(l.begin(), l.end()) {} -- template <typename ForwardIterator, -- typename std::enable_if<!std::is_integral<ForwardIterator>::value, -- bool>::type = true> -- UnorderedSequence(ForwardIterator begin, ForwardIterator end) -- : values_(begin, end) {} -- // one-argument constructor of value type T, to appease older toolchains that -- // get confused by one-element initializer lists in some contexts -- explicit UnorderedSequence(const T& v) : values_(&v, &v + 1) {} -- -- using value_type = T; -- -- size_t size() const { return values_.size(); } -- typename std::vector<T>::const_iterator begin() const { -- return values_.begin(); -- } -- typename std::vector<T>::const_iterator end() const { return values_.end(); } -- -- friend bool operator==(const UnorderedSequence& lhs, -- const UnorderedSequence& rhs) { -- return lhs.size() == rhs.size() && -- std::is_permutation(lhs.begin(), lhs.end(), rhs.begin()); -- } -- friend bool operator!=(const UnorderedSequence& lhs, -- const UnorderedSequence& rhs) { -- return !(lhs == rhs); -- } -- template <typename H> -- friend H AbslHashValue(H h, const UnorderedSequence& u) { -- return H::combine(H::combine_unordered(std::move(h), u.begin(), u.end()), -- u.size()); -- } -- -- private: -- std::vector<T> values_; --}; -- --template <typename T> --class HashValueSequenceTest : public testing::Test { --}; --TYPED_TEST_SUITE_P(HashValueSequenceTest); -- --TYPED_TEST_P(HashValueSequenceTest, BasicUsage) { -- EXPECT_TRUE((is_hashable<TypeParam>::value)); -- -- using IntType = typename TypeParam::value_type; -- auto a = static_cast<IntType>(0); -- auto b = static_cast<IntType>(23); -- auto c = static_cast<IntType>(42); -- -- std::vector<TypeParam> exemplars = { -- TypeParam(), TypeParam(), TypeParam{a, b, c}, -- TypeParam{a, c, b}, TypeParam{c, a, b}, TypeParam{a}, -- TypeParam{a, a}, TypeParam{a, a, a}, TypeParam{a, a, b}, -- TypeParam{a, b, a}, TypeParam{b, a, a}, TypeParam{a, b}, -- TypeParam{b, c}}; -- EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); --} -- --REGISTER_TYPED_TEST_SUITE_P(HashValueSequenceTest, BasicUsage); --using IntSequenceTypes = testing::Types< -- std::deque<int>, std::forward_list<int>, std::list<int>, std::vector<int>, -- std::vector<bool>, TypeErasedContainer<std::vector<int>>, std::set<int>, -- std::multiset<int>, UnorderedSequence<int>, -- TypeErasedContainer<UnorderedSequence<int>>, std::unordered_set<int>, -- std::unordered_multiset<int>, absl::flat_hash_set<int>, -- absl::node_hash_set<int>, absl::btree_set<int>>; --INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueSequenceTest, IntSequenceTypes); -- --template <typename T> --class HashValueNestedSequenceTest : public testing::Test {}; --TYPED_TEST_SUITE_P(HashValueNestedSequenceTest); -- --TYPED_TEST_P(HashValueNestedSequenceTest, BasicUsage) { -- using T = TypeParam; -- using V = typename T::value_type; -- std::vector<T> exemplars = { -- // empty case -- T{}, -- // sets of empty sets -- T{V{}}, T{V{}, V{}}, T{V{}, V{}, V{}}, -- // multisets of different values -- T{V{1}}, T{V{1, 1}, V{1, 1}}, T{V{1, 1, 1}, V{1, 1, 1}, V{1, 1, 1}}, -- // various orderings of same nested sets -- T{V{}, V{1, 2}}, T{V{}, V{2, 1}}, T{V{1, 2}, V{}}, T{V{2, 1}, V{}}, -- // various orderings of various nested sets, case 2 -- T{V{1, 2}, V{3, 4}}, T{V{1, 2}, V{4, 3}}, T{V{1, 3}, V{2, 4}}, -- T{V{1, 3}, V{4, 2}}, T{V{1, 4}, V{2, 3}}, T{V{1, 4}, V{3, 2}}, -- T{V{2, 3}, V{1, 4}}, T{V{2, 3}, V{4, 1}}, T{V{2, 4}, V{1, 3}}, -- T{V{2, 4}, V{3, 1}}, T{V{3, 4}, V{1, 2}}, T{V{3, 4}, V{2, 1}}}; -- EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); --} -- --REGISTER_TYPED_TEST_SUITE_P(HashValueNestedSequenceTest, BasicUsage); --template <typename T> --using TypeErasedSet = TypeErasedContainer<UnorderedSequence<T>>; -- --using NestedIntSequenceTypes = testing::Types< -- std::vector<std::vector<int>>, std::vector<UnorderedSequence<int>>, -- std::vector<TypeErasedSet<int>>, UnorderedSequence<std::vector<int>>, -- UnorderedSequence<UnorderedSequence<int>>, -- UnorderedSequence<TypeErasedSet<int>>, TypeErasedSet<std::vector<int>>, -- TypeErasedSet<UnorderedSequence<int>>, TypeErasedSet<TypeErasedSet<int>>>; --INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueNestedSequenceTest, -- NestedIntSequenceTypes); -- - // Private type that only supports AbslHashValue to make sure our chosen hash - // implementation is recursive within absl::Hash. - // It uses std::abs() on the value to provide different bitwise representations -@@ -793,64 +631,6 @@ - #endif - } - --template <typename T> --class HashValueAssociativeMapTest : public testing::Test {}; --TYPED_TEST_SUITE_P(HashValueAssociativeMapTest); -- --TYPED_TEST_P(HashValueAssociativeMapTest, BasicUsage) { -- using M = TypeParam; -- using V = typename M::value_type; -- std::vector<M> exemplars{M{}, -- M{V{0, "foo"}}, -- M{V{1, "foo"}}, -- M{V{0, "bar"}}, -- M{V{1, "bar"}}, -- M{V{0, "foo"}, V{42, "bar"}}, -- M{V{42, "bar"}, V{0, "foo"}}, -- M{V{1, "foo"}, V{42, "bar"}}, -- M{V{1, "foo"}, V{43, "bar"}}, -- M{V{1, "foo"}, V{43, "baz"}}}; -- EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); --} -- --REGISTER_TYPED_TEST_SUITE_P(HashValueAssociativeMapTest, BasicUsage); --using AssociativeMapTypes = testing::Types< -- std::map<int, std::string>, std::unordered_map<int, std::string>, -- absl::flat_hash_map<int, std::string>, -- absl::node_hash_map<int, std::string>, absl::btree_map<int, std::string>, -- UnorderedSequence<std::pair<const int, std::string>>>; --INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueAssociativeMapTest, -- AssociativeMapTypes); -- --template <typename T> --class HashValueAssociativeMultimapTest : public testing::Test {}; --TYPED_TEST_SUITE_P(HashValueAssociativeMultimapTest); -- --TYPED_TEST_P(HashValueAssociativeMultimapTest, BasicUsage) { -- using MM = TypeParam; -- using V = typename MM::value_type; -- std::vector<MM> exemplars{MM{}, -- MM{V{0, "foo"}}, -- MM{V{1, "foo"}}, -- MM{V{0, "bar"}}, -- MM{V{1, "bar"}}, -- MM{V{0, "foo"}, V{0, "bar"}}, -- MM{V{0, "bar"}, V{0, "foo"}}, -- MM{V{0, "foo"}, V{42, "bar"}}, -- MM{V{1, "foo"}, V{42, "bar"}}, -- MM{V{1, "foo"}, V{1, "foo"}, V{43, "bar"}}, -- MM{V{1, "foo"}, V{43, "bar"}, V{1, "foo"}}, -- MM{V{1, "foo"}, V{43, "baz"}}}; -- EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); --} -- --REGISTER_TYPED_TEST_SUITE_P(HashValueAssociativeMultimapTest, BasicUsage); --using AssociativeMultimapTypes = -- testing::Types<std::multimap<int, std::string>, -- std::unordered_multimap<int, std::string>>; --INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueAssociativeMultimapTest, -- AssociativeMultimapTypes); -- - TEST(HashValueTest, ReferenceWrapper) { - EXPECT_TRUE(is_hashable<std::reference_wrapper<Private>>::value); - ---- /dev/null -+++ b/absl/hash/internal/hash_test.h -@@ -0,0 +1,87 @@ -+// Copyright 2023 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+ -+// Common code shared between absl/hash/hash_test.cc and -+// absl/hash/hash_instantiated_test.cc. -+ -+#ifndef ABSL_HASH_INTERNAL_HASH_TEST_H_ -+#define ABSL_HASH_INTERNAL_HASH_TEST_H_ -+ -+#include <type_traits> -+#include <utility> -+ -+#include "absl/base/config.h" -+#include "absl/hash/hash.h" -+ -+namespace absl { -+ABSL_NAMESPACE_BEGIN -+namespace hash_test_internal { -+ -+// Utility wrapper of T for the purposes of testing the `AbslHash` type erasure -+// mechanism. `TypeErasedValue<T>` can be constructed with a `T`, and can -+// be compared and hashed. However, all hashing goes through the hashing -+// type-erasure framework. -+template <typename T> -+class TypeErasedValue { -+ public: -+ TypeErasedValue() = default; -+ TypeErasedValue(const TypeErasedValue&) = default; -+ TypeErasedValue(TypeErasedValue&&) = default; -+ explicit TypeErasedValue(const T& n) : n_(n) {} -+ -+ template <typename H> -+ friend H AbslHashValue(H hash_state, const TypeErasedValue& v) { -+ v.HashValue(absl::HashState::Create(&hash_state)); -+ return hash_state; -+ } -+ -+ void HashValue(absl::HashState state) const { -+ absl::HashState::combine(std::move(state), n_); -+ } -+ -+ bool operator==(const TypeErasedValue& rhs) const { return n_ == rhs.n_; } -+ bool operator!=(const TypeErasedValue& rhs) const { return !(*this == rhs); } -+ -+ private: -+ T n_; -+}; -+ -+// A TypeErasedValue refinement, for containers. It exposes the wrapped -+// `value_type` and is constructible from an initializer list. -+template <typename T> -+class TypeErasedContainer : public TypeErasedValue<T> { -+ public: -+ using value_type = typename T::value_type; -+ TypeErasedContainer() = default; -+ TypeErasedContainer(const TypeErasedContainer&) = default; -+ TypeErasedContainer(TypeErasedContainer&&) = default; -+ explicit TypeErasedContainer(const T& n) : TypeErasedValue<T>(n) {} -+ TypeErasedContainer(std::initializer_list<value_type> init_list) -+ : TypeErasedContainer(T(init_list.begin(), init_list.end())) {} -+ // one-argument constructor of value type T, to appease older toolchains that -+ // get confused by one-element initializer lists in some contexts -+ explicit TypeErasedContainer(const value_type& v) -+ : TypeErasedContainer(T(&v, &v + 1)) {} -+}; -+ -+// Helper trait to verify if T is hashable. We use absl::Hash's poison status to -+// detect it. -+template <typename T> -+using is_hashable = std::is_default_constructible<absl::Hash<T>>; -+ -+} // namespace hash_test_internal -+ABSL_NAMESPACE_END -+} // namespace absl -+ -+#endif // ABSL_HASH_INTERNAL_HASH_TEST_H_ |