unordered_map_constructor_test.h
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 #ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_CONSTRUCTOR_TEST_H_
16 #define ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_CONSTRUCTOR_TEST_H_
17 
18 #include <algorithm>
19 #include <vector>
20 
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
25 
26 namespace absl {
27 namespace container_internal {
28 
29 template <class UnordMap>
30 class ConstructorTest : public ::testing::Test {};
31 
33 
35  TypeParam m;
36  EXPECT_TRUE(m.empty());
37  EXPECT_THAT(m, ::testing::UnorderedElementsAre());
38 }
39 
41  TypeParam m(123);
42  EXPECT_TRUE(m.empty());
43  EXPECT_THAT(m, ::testing::UnorderedElementsAre());
44  EXPECT_GE(m.bucket_count(), 123);
45 }
46 
47 TYPED_TEST_P(ConstructorTest, BucketCountHash) {
48  using H = typename TypeParam::hasher;
49  H hasher;
50  TypeParam m(123, hasher);
51  EXPECT_EQ(m.hash_function(), hasher);
52  EXPECT_TRUE(m.empty());
53  EXPECT_THAT(m, ::testing::UnorderedElementsAre());
54  EXPECT_GE(m.bucket_count(), 123);
55 }
56 
57 TYPED_TEST_P(ConstructorTest, BucketCountHashEqual) {
58  using H = typename TypeParam::hasher;
59  using E = typename TypeParam::key_equal;
60  H hasher;
61  E equal;
62  TypeParam m(123, hasher, equal);
63  EXPECT_EQ(m.hash_function(), hasher);
64  EXPECT_EQ(m.key_eq(), equal);
65  EXPECT_TRUE(m.empty());
66  EXPECT_THAT(m, ::testing::UnorderedElementsAre());
67  EXPECT_GE(m.bucket_count(), 123);
68 }
69 
70 TYPED_TEST_P(ConstructorTest, BucketCountHashEqualAlloc) {
71  using H = typename TypeParam::hasher;
72  using E = typename TypeParam::key_equal;
73  using A = typename TypeParam::allocator_type;
74  H hasher;
75  E equal;
76  A alloc(0);
77  TypeParam m(123, hasher, equal, alloc);
78  EXPECT_EQ(m.hash_function(), hasher);
79  EXPECT_EQ(m.key_eq(), equal);
80  EXPECT_EQ(m.get_allocator(), alloc);
81  EXPECT_TRUE(m.empty());
82  EXPECT_THAT(m, ::testing::UnorderedElementsAre());
83  EXPECT_GE(m.bucket_count(), 123);
84 }
85 
86 template <typename T>
87 struct is_std_unordered_map : std::false_type {};
88 
89 template <typename... T>
90 struct is_std_unordered_map<std::unordered_map<T...>> : std::true_type {};
91 
92 #if defined(UNORDERED_MAP_CXX14) || defined(UNORDERED_MAP_CXX17)
93 using has_cxx14_std_apis = std::true_type;
94 #else
95 using has_cxx14_std_apis = std::false_type;
96 #endif
97 
98 template <typename T>
99 using expect_cxx14_apis =
102 
103 template <typename TypeParam>
104 void BucketCountAllocTest(std::false_type) {}
105 
106 template <typename TypeParam>
107 void BucketCountAllocTest(std::true_type) {
108  using A = typename TypeParam::allocator_type;
109  A alloc(0);
110  TypeParam m(123, alloc);
111  EXPECT_EQ(m.get_allocator(), alloc);
112  EXPECT_TRUE(m.empty());
113  EXPECT_THAT(m, ::testing::UnorderedElementsAre());
114  EXPECT_GE(m.bucket_count(), 123);
115 }
116 
117 TYPED_TEST_P(ConstructorTest, BucketCountAlloc) {
118  BucketCountAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
119 }
120 
121 template <typename TypeParam>
122 void BucketCountHashAllocTest(std::false_type) {}
123 
124 template <typename TypeParam>
125 void BucketCountHashAllocTest(std::true_type) {
126  using H = typename TypeParam::hasher;
127  using A = typename TypeParam::allocator_type;
128  H hasher;
129  A alloc(0);
130  TypeParam m(123, hasher, alloc);
131  EXPECT_EQ(m.hash_function(), hasher);
132  EXPECT_EQ(m.get_allocator(), alloc);
133  EXPECT_TRUE(m.empty());
134  EXPECT_THAT(m, ::testing::UnorderedElementsAre());
135  EXPECT_GE(m.bucket_count(), 123);
136 }
137 
138 TYPED_TEST_P(ConstructorTest, BucketCountHashAlloc) {
139  BucketCountHashAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
140 }
141 
142 #if ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS
143 using has_alloc_std_constructors = std::true_type;
144 #else
145 using has_alloc_std_constructors = std::false_type;
146 #endif
147 
148 template <typename T>
152 
153 template <typename TypeParam>
154 void AllocTest(std::false_type) {}
155 
156 template <typename TypeParam>
157 void AllocTest(std::true_type) {
158  using A = typename TypeParam::allocator_type;
159  A alloc(0);
160  TypeParam m(alloc);
161  EXPECT_EQ(m.get_allocator(), alloc);
162  EXPECT_TRUE(m.empty());
163  EXPECT_THAT(m, ::testing::UnorderedElementsAre());
164 }
165 
167  AllocTest<TypeParam>(expect_alloc_constructors<TypeParam>());
168 }
169 
170 TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashEqualAlloc) {
172  using H = typename TypeParam::hasher;
173  using E = typename TypeParam::key_equal;
174  using A = typename TypeParam::allocator_type;
175  H hasher;
176  E equal;
177  A alloc(0);
178  std::vector<T> values;
179  std::generate_n(std::back_inserter(values), 10,
181  TypeParam m(values.begin(), values.end(), 123, hasher, equal, alloc);
182  EXPECT_EQ(m.hash_function(), hasher);
183  EXPECT_EQ(m.key_eq(), equal);
184  EXPECT_EQ(m.get_allocator(), alloc);
185  EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values));
186  EXPECT_GE(m.bucket_count(), 123);
187 }
188 
189 template <typename TypeParam>
190 void InputIteratorBucketAllocTest(std::false_type) {}
191 
192 template <typename TypeParam>
193 void InputIteratorBucketAllocTest(std::true_type) {
195  using A = typename TypeParam::allocator_type;
196  A alloc(0);
197  std::vector<T> values;
198  std::generate_n(std::back_inserter(values), 10,
200  TypeParam m(values.begin(), values.end(), 123, alloc);
201  EXPECT_EQ(m.get_allocator(), alloc);
202  EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values));
203  EXPECT_GE(m.bucket_count(), 123);
204 }
205 
206 TYPED_TEST_P(ConstructorTest, InputIteratorBucketAlloc) {
207  InputIteratorBucketAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
208 }
209 
210 template <typename TypeParam>
211 void InputIteratorBucketHashAllocTest(std::false_type) {}
212 
213 template <typename TypeParam>
214 void InputIteratorBucketHashAllocTest(std::true_type) {
216  using H = typename TypeParam::hasher;
217  using A = typename TypeParam::allocator_type;
218  H hasher;
219  A alloc(0);
220  std::vector<T> values;
221  std::generate_n(std::back_inserter(values), 10,
223  TypeParam m(values.begin(), values.end(), 123, hasher, alloc);
224  EXPECT_EQ(m.hash_function(), hasher);
225  EXPECT_EQ(m.get_allocator(), alloc);
226  EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values));
227  EXPECT_GE(m.bucket_count(), 123);
228 }
229 
230 TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashAlloc) {
231  InputIteratorBucketHashAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
232 }
233 
234 TYPED_TEST_P(ConstructorTest, CopyConstructor) {
236  using H = typename TypeParam::hasher;
237  using E = typename TypeParam::key_equal;
238  using A = typename TypeParam::allocator_type;
239  H hasher;
240  E equal;
241  A alloc(0);
242  TypeParam m(123, hasher, equal, alloc);
243  for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
244  TypeParam n(m);
245  EXPECT_EQ(m.hash_function(), n.hash_function());
246  EXPECT_EQ(m.key_eq(), n.key_eq());
247  EXPECT_EQ(m.get_allocator(), n.get_allocator());
248  EXPECT_EQ(m, n);
249 }
250 
251 template <typename TypeParam>
252 void CopyConstructorAllocTest(std::false_type) {}
253 
254 template <typename TypeParam>
255 void CopyConstructorAllocTest(std::true_type) {
257  using H = typename TypeParam::hasher;
258  using E = typename TypeParam::key_equal;
259  using A = typename TypeParam::allocator_type;
260  H hasher;
261  E equal;
262  A alloc(0);
263  TypeParam m(123, hasher, equal, alloc);
264  for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
265  TypeParam n(m, A(11));
266  EXPECT_EQ(m.hash_function(), n.hash_function());
267  EXPECT_EQ(m.key_eq(), n.key_eq());
268  EXPECT_NE(m.get_allocator(), n.get_allocator());
269  EXPECT_EQ(m, n);
270 }
271 
272 TYPED_TEST_P(ConstructorTest, CopyConstructorAlloc) {
273  CopyConstructorAllocTest<TypeParam>(expect_alloc_constructors<TypeParam>());
274 }
275 
276 // TODO(alkis): Test non-propagating allocators on copy constructors.
277 
278 TYPED_TEST_P(ConstructorTest, MoveConstructor) {
280  using H = typename TypeParam::hasher;
281  using E = typename TypeParam::key_equal;
282  using A = typename TypeParam::allocator_type;
283  H hasher;
284  E equal;
285  A alloc(0);
286  TypeParam m(123, hasher, equal, alloc);
287  for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
288  TypeParam t(m);
289  TypeParam n(std::move(t));
290  EXPECT_EQ(m.hash_function(), n.hash_function());
291  EXPECT_EQ(m.key_eq(), n.key_eq());
292  EXPECT_EQ(m.get_allocator(), n.get_allocator());
293  EXPECT_EQ(m, n);
294 }
295 
296 template <typename TypeParam>
297 void MoveConstructorAllocTest(std::false_type) {}
298 
299 template <typename TypeParam>
300 void MoveConstructorAllocTest(std::true_type) {
302  using H = typename TypeParam::hasher;
303  using E = typename TypeParam::key_equal;
304  using A = typename TypeParam::allocator_type;
305  H hasher;
306  E equal;
307  A alloc(0);
308  TypeParam m(123, hasher, equal, alloc);
309  for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
310  TypeParam t(m);
311  TypeParam n(std::move(t), A(1));
312  EXPECT_EQ(m.hash_function(), n.hash_function());
313  EXPECT_EQ(m.key_eq(), n.key_eq());
314  EXPECT_NE(m.get_allocator(), n.get_allocator());
315  EXPECT_EQ(m, n);
316 }
317 
318 TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) {
319  MoveConstructorAllocTest<TypeParam>(expect_alloc_constructors<TypeParam>());
320 }
321 
322 // TODO(alkis): Test non-propagating allocators on move constructors.
323 
324 TYPED_TEST_P(ConstructorTest, InitializerListBucketHashEqualAlloc) {
327  std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
328  using H = typename TypeParam::hasher;
329  using E = typename TypeParam::key_equal;
330  using A = typename TypeParam::allocator_type;
331  H hasher;
332  E equal;
333  A alloc(0);
334  TypeParam m(values, 123, hasher, equal, alloc);
335  EXPECT_EQ(m.hash_function(), hasher);
336  EXPECT_EQ(m.key_eq(), equal);
337  EXPECT_EQ(m.get_allocator(), alloc);
338  EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values));
339  EXPECT_GE(m.bucket_count(), 123);
340 }
341 
342 template <typename TypeParam>
343 void InitializerListBucketAllocTest(std::false_type) {}
344 
345 template <typename TypeParam>
346 void InitializerListBucketAllocTest(std::true_type) {
348  using A = typename TypeParam::allocator_type;
350  std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
351  A alloc(0);
352  TypeParam m(values, 123, alloc);
353  EXPECT_EQ(m.get_allocator(), alloc);
354  EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values));
355  EXPECT_GE(m.bucket_count(), 123);
356 }
357 
358 TYPED_TEST_P(ConstructorTest, InitializerListBucketAlloc) {
359  InitializerListBucketAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
360 }
361 
362 template <typename TypeParam>
363 void InitializerListBucketHashAllocTest(std::false_type) {}
364 
365 template <typename TypeParam>
368  using H = typename TypeParam::hasher;
369  using A = typename TypeParam::allocator_type;
370  H hasher;
371  A alloc(0);
373  std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
374  TypeParam m(values, 123, hasher, alloc);
375  EXPECT_EQ(m.hash_function(), hasher);
376  EXPECT_EQ(m.get_allocator(), alloc);
377  EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values));
378  EXPECT_GE(m.bucket_count(), 123);
379 }
380 
381 TYPED_TEST_P(ConstructorTest, InitializerListBucketHashAlloc) {
382  InitializerListBucketHashAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
383 }
384 
387  using H = typename TypeParam::hasher;
388  using E = typename TypeParam::key_equal;
389  using A = typename TypeParam::allocator_type;
390  H hasher;
391  E equal;
392  A alloc(0);
394  TypeParam m({gen(), gen(), gen()}, 123, hasher, equal, alloc);
395  TypeParam n;
396  n = m;
397  EXPECT_EQ(m.hash_function(), n.hash_function());
398  EXPECT_EQ(m.key_eq(), n.key_eq());
399  EXPECT_EQ(m, n);
400 }
401 
402 // TODO(alkis): Test [non-]propagating allocators on move/copy assignments
403 // (it depends on traits).
404 
405 TYPED_TEST_P(ConstructorTest, MoveAssignment) {
407  using H = typename TypeParam::hasher;
408  using E = typename TypeParam::key_equal;
409  using A = typename TypeParam::allocator_type;
410  H hasher;
411  E equal;
412  A alloc(0);
414  TypeParam m({gen(), gen(), gen()}, 123, hasher, equal, alloc);
415  TypeParam t(m);
416  TypeParam n;
417  n = std::move(t);
418  EXPECT_EQ(m.hash_function(), n.hash_function());
419  EXPECT_EQ(m.key_eq(), n.key_eq());
420  EXPECT_EQ(m, n);
421 }
422 
423 TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerList) {
426  std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
427  TypeParam m;
428  m = values;
429  EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values));
430 }
431 
432 TYPED_TEST_P(ConstructorTest, AssignmentOverwritesExisting) {
435  TypeParam m({gen(), gen(), gen()});
436  TypeParam n({gen()});
437  n = m;
438  EXPECT_EQ(m, n);
439 }
440 
441 TYPED_TEST_P(ConstructorTest, MoveAssignmentOverwritesExisting) {
444  TypeParam m({gen(), gen(), gen()});
445  TypeParam t(m);
446  TypeParam n({gen()});
447  n = std::move(t);
448  EXPECT_EQ(m, n);
449 }
450 
451 TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerListOverwritesExisting) {
454  std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
455  TypeParam m;
456  m = values;
457  EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values));
458 }
459 
460 TYPED_TEST_P(ConstructorTest, AssignmentOnSelf) {
463  std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
464  TypeParam m(values);
465  m = *&m; // Avoid -Wself-assign
466  EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values));
467 }
468 
469 // We cannot test self move as standard states that it leaves standard
470 // containers in unspecified state (and in practice in causes memory-leak
471 // according to heap-checker!).
472 
474  ConstructorTest, NoArgs, BucketCount, BucketCountHash, BucketCountHashEqual,
475  BucketCountHashEqualAlloc, BucketCountAlloc, BucketCountHashAlloc, Alloc,
476  InputIteratorBucketHashEqualAlloc, InputIteratorBucketAlloc,
477  InputIteratorBucketHashAlloc, CopyConstructor, CopyConstructorAlloc,
478  MoveConstructor, MoveConstructorAlloc, InitializerListBucketHashEqualAlloc,
479  InitializerListBucketAlloc, InitializerListBucketHashAlloc, Assignment,
480  MoveAssignment, AssignmentFromInitializerList, AssignmentOverwritesExisting,
481  MoveAssignmentOverwritesExisting,
482  AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf);
483 
484 } // namespace container_internal
485 } // namespace absl
486 
487 #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_CONSTRUCTOR_TEST_H_
auto items(const Map &m) -> std::vector< std::pair< typename Map::key_type, typename Map::mapped_type >>
void InitializerListBucketHashAllocTest(std::false_type)
void MoveConstructorAllocTest(std::false_type)
void InputIteratorBucketHashAllocTest(std::false_type)
TYPED_TEST_SUITE_P(ConstructorTest)
void InitializerListBucketAllocTest(std::false_type)
Definition: algorithm.h:29
hash_default_hash< T > hasher
bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2, Pred &&pred)
Definition: algorithm.h:99
void InputIteratorBucketAllocTest(std::false_type)
TYPED_TEST_P(ConstructorTest, NoArgs)
decltype(std::declval< const Generator< typename std::conditional< generator_internal::IsMap< Container >::value, typename Container::value_type, typename Container::key_type >::type > & >()()) GeneratedType
std::allocator< int > alloc
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: utility.h:219
void CopyConstructorAllocTest(std::false_type)
REGISTER_TYPED_TEST_CASE_P(ConstructorTest, NoArgs, BucketCount, BucketCountHash, BucketCountHashEqual, BucketCountHashEqualAlloc, BucketCountAlloc, BucketCountHashAlloc, Alloc, InputIteratorBucketHashEqualAlloc, InputIteratorBucketAlloc, InputIteratorBucketHashAlloc, CopyConstructor, CopyConstructorAlloc, MoveConstructor, MoveConstructorAlloc, InitializerListBucketHashEqualAlloc, InitializerListBucketAlloc, InitializerListBucketHashAlloc, Assignment, MoveAssignment, AssignmentFromInitializerList, AssignmentOverwritesExisting, MoveAssignmentOverwritesExisting, AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf)
void BucketCountHashAllocTest(std::false_type)


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