00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_
00016 #define ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_
00017
00018 #include <algorithm>
00019 #include <unordered_set>
00020 #include <vector>
00021
00022 #include "gmock/gmock.h"
00023 #include "gtest/gtest.h"
00024 #include "absl/container/internal/hash_generator_testing.h"
00025 #include "absl/container/internal/hash_policy_testing.h"
00026 #include "absl/meta/type_traits.h"
00027
00028 namespace absl {
00029 namespace container_internal {
00030
00031 template <class UnordMap>
00032 class ConstructorTest : public ::testing::Test {};
00033
00034 TYPED_TEST_SUITE_P(ConstructorTest);
00035
00036 TYPED_TEST_P(ConstructorTest, NoArgs) {
00037 TypeParam m;
00038 EXPECT_TRUE(m.empty());
00039 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
00040 }
00041
00042 TYPED_TEST_P(ConstructorTest, BucketCount) {
00043 TypeParam m(123);
00044 EXPECT_TRUE(m.empty());
00045 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
00046 EXPECT_GE(m.bucket_count(), 123);
00047 }
00048
00049 TYPED_TEST_P(ConstructorTest, BucketCountHash) {
00050 using H = typename TypeParam::hasher;
00051 H hasher;
00052 TypeParam m(123, hasher);
00053 EXPECT_EQ(m.hash_function(), hasher);
00054 EXPECT_TRUE(m.empty());
00055 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
00056 EXPECT_GE(m.bucket_count(), 123);
00057 }
00058
00059 TYPED_TEST_P(ConstructorTest, BucketCountHashEqual) {
00060 using H = typename TypeParam::hasher;
00061 using E = typename TypeParam::key_equal;
00062 H hasher;
00063 E equal;
00064 TypeParam m(123, hasher, equal);
00065 EXPECT_EQ(m.hash_function(), hasher);
00066 EXPECT_EQ(m.key_eq(), equal);
00067 EXPECT_TRUE(m.empty());
00068 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
00069 EXPECT_GE(m.bucket_count(), 123);
00070 }
00071
00072 TYPED_TEST_P(ConstructorTest, BucketCountHashEqualAlloc) {
00073 using H = typename TypeParam::hasher;
00074 using E = typename TypeParam::key_equal;
00075 using A = typename TypeParam::allocator_type;
00076 H hasher;
00077 E equal;
00078 A alloc(0);
00079 TypeParam m(123, hasher, equal, alloc);
00080 EXPECT_EQ(m.hash_function(), hasher);
00081 EXPECT_EQ(m.key_eq(), equal);
00082 EXPECT_EQ(m.get_allocator(), alloc);
00083 EXPECT_TRUE(m.empty());
00084 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
00085 EXPECT_GE(m.bucket_count(), 123);
00086
00087 const auto& cm = m;
00088 EXPECT_EQ(cm.hash_function(), hasher);
00089 EXPECT_EQ(cm.key_eq(), equal);
00090 EXPECT_EQ(cm.get_allocator(), alloc);
00091 EXPECT_TRUE(cm.empty());
00092 EXPECT_THAT(keys(cm), ::testing::UnorderedElementsAre());
00093 EXPECT_GE(cm.bucket_count(), 123);
00094 }
00095
00096 template <typename T>
00097 struct is_std_unordered_set : std::false_type {};
00098
00099 template <typename... T>
00100 struct is_std_unordered_set<std::unordered_set<T...>> : std::true_type {};
00101
00102 #if defined(UNORDERED_SET_CXX14) || defined(UNORDERED_SET_CXX17)
00103 using has_cxx14_std_apis = std::true_type;
00104 #else
00105 using has_cxx14_std_apis = std::false_type;
00106 #endif
00107
00108 template <typename T>
00109 using expect_cxx14_apis =
00110 absl::disjunction<absl::negation<is_std_unordered_set<T>>,
00111 has_cxx14_std_apis>;
00112
00113 template <typename TypeParam>
00114 void BucketCountAllocTest(std::false_type) {}
00115
00116 template <typename TypeParam>
00117 void BucketCountAllocTest(std::true_type) {
00118 using A = typename TypeParam::allocator_type;
00119 A alloc(0);
00120 TypeParam m(123, alloc);
00121 EXPECT_EQ(m.get_allocator(), alloc);
00122 EXPECT_TRUE(m.empty());
00123 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
00124 EXPECT_GE(m.bucket_count(), 123);
00125 }
00126
00127 TYPED_TEST_P(ConstructorTest, BucketCountAlloc) {
00128 BucketCountAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
00129 }
00130
00131 template <typename TypeParam>
00132 void BucketCountHashAllocTest(std::false_type) {}
00133
00134 template <typename TypeParam>
00135 void BucketCountHashAllocTest(std::true_type) {
00136 using H = typename TypeParam::hasher;
00137 using A = typename TypeParam::allocator_type;
00138 H hasher;
00139 A alloc(0);
00140 TypeParam m(123, hasher, alloc);
00141 EXPECT_EQ(m.hash_function(), hasher);
00142 EXPECT_EQ(m.get_allocator(), alloc);
00143 EXPECT_TRUE(m.empty());
00144 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
00145 EXPECT_GE(m.bucket_count(), 123);
00146 }
00147
00148 TYPED_TEST_P(ConstructorTest, BucketCountHashAlloc) {
00149 BucketCountHashAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
00150 }
00151
00152 #if ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS
00153 using has_alloc_std_constructors = std::true_type;
00154 #else
00155 using has_alloc_std_constructors = std::false_type;
00156 #endif
00157
00158 template <typename T>
00159 using expect_alloc_constructors =
00160 absl::disjunction<absl::negation<is_std_unordered_set<T>>,
00161 has_alloc_std_constructors>;
00162
00163 template <typename TypeParam>
00164 void AllocTest(std::false_type) {}
00165
00166 template <typename TypeParam>
00167 void AllocTest(std::true_type) {
00168 using A = typename TypeParam::allocator_type;
00169 A alloc(0);
00170 TypeParam m(alloc);
00171 EXPECT_EQ(m.get_allocator(), alloc);
00172 EXPECT_TRUE(m.empty());
00173 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
00174 }
00175
00176 TYPED_TEST_P(ConstructorTest, Alloc) {
00177 AllocTest<TypeParam>(expect_alloc_constructors<TypeParam>());
00178 }
00179
00180 TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashEqualAlloc) {
00181 using T = hash_internal::GeneratedType<TypeParam>;
00182 using H = typename TypeParam::hasher;
00183 using E = typename TypeParam::key_equal;
00184 using A = typename TypeParam::allocator_type;
00185 H hasher;
00186 E equal;
00187 A alloc(0);
00188 std::vector<T> values;
00189 for (size_t i = 0; i != 10; ++i)
00190 values.push_back(hash_internal::Generator<T>()());
00191 TypeParam m(values.begin(), values.end(), 123, hasher, equal, alloc);
00192 EXPECT_EQ(m.hash_function(), hasher);
00193 EXPECT_EQ(m.key_eq(), equal);
00194 EXPECT_EQ(m.get_allocator(), alloc);
00195 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
00196 EXPECT_GE(m.bucket_count(), 123);
00197 }
00198
00199 template <typename TypeParam>
00200 void InputIteratorBucketAllocTest(std::false_type) {}
00201
00202 template <typename TypeParam>
00203 void InputIteratorBucketAllocTest(std::true_type) {
00204 using T = hash_internal::GeneratedType<TypeParam>;
00205 using A = typename TypeParam::allocator_type;
00206 A alloc(0);
00207 std::vector<T> values;
00208 for (size_t i = 0; i != 10; ++i)
00209 values.push_back(hash_internal::Generator<T>()());
00210 TypeParam m(values.begin(), values.end(), 123, alloc);
00211 EXPECT_EQ(m.get_allocator(), alloc);
00212 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
00213 EXPECT_GE(m.bucket_count(), 123);
00214 }
00215
00216 TYPED_TEST_P(ConstructorTest, InputIteratorBucketAlloc) {
00217 InputIteratorBucketAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
00218 }
00219
00220 template <typename TypeParam>
00221 void InputIteratorBucketHashAllocTest(std::false_type) {}
00222
00223 template <typename TypeParam>
00224 void InputIteratorBucketHashAllocTest(std::true_type) {
00225 using T = hash_internal::GeneratedType<TypeParam>;
00226 using H = typename TypeParam::hasher;
00227 using A = typename TypeParam::allocator_type;
00228 H hasher;
00229 A alloc(0);
00230 std::vector<T> values;
00231 for (size_t i = 0; i != 10; ++i)
00232 values.push_back(hash_internal::Generator<T>()());
00233 TypeParam m(values.begin(), values.end(), 123, hasher, alloc);
00234 EXPECT_EQ(m.hash_function(), hasher);
00235 EXPECT_EQ(m.get_allocator(), alloc);
00236 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
00237 EXPECT_GE(m.bucket_count(), 123);
00238 }
00239
00240 TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashAlloc) {
00241 InputIteratorBucketHashAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
00242 }
00243
00244 TYPED_TEST_P(ConstructorTest, CopyConstructor) {
00245 using T = hash_internal::GeneratedType<TypeParam>;
00246 using H = typename TypeParam::hasher;
00247 using E = typename TypeParam::key_equal;
00248 using A = typename TypeParam::allocator_type;
00249 H hasher;
00250 E equal;
00251 A alloc(0);
00252 TypeParam m(123, hasher, equal, alloc);
00253 for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
00254 TypeParam n(m);
00255 EXPECT_EQ(m.hash_function(), n.hash_function());
00256 EXPECT_EQ(m.key_eq(), n.key_eq());
00257 EXPECT_EQ(m.get_allocator(), n.get_allocator());
00258 EXPECT_EQ(m, n);
00259 EXPECT_NE(TypeParam(0, hasher, equal, alloc), n);
00260 }
00261
00262 template <typename TypeParam>
00263 void CopyConstructorAllocTest(std::false_type) {}
00264
00265 template <typename TypeParam>
00266 void CopyConstructorAllocTest(std::true_type) {
00267 using T = hash_internal::GeneratedType<TypeParam>;
00268 using H = typename TypeParam::hasher;
00269 using E = typename TypeParam::key_equal;
00270 using A = typename TypeParam::allocator_type;
00271 H hasher;
00272 E equal;
00273 A alloc(0);
00274 TypeParam m(123, hasher, equal, alloc);
00275 for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
00276 TypeParam n(m, A(11));
00277 EXPECT_EQ(m.hash_function(), n.hash_function());
00278 EXPECT_EQ(m.key_eq(), n.key_eq());
00279 EXPECT_NE(m.get_allocator(), n.get_allocator());
00280 EXPECT_EQ(m, n);
00281 }
00282
00283 TYPED_TEST_P(ConstructorTest, CopyConstructorAlloc) {
00284 CopyConstructorAllocTest<TypeParam>(expect_alloc_constructors<TypeParam>());
00285 }
00286
00287
00288
00289 TYPED_TEST_P(ConstructorTest, MoveConstructor) {
00290 using T = hash_internal::GeneratedType<TypeParam>;
00291 using H = typename TypeParam::hasher;
00292 using E = typename TypeParam::key_equal;
00293 using A = typename TypeParam::allocator_type;
00294 H hasher;
00295 E equal;
00296 A alloc(0);
00297 TypeParam m(123, hasher, equal, alloc);
00298 for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
00299 TypeParam t(m);
00300 TypeParam n(std::move(t));
00301 EXPECT_EQ(m.hash_function(), n.hash_function());
00302 EXPECT_EQ(m.key_eq(), n.key_eq());
00303 EXPECT_EQ(m.get_allocator(), n.get_allocator());
00304 EXPECT_EQ(m, n);
00305 }
00306
00307 template <typename TypeParam>
00308 void MoveConstructorAllocTest(std::false_type) {}
00309
00310 template <typename TypeParam>
00311 void MoveConstructorAllocTest(std::true_type) {
00312 using T = hash_internal::GeneratedType<TypeParam>;
00313 using H = typename TypeParam::hasher;
00314 using E = typename TypeParam::key_equal;
00315 using A = typename TypeParam::allocator_type;
00316 H hasher;
00317 E equal;
00318 A alloc(0);
00319 TypeParam m(123, hasher, equal, alloc);
00320 for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
00321 TypeParam t(m);
00322 TypeParam n(std::move(t), A(1));
00323 EXPECT_EQ(m.hash_function(), n.hash_function());
00324 EXPECT_EQ(m.key_eq(), n.key_eq());
00325 EXPECT_NE(m.get_allocator(), n.get_allocator());
00326 EXPECT_EQ(m, n);
00327 }
00328
00329 TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) {
00330 MoveConstructorAllocTest<TypeParam>(expect_alloc_constructors<TypeParam>());
00331 }
00332
00333
00334
00335 TYPED_TEST_P(ConstructorTest, InitializerListBucketHashEqualAlloc) {
00336 using T = hash_internal::GeneratedType<TypeParam>;
00337 hash_internal::Generator<T> gen;
00338 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
00339 using H = typename TypeParam::hasher;
00340 using E = typename TypeParam::key_equal;
00341 using A = typename TypeParam::allocator_type;
00342 H hasher;
00343 E equal;
00344 A alloc(0);
00345 TypeParam m(values, 123, hasher, equal, alloc);
00346 EXPECT_EQ(m.hash_function(), hasher);
00347 EXPECT_EQ(m.key_eq(), equal);
00348 EXPECT_EQ(m.get_allocator(), alloc);
00349 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
00350 EXPECT_GE(m.bucket_count(), 123);
00351 }
00352
00353 template <typename TypeParam>
00354 void InitializerListBucketAllocTest(std::false_type) {}
00355
00356 template <typename TypeParam>
00357 void InitializerListBucketAllocTest(std::true_type) {
00358 using T = hash_internal::GeneratedType<TypeParam>;
00359 using A = typename TypeParam::allocator_type;
00360 hash_internal::Generator<T> gen;
00361 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
00362 A alloc(0);
00363 TypeParam m(values, 123, alloc);
00364 EXPECT_EQ(m.get_allocator(), alloc);
00365 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
00366 EXPECT_GE(m.bucket_count(), 123);
00367 }
00368
00369 TYPED_TEST_P(ConstructorTest, InitializerListBucketAlloc) {
00370 InitializerListBucketAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
00371 }
00372
00373 template <typename TypeParam>
00374 void InitializerListBucketHashAllocTest(std::false_type) {}
00375
00376 template <typename TypeParam>
00377 void InitializerListBucketHashAllocTest(std::true_type) {
00378 using T = hash_internal::GeneratedType<TypeParam>;
00379 using H = typename TypeParam::hasher;
00380 using A = typename TypeParam::allocator_type;
00381 H hasher;
00382 A alloc(0);
00383 hash_internal::Generator<T> gen;
00384 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
00385 TypeParam m(values, 123, hasher, alloc);
00386 EXPECT_EQ(m.hash_function(), hasher);
00387 EXPECT_EQ(m.get_allocator(), alloc);
00388 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
00389 EXPECT_GE(m.bucket_count(), 123);
00390 }
00391
00392 TYPED_TEST_P(ConstructorTest, InitializerListBucketHashAlloc) {
00393 InitializerListBucketHashAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
00394 }
00395
00396 TYPED_TEST_P(ConstructorTest, CopyAssignment) {
00397 using T = hash_internal::GeneratedType<TypeParam>;
00398 using H = typename TypeParam::hasher;
00399 using E = typename TypeParam::key_equal;
00400 using A = typename TypeParam::allocator_type;
00401 H hasher;
00402 E equal;
00403 A alloc(0);
00404 hash_internal::Generator<T> gen;
00405 TypeParam m({gen(), gen(), gen()}, 123, hasher, equal, alloc);
00406 TypeParam n;
00407 n = m;
00408 EXPECT_EQ(m.hash_function(), n.hash_function());
00409 EXPECT_EQ(m.key_eq(), n.key_eq());
00410 EXPECT_EQ(m, n);
00411 }
00412
00413
00414
00415
00416 TYPED_TEST_P(ConstructorTest, MoveAssignment) {
00417 using T = hash_internal::GeneratedType<TypeParam>;
00418 using H = typename TypeParam::hasher;
00419 using E = typename TypeParam::key_equal;
00420 using A = typename TypeParam::allocator_type;
00421 H hasher;
00422 E equal;
00423 A alloc(0);
00424 hash_internal::Generator<T> gen;
00425 TypeParam m({gen(), gen(), gen()}, 123, hasher, equal, alloc);
00426 TypeParam t(m);
00427 TypeParam n;
00428 n = std::move(t);
00429 EXPECT_EQ(m.hash_function(), n.hash_function());
00430 EXPECT_EQ(m.key_eq(), n.key_eq());
00431 EXPECT_EQ(m, n);
00432 }
00433
00434 TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerList) {
00435 using T = hash_internal::GeneratedType<TypeParam>;
00436 hash_internal::Generator<T> gen;
00437 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
00438 TypeParam m;
00439 m = values;
00440 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
00441 }
00442
00443 TYPED_TEST_P(ConstructorTest, AssignmentOverwritesExisting) {
00444 using T = hash_internal::GeneratedType<TypeParam>;
00445 hash_internal::Generator<T> gen;
00446 TypeParam m({gen(), gen(), gen()});
00447 TypeParam n({gen()});
00448 n = m;
00449 EXPECT_EQ(m, n);
00450 }
00451
00452 TYPED_TEST_P(ConstructorTest, MoveAssignmentOverwritesExisting) {
00453 using T = hash_internal::GeneratedType<TypeParam>;
00454 hash_internal::Generator<T> gen;
00455 TypeParam m({gen(), gen(), gen()});
00456 TypeParam t(m);
00457 TypeParam n({gen()});
00458 n = std::move(t);
00459 EXPECT_EQ(m, n);
00460 }
00461
00462 TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerListOverwritesExisting) {
00463 using T = hash_internal::GeneratedType<TypeParam>;
00464 hash_internal::Generator<T> gen;
00465 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
00466 TypeParam m;
00467 m = values;
00468 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
00469 }
00470
00471 TYPED_TEST_P(ConstructorTest, AssignmentOnSelf) {
00472 using T = hash_internal::GeneratedType<TypeParam>;
00473 hash_internal::Generator<T> gen;
00474 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
00475 TypeParam m(values);
00476 m = *&m;
00477 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
00478 }
00479
00480 REGISTER_TYPED_TEST_CASE_P(
00481 ConstructorTest, NoArgs, BucketCount, BucketCountHash, BucketCountHashEqual,
00482 BucketCountHashEqualAlloc, BucketCountAlloc, BucketCountHashAlloc, Alloc,
00483 InputIteratorBucketHashEqualAlloc, InputIteratorBucketAlloc,
00484 InputIteratorBucketHashAlloc, CopyConstructor, CopyConstructorAlloc,
00485 MoveConstructor, MoveConstructorAlloc, InitializerListBucketHashEqualAlloc,
00486 InitializerListBucketAlloc, InitializerListBucketHashAlloc, CopyAssignment,
00487 MoveAssignment, AssignmentFromInitializerList, AssignmentOverwritesExisting,
00488 MoveAssignmentOverwritesExisting,
00489 AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf);
00490
00491 }
00492 }
00493
00494 #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_