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 
16 
17 #include <functional>
18 #include <type_traits>
19 #include <utility>
20 
21 #include "gtest/gtest.h"
23 
24 namespace absl {
25 namespace container_internal {
26 namespace {
27 
28 using ::testing::Types;
29 
30 TEST(Eq, Int32) {
31  hash_default_eq<int32_t> eq;
32  EXPECT_TRUE(eq(1, 1u));
33  EXPECT_TRUE(eq(1, char{1}));
34  EXPECT_TRUE(eq(1, true));
35  EXPECT_TRUE(eq(1, double{1.1}));
36  EXPECT_FALSE(eq(1, char{2}));
37  EXPECT_FALSE(eq(1, 2u));
38  EXPECT_FALSE(eq(1, false));
39  EXPECT_FALSE(eq(1, 2.));
40 }
41 
42 TEST(Hash, Int32) {
43  hash_default_hash<int32_t> hash;
44  auto h = hash(1);
45  EXPECT_EQ(h, hash(1u));
46  EXPECT_EQ(h, hash(char{1}));
47  EXPECT_EQ(h, hash(true));
48  EXPECT_EQ(h, hash(double{1.1}));
49  EXPECT_NE(h, hash(2u));
50  EXPECT_NE(h, hash(char{2}));
51  EXPECT_NE(h, hash(false));
52  EXPECT_NE(h, hash(2.));
53 }
54 
55 enum class MyEnum { A, B, C, D };
56 
57 TEST(Eq, Enum) {
59  EXPECT_TRUE(eq(MyEnum::A, MyEnum::A));
60  EXPECT_FALSE(eq(MyEnum::A, MyEnum::B));
61 }
62 
63 TEST(Hash, Enum) {
65 
66  for (MyEnum e : {MyEnum::A, MyEnum::B, MyEnum::C}) {
67  auto h = hash(e);
68  EXPECT_EQ(h, hash_default_hash<int>{}(static_cast<int>(e)));
69  EXPECT_NE(h, hash(MyEnum::D));
70  }
71 }
72 
73 using StringTypes = ::testing::Types<std::string, absl::string_view>;
74 
75 template <class T>
76 struct EqString : ::testing::Test {
77  hash_default_eq<T> key_eq;
78 };
79 
80 TYPED_TEST_SUITE(EqString, StringTypes);
81 
82 template <class T>
83 struct HashString : ::testing::Test {
84  hash_default_hash<T> hasher;
85 };
86 
87 TYPED_TEST_SUITE(HashString, StringTypes);
88 
89 TYPED_TEST(EqString, Works) {
90  auto eq = this->key_eq;
91  EXPECT_TRUE(eq("a", "a"));
92  EXPECT_TRUE(eq("a", absl::string_view("a")));
93  EXPECT_TRUE(eq("a", std::string("a")));
94  EXPECT_FALSE(eq("a", "b"));
95  EXPECT_FALSE(eq("a", absl::string_view("b")));
96  EXPECT_FALSE(eq("a", std::string("b")));
97 }
98 
99 TYPED_TEST(HashString, Works) {
100  auto hash = this->hasher;
101  auto h = hash("a");
102  EXPECT_EQ(h, hash(absl::string_view("a")));
103  EXPECT_EQ(h, hash(std::string("a")));
104  EXPECT_NE(h, hash(absl::string_view("b")));
105  EXPECT_NE(h, hash(std::string("b")));
106 }
107 
108 struct NoDeleter {
109  template <class T>
110  void operator()(const T* ptr) const {}
111 };
112 
113 using PointerTypes =
114  ::testing::Types<const int*, int*, std::unique_ptr<const int>,
115  std::unique_ptr<const int, NoDeleter>,
116  std::unique_ptr<int>, std::unique_ptr<int, NoDeleter>,
117  std::shared_ptr<const int>, std::shared_ptr<int>>;
118 
119 template <class T>
120 struct EqPointer : ::testing::Test {
121  hash_default_eq<T> key_eq;
122 };
123 
124 TYPED_TEST_SUITE(EqPointer, PointerTypes);
125 
126 template <class T>
127 struct HashPointer : ::testing::Test {
128  hash_default_hash<T> hasher;
129 };
130 
131 TYPED_TEST_SUITE(HashPointer, PointerTypes);
132 
133 TYPED_TEST(EqPointer, Works) {
134  int dummy;
135  auto eq = this->key_eq;
136  auto sptr = std::make_shared<int>();
137  std::shared_ptr<const int> csptr = sptr;
138  int* ptr = sptr.get();
139  const int* cptr = ptr;
140  std::unique_ptr<int, NoDeleter> uptr(ptr);
141  std::unique_ptr<const int, NoDeleter> cuptr(ptr);
142 
143  EXPECT_TRUE(eq(ptr, cptr));
144  EXPECT_TRUE(eq(ptr, sptr));
145  EXPECT_TRUE(eq(ptr, uptr));
146  EXPECT_TRUE(eq(ptr, csptr));
147  EXPECT_TRUE(eq(ptr, cuptr));
148  EXPECT_FALSE(eq(&dummy, cptr));
149  EXPECT_FALSE(eq(&dummy, sptr));
150  EXPECT_FALSE(eq(&dummy, uptr));
151  EXPECT_FALSE(eq(&dummy, csptr));
152  EXPECT_FALSE(eq(&dummy, cuptr));
153 }
154 
155 TEST(Hash, DerivedAndBase) {
156  struct Base {};
157  struct Derived : Base {};
158 
159  hash_default_hash<Base*> hasher;
160 
161  Base base;
162  Derived derived;
163  EXPECT_NE(hasher(&base), hasher(&derived));
164  EXPECT_EQ(hasher(static_cast<Base*>(&derived)), hasher(&derived));
165 
166  auto dp = std::make_shared<Derived>();
167  EXPECT_EQ(hasher(static_cast<Base*>(dp.get())), hasher(dp));
168 }
169 
170 TEST(Hash, FunctionPointer) {
171  using Func = int (*)();
172  hash_default_hash<Func> hasher;
173  hash_default_eq<Func> eq;
174 
175  Func p1 = [] { return 1; }, p2 = [] { return 2; };
176  EXPECT_EQ(hasher(p1), hasher(p1));
177  EXPECT_TRUE(eq(p1, p1));
178 
179  EXPECT_NE(hasher(p1), hasher(p2));
180  EXPECT_FALSE(eq(p1, p2));
181 }
182 
183 TYPED_TEST(HashPointer, Works) {
184  int dummy;
185  auto hash = this->hasher;
186  auto sptr = std::make_shared<int>();
187  std::shared_ptr<const int> csptr = sptr;
188  int* ptr = sptr.get();
189  const int* cptr = ptr;
190  std::unique_ptr<int, NoDeleter> uptr(ptr);
191  std::unique_ptr<const int, NoDeleter> cuptr(ptr);
192 
193  EXPECT_EQ(hash(ptr), hash(cptr));
194  EXPECT_EQ(hash(ptr), hash(sptr));
195  EXPECT_EQ(hash(ptr), hash(uptr));
196  EXPECT_EQ(hash(ptr), hash(csptr));
197  EXPECT_EQ(hash(ptr), hash(cuptr));
198  EXPECT_NE(hash(&dummy), hash(cptr));
199  EXPECT_NE(hash(&dummy), hash(sptr));
200  EXPECT_NE(hash(&dummy), hash(uptr));
201  EXPECT_NE(hash(&dummy), hash(csptr));
202  EXPECT_NE(hash(&dummy), hash(cuptr));
203 }
204 
205 // Cartesian product of (std::string, absl::string_view)
206 // with (std::string, absl::string_view, const char*).
207 using StringTypesCartesianProduct = Types<
208  // clang-format off
209 
210  std::pair<absl::string_view, std::string>,
211  std::pair<absl::string_view, absl::string_view>,
212  std::pair<absl::string_view, const char*>>;
213 // clang-format on
214 
215 constexpr char kFirstString[] = "abc123";
216 constexpr char kSecondString[] = "ijk456";
217 
218 template <typename T>
219 struct StringLikeTest : public ::testing::Test {
220  typename T::first_type a1{kFirstString};
221  typename T::second_type b1{kFirstString};
222  typename T::first_type a2{kSecondString};
223  typename T::second_type b2{kSecondString};
224  hash_default_eq<typename T::first_type> eq;
225  hash_default_hash<typename T::first_type> hash;
226 };
227 
228 TYPED_TEST_CASE_P(StringLikeTest);
229 
230 TYPED_TEST_P(StringLikeTest, Eq) {
231  EXPECT_TRUE(this->eq(this->a1, this->b1));
232  EXPECT_TRUE(this->eq(this->b1, this->a1));
233 }
234 
235 TYPED_TEST_P(StringLikeTest, NotEq) {
236  EXPECT_FALSE(this->eq(this->a1, this->b2));
237  EXPECT_FALSE(this->eq(this->b2, this->a1));
238 }
239 
240 TYPED_TEST_P(StringLikeTest, HashEq) {
241  EXPECT_EQ(this->hash(this->a1), this->hash(this->b1));
242  EXPECT_EQ(this->hash(this->a2), this->hash(this->b2));
243  // It would be a poor hash function which collides on these strings.
244  EXPECT_NE(this->hash(this->a1), this->hash(this->b2));
245 }
246 
247 TYPED_TEST_SUITE(StringLikeTest, StringTypesCartesianProduct);
248 
249 } // namespace
250 } // namespace container_internal
251 } // namespace absl
252 
253 enum Hash : size_t {
254  kStd = 0x2, // std::hash
255 #ifdef _MSC_VER
256  kExtension = kStd, // In MSVC, std::hash == ::hash
257 #else // _MSC_VER
258  kExtension = 0x4, // ::hash (GCC extension)
259 #endif // _MSC_VER
260 };
261 
262 // H is a bitmask of Hash enumerations.
263 // Hashable<H> is hashable via all means specified in H.
264 template <int H>
265 struct Hashable {
266  static constexpr bool HashableBy(Hash h) { return h & H; }
267 };
268 
269 namespace std {
270 template <int H>
271 struct hash<Hashable<H>> {
272  template <class E = Hashable<H>,
273  class = typename std::enable_if<E::HashableBy(kStd)>::type>
274  size_t operator()(E) const {
275  return kStd;
276  }
277 };
278 } // namespace std
279 
280 namespace absl {
281 namespace container_internal {
282 namespace {
283 
284 template <class T>
285 size_t Hash(const T& v) {
286  return hash_default_hash<T>()(v);
287 }
288 
289 TEST(Delegate, HashDispatch) {
290  EXPECT_EQ(Hash(kStd), Hash(Hashable<kStd>()));
291 }
292 
293 } // namespace
294 } // namespace container_internal
295 } // namespace absl
int v
Definition: variant_test.cc:81
hash_default_eq< T > key_eq
TEST(NotificationTest, SanityTest)
typename container_internal::HashEq< T >::Hash hash_default_hash
T::first_type a1
Definition: algorithm.h:29
T::second_type b2
T::second_type b1
hash_default_hash< T > hasher
char * ptr
hash_default_hash< typename T::first_type > hash
T::first_type a2
TYPED_TEST_P(ConstructorTest, NoArgs)
typename container_internal::HashEq< T >::Eq hash_default_eq
#define C(x)
Definition: city_test.cc:47
hash_default_eq< typename T::first_type > eq
absl::hash_internal::Hash< T > Hash
Definition: hash.h:213
static constexpr bool HashableBy(Hash h)


abseil_cpp
Author(s):
autogenerated on Mon Feb 28 2022 21:31:18