abseil-cpp/absl/container/internal/hash_function_defaults_test.cc
Go to the documentation of this file.
1 // Copyright 2018 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/container/internal/hash_function_defaults.h"
16 
17 #include <functional>
18 #include <type_traits>
19 #include <utility>
20 
21 #include "gtest/gtest.h"
22 #include "absl/random/random.h"
23 #include "absl/strings/cord.h"
24 #include "absl/strings/cord_test_helpers.h"
25 #include "absl/strings/string_view.h"
26 
27 namespace absl {
29 namespace container_internal {
30 namespace {
31 
33 
34 TEST(Eq, Int32) {
35  hash_default_eq<int32_t> eq;
36  EXPECT_TRUE(eq(1, 1u));
37  EXPECT_TRUE(eq(1, char{1}));
38  EXPECT_TRUE(eq(1, true));
39  EXPECT_TRUE(eq(1, double{1.1}));
40  EXPECT_FALSE(eq(1, char{2}));
41  EXPECT_FALSE(eq(1, 2u));
42  EXPECT_FALSE(eq(1, false));
43  EXPECT_FALSE(eq(1, 2.));
44 }
45 
46 TEST(Hash, Int32) {
47  hash_default_hash<int32_t> hash;
48  auto h = hash(1);
49  EXPECT_EQ(h, hash(1u));
50  EXPECT_EQ(h, hash(char{1}));
51  EXPECT_EQ(h, hash(true));
52  EXPECT_EQ(h, hash(double{1.1}));
53  EXPECT_NE(h, hash(2u));
54  EXPECT_NE(h, hash(char{2}));
55  EXPECT_NE(h, hash(false));
56  EXPECT_NE(h, hash(2.));
57 }
58 
59 enum class MyEnum { A, B, C, D };
60 
61 TEST(Eq, Enum) {
62  hash_default_eq<MyEnum> eq;
64  EXPECT_FALSE(eq(MyEnum::A, MyEnum::B));
65 }
66 
67 TEST(Hash, Enum) {
68  hash_default_hash<MyEnum> hash;
69 
70  for (MyEnum e : {MyEnum::A, MyEnum::B, MyEnum::C}) {
71  auto h = hash(e);
72  EXPECT_EQ(h, hash_default_hash<int>{}(static_cast<int>(e)));
73  EXPECT_NE(h, hash(MyEnum::D));
74  }
75 }
76 
78 
79 template <class T>
80 struct EqString : ::testing::Test {
81  hash_default_eq<T> key_eq;
82 };
83 
84 TYPED_TEST_SUITE(EqString, StringTypes);
85 
86 template <class T>
87 struct HashString : ::testing::Test {
88  hash_default_hash<T> hasher;
89 };
90 
91 TYPED_TEST_SUITE(HashString, StringTypes);
92 
93 TYPED_TEST(EqString, Works) {
94  auto eq = this->key_eq;
95  EXPECT_TRUE(eq("a", "a"));
96  EXPECT_TRUE(eq("a", absl::string_view("a")));
97  EXPECT_TRUE(eq("a", std::string("a")));
98  EXPECT_FALSE(eq("a", "b"));
99  EXPECT_FALSE(eq("a", absl::string_view("b")));
100  EXPECT_FALSE(eq("a", std::string("b")));
101 }
102 
103 TYPED_TEST(HashString, Works) {
104  auto hash = this->hasher;
105  auto h = hash("a");
106  EXPECT_EQ(h, hash(absl::string_view("a")));
107  EXPECT_EQ(h, hash(std::string("a")));
108  EXPECT_NE(h, hash(absl::string_view("b")));
109  EXPECT_NE(h, hash(std::string("b")));
110 }
111 
112 struct NoDeleter {
113  template <class T>
114  void operator()(const T* ptr) const {}
115 };
116 
117 using PointerTypes =
119  std::unique_ptr<const int, NoDeleter>,
120  std::unique_ptr<int>, std::unique_ptr<int, NoDeleter>,
121  std::shared_ptr<const int>, std::shared_ptr<int>>;
122 
123 template <class T>
124 struct EqPointer : ::testing::Test {
125  hash_default_eq<T> key_eq;
126 };
127 
128 TYPED_TEST_SUITE(EqPointer, PointerTypes);
129 
130 template <class T>
131 struct HashPointer : ::testing::Test {
132  hash_default_hash<T> hasher;
133 };
134 
135 TYPED_TEST_SUITE(HashPointer, PointerTypes);
136 
137 TYPED_TEST(EqPointer, Works) {
138  int dummy;
139  auto eq = this->key_eq;
140  auto sptr = std::make_shared<int>();
141  std::shared_ptr<const int> csptr = sptr;
142  int* ptr = sptr.get();
143  const int* cptr = ptr;
144  std::unique_ptr<int, NoDeleter> uptr(ptr);
145  std::unique_ptr<const int, NoDeleter> cuptr(ptr);
146 
147  EXPECT_TRUE(eq(ptr, cptr));
148  EXPECT_TRUE(eq(ptr, sptr));
149  EXPECT_TRUE(eq(ptr, uptr));
150  EXPECT_TRUE(eq(ptr, csptr));
151  EXPECT_TRUE(eq(ptr, cuptr));
152  EXPECT_FALSE(eq(&dummy, cptr));
153  EXPECT_FALSE(eq(&dummy, sptr));
154  EXPECT_FALSE(eq(&dummy, uptr));
155  EXPECT_FALSE(eq(&dummy, csptr));
156  EXPECT_FALSE(eq(&dummy, cuptr));
157 }
158 
159 TEST(Hash, DerivedAndBase) {
160  struct Base {};
161  struct Derived : Base {};
162 
163  hash_default_hash<Base*> hasher;
164 
165  Base base;
166  Derived derived;
167  EXPECT_NE(hasher(&base), hasher(&derived));
168  EXPECT_EQ(hasher(static_cast<Base*>(&derived)), hasher(&derived));
169 
170  auto dp = std::make_shared<Derived>();
171  EXPECT_EQ(hasher(static_cast<Base*>(dp.get())), hasher(dp));
172 }
173 
174 TEST(Hash, FunctionPointer) {
175  using Func = int (*)();
176  hash_default_hash<Func> hasher;
177  hash_default_eq<Func> eq;
178 
179  Func p1 = [] { return 1; }, p2 = [] { return 2; };
180  EXPECT_EQ(hasher(p1), hasher(p1));
181  EXPECT_TRUE(eq(p1, p1));
182 
183  EXPECT_NE(hasher(p1), hasher(p2));
184  EXPECT_FALSE(eq(p1, p2));
185 }
186 
187 TYPED_TEST(HashPointer, Works) {
188  int dummy;
189  auto hash = this->hasher;
190  auto sptr = std::make_shared<int>();
191  std::shared_ptr<const int> csptr = sptr;
192  int* ptr = sptr.get();
193  const int* cptr = ptr;
194  std::unique_ptr<int, NoDeleter> uptr(ptr);
195  std::unique_ptr<const int, NoDeleter> cuptr(ptr);
196 
197  EXPECT_EQ(hash(ptr), hash(cptr));
198  EXPECT_EQ(hash(ptr), hash(sptr));
199  EXPECT_EQ(hash(ptr), hash(uptr));
200  EXPECT_EQ(hash(ptr), hash(csptr));
201  EXPECT_EQ(hash(ptr), hash(cuptr));
202  EXPECT_NE(hash(&dummy), hash(cptr));
203  EXPECT_NE(hash(&dummy), hash(sptr));
204  EXPECT_NE(hash(&dummy), hash(uptr));
205  EXPECT_NE(hash(&dummy), hash(csptr));
206  EXPECT_NE(hash(&dummy), hash(cuptr));
207 }
208 
209 TEST(EqCord, Works) {
210  hash_default_eq<absl::Cord> eq;
211  const absl::string_view a_string_view = "a";
212  const absl::Cord a_cord(a_string_view);
213  const absl::string_view b_string_view = "b";
214  const absl::Cord b_cord(b_string_view);
215 
216  EXPECT_TRUE(eq(a_cord, a_cord));
217  EXPECT_TRUE(eq(a_cord, a_string_view));
218  EXPECT_TRUE(eq(a_string_view, a_cord));
219  EXPECT_FALSE(eq(a_cord, b_cord));
220  EXPECT_FALSE(eq(a_cord, b_string_view));
221  EXPECT_FALSE(eq(b_string_view, a_cord));
222 }
223 
224 TEST(HashCord, Works) {
225  hash_default_hash<absl::Cord> hash;
226  const absl::string_view a_string_view = "a";
227  const absl::Cord a_cord(a_string_view);
228  const absl::string_view b_string_view = "b";
229  const absl::Cord b_cord(b_string_view);
230 
231  EXPECT_EQ(hash(a_cord), hash(a_cord));
232  EXPECT_EQ(hash(b_cord), hash(b_cord));
233  EXPECT_EQ(hash(a_string_view), hash(a_cord));
234  EXPECT_EQ(hash(b_string_view), hash(b_cord));
235  EXPECT_EQ(hash(absl::Cord("")), hash(""));
237 
238  EXPECT_NE(hash(a_cord), hash(b_cord));
239  EXPECT_NE(hash(a_cord), hash(b_string_view));
240  EXPECT_NE(hash(a_string_view), hash(b_cord));
241  EXPECT_NE(hash(a_string_view), hash(b_string_view));
242 }
243 
244 void NoOpReleaser(absl::string_view data, void* arg) {}
245 
246 TEST(HashCord, FragmentedCordWorks) {
247  hash_default_hash<absl::Cord> hash;
248  absl::Cord c = absl::MakeFragmentedCord({"a", "b", "c"});
249  EXPECT_FALSE(c.TryFlat().has_value());
250  EXPECT_EQ(hash(c), hash("abc"));
251 }
252 
253 TEST(HashCord, FragmentedLongCordWorks) {
254  hash_default_hash<absl::Cord> hash;
255  // Crete some large strings which do not fit on the stack.
256  std::string a(65536, 'a');
257  std::string b(65536, 'b');
259  EXPECT_FALSE(c.TryFlat().has_value());
260  EXPECT_EQ(hash(c), hash(a + b));
261 }
262 
263 TEST(HashCord, RandomCord) {
264  hash_default_hash<absl::Cord> hash;
265  auto bitgen = absl::BitGen();
266  for (int i = 0; i < 1000; ++i) {
267  const int number_of_segments = absl::Uniform(bitgen, 0, 10);
268  std::vector<std::string> pieces;
269  for (size_t s = 0; s < number_of_segments; ++s) {
271  str.resize(absl::Uniform(bitgen, 0, 4096));
272  // MSVC needed the explicit return type in the lambda.
273  std::generate(str.begin(), str.end(), [&]() -> char {
274  return static_cast<char>(absl::Uniform<unsigned char>(bitgen));
275  });
276  pieces.push_back(str);
277  }
279  EXPECT_EQ(hash(c), hash(std::string(c)));
280  }
281 }
282 
283 // Cartesian product of (std::string, absl::string_view)
284 // with (std::string, absl::string_view, const char*, absl::Cord).
285 using StringTypesCartesianProduct = Types<
286  // clang-format off
287  std::pair<absl::Cord, std::string>,
288  std::pair<absl::Cord, absl::string_view>,
289  std::pair<absl::Cord, absl::Cord>,
290  std::pair<absl::Cord, const char*>,
291 
292  std::pair<std::string, absl::Cord>,
293  std::pair<absl::string_view, absl::Cord>,
294 
295  std::pair<absl::string_view, std::string>,
296  std::pair<absl::string_view, absl::string_view>,
297  std::pair<absl::string_view, const char*>>;
298 // clang-format on
299 
300 constexpr char kFirstString[] = "abc123";
301 constexpr char kSecondString[] = "ijk456";
302 
303 template <typename T>
304 struct StringLikeTest : public ::testing::Test {
305  typename T::first_type a1{kFirstString};
306  typename T::second_type b1{kFirstString};
307  typename T::first_type a2{kSecondString};
308  typename T::second_type b2{kSecondString};
309  hash_default_eq<typename T::first_type> eq;
310  hash_default_hash<typename T::first_type> hash;
311 };
312 
313 TYPED_TEST_SUITE_P(StringLikeTest);
314 
315 TYPED_TEST_P(StringLikeTest, Eq) {
316  EXPECT_TRUE(this->eq(this->a1, this->b1));
317  EXPECT_TRUE(this->eq(this->b1, this->a1));
318 }
319 
320 TYPED_TEST_P(StringLikeTest, NotEq) {
321  EXPECT_FALSE(this->eq(this->a1, this->b2));
322  EXPECT_FALSE(this->eq(this->b2, this->a1));
323 }
324 
325 TYPED_TEST_P(StringLikeTest, HashEq) {
326  EXPECT_EQ(this->hash(this->a1), this->hash(this->b1));
327  EXPECT_EQ(this->hash(this->a2), this->hash(this->b2));
328  // It would be a poor hash function which collides on these strings.
329  EXPECT_NE(this->hash(this->a1), this->hash(this->b2));
330 }
331 
332 TYPED_TEST_SUITE(StringLikeTest, StringTypesCartesianProduct);
333 
334 } // namespace
335 } // namespace container_internal
337 } // namespace absl
338 
339 enum Hash : size_t {
340  kStd = 0x1, // std::hash
341 #ifdef _MSC_VER
342  kExtension = kStd, // In MSVC, std::hash == ::hash
343 #else // _MSC_VER
344  kExtension = 0x2, // ::hash (GCC extension)
345 #endif // _MSC_VER
346 };
347 
348 // H is a bitmask of Hash enumerations.
349 // Hashable<H> is hashable via all means specified in H.
350 template <int H>
351 struct Hashable {
352  static constexpr bool HashableBy(Hash h) { return h & H; }
353 };
354 
355 namespace std {
356 template <int H>
357 struct hash<Hashable<H>> {
358  template <class E = Hashable<H>,
359  class = typename std::enable_if<E::HashableBy(kStd)>::type>
360  size_t operator()(E) const {
361  return kStd;
362  }
363 };
364 } // namespace std
365 
366 namespace absl {
368 namespace container_internal {
369 namespace {
370 
371 template <class T>
372 size_t Hash(const T& v) {
373  return hash_default_hash<T>()(v);
374 }
375 
376 TEST(Delegate, HashDispatch) {
378 }
379 
380 } // namespace
381 } // namespace container_internal
383 } // namespace absl
xds_interop_client.str
str
Definition: xds_interop_client.py:487
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
ptr
char * ptr
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:45
absl::Cord
Definition: abseil-cpp/absl/strings/cord.h:150
Hashable
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:351
Hash
Hash
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:339
testing::internal::Int32
TypeWithSize< 4 >::Int Int32
Definition: bloaty/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:2159
fix_build_deps.c
list c
Definition: fix_build_deps.py:490
C
#define C(x)
Definition: abseil-cpp/absl/hash/internal/city_test.cc:49
std::hash< Hashable< H > >::operator()
size_t operator()(E) const
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:360
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::TEST
TEST(NotificationTest, SanityTest)
Definition: abseil-cpp/absl/synchronization/notification_test.cc:126
absl::FormatConversionChar::s
@ s
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
T
#define T(upbtypeconst, upbtype, ctype, default_value)
key_eq
hash_default_eq< T > key_eq
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:81
Hashable::HashableBy
static constexpr bool HashableBy(Hash h)
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:352
Enum
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:867
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
testing::internal::ProxyTypeList
Definition: googletest/googletest/include/gtest/internal/gtest-type-util.h:155
hasher
hash_default_hash< T > hasher
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:88
testing::Types
internal::ProxyTypeList< Ts... > Types
Definition: boringssl-with-bazel/src/third_party/googletest/include/gtest/internal/gtest-type-util.h:183
absl::FormatConversionChar::e
@ e
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
a2
T::first_type a2
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:307
absl::BitGen
random_internal::NonsecureURBGBase< random_internal::randen_engine< uint64_t > > BitGen
Definition: abseil-cpp/absl/random/random.h:121
xds_interop_client.int
int
Definition: xds_interop_client.py:113
b2
T::second_type b2
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:308
absl::random_internal_nanobenchmark::Func
FuncOutput(*)(const void *, FuncInput) Func
Definition: abseil-cpp/absl/random/internal/nanobenchmark.h:68
hash
hash_default_hash< typename T::first_type > hash
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:310
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
TYPED_TEST
#define TYPED_TEST(CaseName, TestName)
Definition: googletest/googletest/include/gtest/gtest-typed-test.h:197
testing::Eq
internal::EqMatcher< T > Eq(T x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8561
A
#define A(T)
arg
Definition: cmdline.cc:40
grpc_core::HashPointer
constexpr size_t HashPointer(T *p, size_t range)
Definition: useful.h:102
gen_synthetic_protos.base
base
Definition: gen_synthetic_protos.py:31
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
a1
T::first_type a1
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:305
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
H
#define H(b, c, d)
Definition: md4.c:114
kExtension
@ kExtension
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:344
b1
T::second_type b1
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:306
abseil.generate
def generate(args)
Definition: abseil-cpp/absl/abseil.podspec.gen.py:200
absl::compare_internal::eq
eq
Definition: abseil-cpp/absl/types/compare.h:72
absl::container_internal::TYPED_TEST_P
TYPED_TEST_P(ConstructorTest, NoArgs)
Definition: abseil-cpp/absl/container/internal/unordered_map_constructor_test.h:36
TYPED_TEST_SUITE
#define TYPED_TEST_SUITE(CaseName, Types,...)
Definition: googletest/googletest/include/gtest/gtest-typed-test.h:191
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
A
Definition: miscompile_with_no_unique_address_test.cc:23
absl::ABSL_NAMESPACE_BEGIN::dummy
int dummy
Definition: function_type_benchmark.cc:28
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
absl::MakeFragmentedCord
Cord MakeFragmentedCord(const Container &c)
Definition: abseil-cpp/absl/strings/cord_test_helpers.h:103
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
kStd
@ kStd
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:340
absl::str_format_internal::LengthMod::h
@ h
absl::container_internal::TYPED_TEST_SUITE_P
TYPED_TEST_SUITE_P(ConstructorTest)
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
absl::Hash
absl::hash_internal::Hash< T > Hash
Definition: abseil-cpp/absl/hash/hash.h:247
absl::Uniform
absl::enable_if_t<!std::is_same< R, void >::value, R > Uniform(TagType tag, URBG &&urbg, R lo, R hi)
Definition: abseil-cpp/absl/random/distributions.h:123


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:00