Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / third_party / abseil-cpp / absl / container / internal / unordered_map_constructor_test.h
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"
23 #include "absl/container/internal/hash_generator_testing.h"
24 #include "absl/container/internal/hash_policy_testing.h"
25
26 namespace absl {
27 namespace container_internal {
28
29 template <class UnordMap>
30 class ConstructorTest : public ::testing::Test {};
31
32 TYPED_TEST_SUITE_P(ConstructorTest);
33
34 TYPED_TEST_P(ConstructorTest, NoArgs) {
35   TypeParam m;
36   EXPECT_TRUE(m.empty());
37   EXPECT_THAT(m, ::testing::UnorderedElementsAre());
38 }
39
40 TYPED_TEST_P(ConstructorTest, BucketCount) {
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 =
100     absl::disjunction<absl::negation<is_std_unordered_map<T>>,
101                       has_cxx14_std_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>
149 using expect_alloc_constructors =
150     absl::disjunction<absl::negation<is_std_unordered_map<T>>,
151                       has_alloc_std_constructors>;
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
166 TYPED_TEST_P(ConstructorTest, Alloc) {
167   AllocTest<TypeParam>(expect_alloc_constructors<TypeParam>());
168 }
169
170 TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashEqualAlloc) {
171   using T = hash_internal::GeneratedType<TypeParam>;
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,
180                   hash_internal::Generator<T>());
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) {
194   using T = hash_internal::GeneratedType<TypeParam>;
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,
199                   hash_internal::Generator<T>());
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) {
215   using T = hash_internal::GeneratedType<TypeParam>;
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,
222                   hash_internal::Generator<T>());
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) {
235   using T = hash_internal::GeneratedType<TypeParam>;
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) {
256   using T = hash_internal::GeneratedType<TypeParam>;
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) {
279   using T = hash_internal::GeneratedType<TypeParam>;
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) {
301   using T = hash_internal::GeneratedType<TypeParam>;
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) {
325   using T = hash_internal::GeneratedType<TypeParam>;
326   hash_internal::Generator<T> gen;
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) {
347   using T = hash_internal::GeneratedType<TypeParam>;
348   using A = typename TypeParam::allocator_type;
349   hash_internal::Generator<T> gen;
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>
366 void InitializerListBucketHashAllocTest(std::true_type) {
367   using T = hash_internal::GeneratedType<TypeParam>;
368   using H = typename TypeParam::hasher;
369   using A = typename TypeParam::allocator_type;
370   H hasher;
371   A alloc(0);
372   hash_internal::Generator<T> gen;
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
385 TYPED_TEST_P(ConstructorTest, Assignment) {
386   using T = hash_internal::GeneratedType<TypeParam>;
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);
393   hash_internal::Generator<T> gen;
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) {
406   using T = hash_internal::GeneratedType<TypeParam>;
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);
413   hash_internal::Generator<T> gen;
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) {
424   using T = hash_internal::GeneratedType<TypeParam>;
425   hash_internal::Generator<T> gen;
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) {
433   using T = hash_internal::GeneratedType<TypeParam>;
434   hash_internal::Generator<T> gen;
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) {
442   using T = hash_internal::GeneratedType<TypeParam>;
443   hash_internal::Generator<T> gen;
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) {
452   using T = hash_internal::GeneratedType<TypeParam>;
453   hash_internal::Generator<T> gen;
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) {
461   using T = hash_internal::GeneratedType<TypeParam>;
462   hash_internal::Generator<T> gen;
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
473 REGISTER_TYPED_TEST_CASE_P(
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_