File indexing completed on 2025-01-30 09:31:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_
0016 #define ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_
0017
0018 #include <algorithm>
0019 #include <unordered_set>
0020 #include <vector>
0021
0022 #include "gmock/gmock.h"
0023 #include "gtest/gtest.h"
0024 #include "absl/container/internal/hash_generator_testing.h"
0025 #include "absl/container/internal/hash_policy_testing.h"
0026 #include "absl/meta/type_traits.h"
0027
0028 namespace absl {
0029 ABSL_NAMESPACE_BEGIN
0030 namespace container_internal {
0031
0032 template <class UnordMap>
0033 class ConstructorTest : public ::testing::Test {};
0034
0035 TYPED_TEST_SUITE_P(ConstructorTest);
0036
0037 TYPED_TEST_P(ConstructorTest, NoArgs) {
0038 TypeParam m;
0039 EXPECT_TRUE(m.empty());
0040 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
0041 }
0042
0043 TYPED_TEST_P(ConstructorTest, BucketCount) {
0044 TypeParam m(123);
0045 EXPECT_TRUE(m.empty());
0046 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
0047 EXPECT_GE(m.bucket_count(), 123);
0048 }
0049
0050 TYPED_TEST_P(ConstructorTest, BucketCountHash) {
0051 using H = typename TypeParam::hasher;
0052 H hasher;
0053 TypeParam m(123, hasher);
0054 EXPECT_EQ(m.hash_function(), hasher);
0055 EXPECT_TRUE(m.empty());
0056 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
0057 EXPECT_GE(m.bucket_count(), 123);
0058 }
0059
0060 TYPED_TEST_P(ConstructorTest, BucketCountHashEqual) {
0061 using H = typename TypeParam::hasher;
0062 using E = typename TypeParam::key_equal;
0063 H hasher;
0064 E equal;
0065 TypeParam m(123, hasher, equal);
0066 EXPECT_EQ(m.hash_function(), hasher);
0067 EXPECT_EQ(m.key_eq(), equal);
0068 EXPECT_TRUE(m.empty());
0069 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
0070 EXPECT_GE(m.bucket_count(), 123);
0071 }
0072
0073 TYPED_TEST_P(ConstructorTest, BucketCountHashEqualAlloc) {
0074 using H = typename TypeParam::hasher;
0075 using E = typename TypeParam::key_equal;
0076 using A = typename TypeParam::allocator_type;
0077 H hasher;
0078 E equal;
0079 A alloc(0);
0080 TypeParam m(123, hasher, equal, alloc);
0081 EXPECT_EQ(m.hash_function(), hasher);
0082 EXPECT_EQ(m.key_eq(), equal);
0083 EXPECT_EQ(m.get_allocator(), alloc);
0084 EXPECT_TRUE(m.empty());
0085 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
0086 EXPECT_GE(m.bucket_count(), 123);
0087
0088 const auto& cm = m;
0089 EXPECT_EQ(cm.hash_function(), hasher);
0090 EXPECT_EQ(cm.key_eq(), equal);
0091 EXPECT_EQ(cm.get_allocator(), alloc);
0092 EXPECT_TRUE(cm.empty());
0093 EXPECT_THAT(keys(cm), ::testing::UnorderedElementsAre());
0094 EXPECT_GE(cm.bucket_count(), 123);
0095 }
0096
0097 template <typename T>
0098 struct is_std_unordered_set : std::false_type {};
0099
0100 template <typename... T>
0101 struct is_std_unordered_set<std::unordered_set<T...>> : std::true_type {};
0102
0103 #if defined(UNORDERED_SET_CXX14) || defined(UNORDERED_SET_CXX17)
0104 using has_cxx14_std_apis = std::true_type;
0105 #else
0106 using has_cxx14_std_apis = std::false_type;
0107 #endif
0108
0109 template <typename T>
0110 using expect_cxx14_apis =
0111 absl::disjunction<absl::negation<is_std_unordered_set<T>>,
0112 has_cxx14_std_apis>;
0113
0114 template <typename TypeParam>
0115 void BucketCountAllocTest(std::false_type) {}
0116
0117 template <typename TypeParam>
0118 void BucketCountAllocTest(std::true_type) {
0119 using A = typename TypeParam::allocator_type;
0120 A alloc(0);
0121 TypeParam m(123, alloc);
0122 EXPECT_EQ(m.get_allocator(), alloc);
0123 EXPECT_TRUE(m.empty());
0124 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
0125 EXPECT_GE(m.bucket_count(), 123);
0126 }
0127
0128 TYPED_TEST_P(ConstructorTest, BucketCountAlloc) {
0129 BucketCountAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
0130 }
0131
0132 template <typename TypeParam>
0133 void BucketCountHashAllocTest(std::false_type) {}
0134
0135 template <typename TypeParam>
0136 void BucketCountHashAllocTest(std::true_type) {
0137 using H = typename TypeParam::hasher;
0138 using A = typename TypeParam::allocator_type;
0139 H hasher;
0140 A alloc(0);
0141 TypeParam m(123, hasher, alloc);
0142 EXPECT_EQ(m.hash_function(), hasher);
0143 EXPECT_EQ(m.get_allocator(), alloc);
0144 EXPECT_TRUE(m.empty());
0145 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
0146 EXPECT_GE(m.bucket_count(), 123);
0147 }
0148
0149 TYPED_TEST_P(ConstructorTest, BucketCountHashAlloc) {
0150 BucketCountHashAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
0151 }
0152
0153 #if ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS
0154 using has_alloc_std_constructors = std::true_type;
0155 #else
0156 using has_alloc_std_constructors = std::false_type;
0157 #endif
0158
0159 template <typename T>
0160 using expect_alloc_constructors =
0161 absl::disjunction<absl::negation<is_std_unordered_set<T>>,
0162 has_alloc_std_constructors>;
0163
0164 template <typename TypeParam>
0165 void AllocTest(std::false_type) {}
0166
0167 template <typename TypeParam>
0168 void AllocTest(std::true_type) {
0169 using A = typename TypeParam::allocator_type;
0170 A alloc(0);
0171 TypeParam m(alloc);
0172 EXPECT_EQ(m.get_allocator(), alloc);
0173 EXPECT_TRUE(m.empty());
0174 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
0175 }
0176
0177 TYPED_TEST_P(ConstructorTest, Alloc) {
0178 AllocTest<TypeParam>(expect_alloc_constructors<TypeParam>());
0179 }
0180
0181 TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashEqualAlloc) {
0182 using T = hash_internal::GeneratedType<TypeParam>;
0183 using H = typename TypeParam::hasher;
0184 using E = typename TypeParam::key_equal;
0185 using A = typename TypeParam::allocator_type;
0186 H hasher;
0187 E equal;
0188 A alloc(0);
0189 std::vector<T> values;
0190 for (size_t i = 0; i != 10; ++i)
0191 values.push_back(hash_internal::Generator<T>()());
0192 TypeParam m(values.begin(), values.end(), 123, hasher, equal, alloc);
0193 EXPECT_EQ(m.hash_function(), hasher);
0194 EXPECT_EQ(m.key_eq(), equal);
0195 EXPECT_EQ(m.get_allocator(), alloc);
0196 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
0197 EXPECT_GE(m.bucket_count(), 123);
0198 }
0199
0200 template <typename TypeParam>
0201 void InputIteratorBucketAllocTest(std::false_type) {}
0202
0203 template <typename TypeParam>
0204 void InputIteratorBucketAllocTest(std::true_type) {
0205 using T = hash_internal::GeneratedType<TypeParam>;
0206 using A = typename TypeParam::allocator_type;
0207 A alloc(0);
0208 std::vector<T> values;
0209 for (size_t i = 0; i != 10; ++i)
0210 values.push_back(hash_internal::Generator<T>()());
0211 TypeParam m(values.begin(), values.end(), 123, alloc);
0212 EXPECT_EQ(m.get_allocator(), alloc);
0213 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
0214 EXPECT_GE(m.bucket_count(), 123);
0215 }
0216
0217 TYPED_TEST_P(ConstructorTest, InputIteratorBucketAlloc) {
0218 InputIteratorBucketAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
0219 }
0220
0221 template <typename TypeParam>
0222 void InputIteratorBucketHashAllocTest(std::false_type) {}
0223
0224 template <typename TypeParam>
0225 void InputIteratorBucketHashAllocTest(std::true_type) {
0226 using T = hash_internal::GeneratedType<TypeParam>;
0227 using H = typename TypeParam::hasher;
0228 using A = typename TypeParam::allocator_type;
0229 H hasher;
0230 A alloc(0);
0231 std::vector<T> values;
0232 for (size_t i = 0; i != 10; ++i)
0233 values.push_back(hash_internal::Generator<T>()());
0234 TypeParam m(values.begin(), values.end(), 123, hasher, alloc);
0235 EXPECT_EQ(m.hash_function(), hasher);
0236 EXPECT_EQ(m.get_allocator(), alloc);
0237 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
0238 EXPECT_GE(m.bucket_count(), 123);
0239 }
0240
0241 TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashAlloc) {
0242 InputIteratorBucketHashAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
0243 }
0244
0245 TYPED_TEST_P(ConstructorTest, CopyConstructor) {
0246 using T = hash_internal::GeneratedType<TypeParam>;
0247 using H = typename TypeParam::hasher;
0248 using E = typename TypeParam::key_equal;
0249 using A = typename TypeParam::allocator_type;
0250 H hasher;
0251 E equal;
0252 A alloc(0);
0253 TypeParam m(123, hasher, equal, alloc);
0254 for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
0255 TypeParam n(m);
0256 EXPECT_EQ(m.hash_function(), n.hash_function());
0257 EXPECT_EQ(m.key_eq(), n.key_eq());
0258 EXPECT_EQ(m.get_allocator(), n.get_allocator());
0259 EXPECT_EQ(m, n);
0260 EXPECT_NE(TypeParam(0, hasher, equal, alloc), n);
0261 }
0262
0263 template <typename TypeParam>
0264 void CopyConstructorAllocTest(std::false_type) {}
0265
0266 template <typename TypeParam>
0267 void CopyConstructorAllocTest(std::true_type) {
0268 using T = hash_internal::GeneratedType<TypeParam>;
0269 using H = typename TypeParam::hasher;
0270 using E = typename TypeParam::key_equal;
0271 using A = typename TypeParam::allocator_type;
0272 H hasher;
0273 E equal;
0274 A alloc(0);
0275 TypeParam m(123, hasher, equal, alloc);
0276 for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
0277 TypeParam n(m, A(11));
0278 EXPECT_EQ(m.hash_function(), n.hash_function());
0279 EXPECT_EQ(m.key_eq(), n.key_eq());
0280 EXPECT_NE(m.get_allocator(), n.get_allocator());
0281 EXPECT_EQ(m, n);
0282 }
0283
0284 TYPED_TEST_P(ConstructorTest, CopyConstructorAlloc) {
0285 CopyConstructorAllocTest<TypeParam>(expect_alloc_constructors<TypeParam>());
0286 }
0287
0288
0289
0290 TYPED_TEST_P(ConstructorTest, MoveConstructor) {
0291 using T = hash_internal::GeneratedType<TypeParam>;
0292 using H = typename TypeParam::hasher;
0293 using E = typename TypeParam::key_equal;
0294 using A = typename TypeParam::allocator_type;
0295 H hasher;
0296 E equal;
0297 A alloc(0);
0298 TypeParam m(123, hasher, equal, alloc);
0299 for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
0300 TypeParam t(m);
0301 TypeParam n(std::move(t));
0302 EXPECT_EQ(m.hash_function(), n.hash_function());
0303 EXPECT_EQ(m.key_eq(), n.key_eq());
0304 EXPECT_EQ(m.get_allocator(), n.get_allocator());
0305 EXPECT_EQ(m, n);
0306 }
0307
0308 template <typename TypeParam>
0309 void MoveConstructorAllocTest(std::false_type) {}
0310
0311 template <typename TypeParam>
0312 void MoveConstructorAllocTest(std::true_type) {
0313 using T = hash_internal::GeneratedType<TypeParam>;
0314 using H = typename TypeParam::hasher;
0315 using E = typename TypeParam::key_equal;
0316 using A = typename TypeParam::allocator_type;
0317 H hasher;
0318 E equal;
0319 A alloc(0);
0320 TypeParam m(123, hasher, equal, alloc);
0321 for (size_t i = 0; i != 10; ++i) m.insert(hash_internal::Generator<T>()());
0322 TypeParam t(m);
0323 TypeParam n(std::move(t), A(1));
0324 EXPECT_EQ(m.hash_function(), n.hash_function());
0325 EXPECT_EQ(m.key_eq(), n.key_eq());
0326 EXPECT_NE(m.get_allocator(), n.get_allocator());
0327 EXPECT_EQ(m, n);
0328 }
0329
0330 TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) {
0331 MoveConstructorAllocTest<TypeParam>(expect_alloc_constructors<TypeParam>());
0332 }
0333
0334
0335
0336 TYPED_TEST_P(ConstructorTest, InitializerListBucketHashEqualAlloc) {
0337 using T = hash_internal::GeneratedType<TypeParam>;
0338 hash_internal::Generator<T> gen;
0339 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
0340 using H = typename TypeParam::hasher;
0341 using E = typename TypeParam::key_equal;
0342 using A = typename TypeParam::allocator_type;
0343 H hasher;
0344 E equal;
0345 A alloc(0);
0346 TypeParam m(values, 123, hasher, equal, alloc);
0347 EXPECT_EQ(m.hash_function(), hasher);
0348 EXPECT_EQ(m.key_eq(), equal);
0349 EXPECT_EQ(m.get_allocator(), alloc);
0350 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
0351 EXPECT_GE(m.bucket_count(), 123);
0352 }
0353
0354 template <typename TypeParam>
0355 void InitializerListBucketAllocTest(std::false_type) {}
0356
0357 template <typename TypeParam>
0358 void InitializerListBucketAllocTest(std::true_type) {
0359 using T = hash_internal::GeneratedType<TypeParam>;
0360 using A = typename TypeParam::allocator_type;
0361 hash_internal::Generator<T> gen;
0362 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
0363 A alloc(0);
0364 TypeParam m(values, 123, alloc);
0365 EXPECT_EQ(m.get_allocator(), alloc);
0366 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
0367 EXPECT_GE(m.bucket_count(), 123);
0368 }
0369
0370 TYPED_TEST_P(ConstructorTest, InitializerListBucketAlloc) {
0371 InitializerListBucketAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
0372 }
0373
0374 template <typename TypeParam>
0375 void InitializerListBucketHashAllocTest(std::false_type) {}
0376
0377 template <typename TypeParam>
0378 void InitializerListBucketHashAllocTest(std::true_type) {
0379 using T = hash_internal::GeneratedType<TypeParam>;
0380 using H = typename TypeParam::hasher;
0381 using A = typename TypeParam::allocator_type;
0382 H hasher;
0383 A alloc(0);
0384 hash_internal::Generator<T> gen;
0385 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
0386 TypeParam m(values, 123, hasher, alloc);
0387 EXPECT_EQ(m.hash_function(), hasher);
0388 EXPECT_EQ(m.get_allocator(), alloc);
0389 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
0390 EXPECT_GE(m.bucket_count(), 123);
0391 }
0392
0393 TYPED_TEST_P(ConstructorTest, InitializerListBucketHashAlloc) {
0394 InitializerListBucketHashAllocTest<TypeParam>(expect_cxx14_apis<TypeParam>());
0395 }
0396
0397 TYPED_TEST_P(ConstructorTest, CopyAssignment) {
0398 using T = hash_internal::GeneratedType<TypeParam>;
0399 using H = typename TypeParam::hasher;
0400 using E = typename TypeParam::key_equal;
0401 using A = typename TypeParam::allocator_type;
0402 H hasher;
0403 E equal;
0404 A alloc(0);
0405 hash_internal::Generator<T> gen;
0406 TypeParam m({gen(), gen(), gen()}, 123, hasher, equal, alloc);
0407 TypeParam n;
0408 n = m;
0409 EXPECT_EQ(m.hash_function(), n.hash_function());
0410 EXPECT_EQ(m.key_eq(), n.key_eq());
0411 EXPECT_EQ(m, n);
0412 }
0413
0414
0415
0416
0417 TYPED_TEST_P(ConstructorTest, MoveAssignment) {
0418 using T = hash_internal::GeneratedType<TypeParam>;
0419 using H = typename TypeParam::hasher;
0420 using E = typename TypeParam::key_equal;
0421 using A = typename TypeParam::allocator_type;
0422 H hasher;
0423 E equal;
0424 A alloc(0);
0425 hash_internal::Generator<T> gen;
0426 TypeParam m({gen(), gen(), gen()}, 123, hasher, equal, alloc);
0427 TypeParam t(m);
0428 TypeParam n;
0429 n = std::move(t);
0430 EXPECT_EQ(m.hash_function(), n.hash_function());
0431 EXPECT_EQ(m.key_eq(), n.key_eq());
0432 EXPECT_EQ(m, n);
0433 }
0434
0435 TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerList) {
0436 using T = hash_internal::GeneratedType<TypeParam>;
0437 hash_internal::Generator<T> gen;
0438 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
0439 TypeParam m;
0440 m = values;
0441 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
0442 }
0443
0444 TYPED_TEST_P(ConstructorTest, AssignmentOverwritesExisting) {
0445 using T = hash_internal::GeneratedType<TypeParam>;
0446 hash_internal::Generator<T> gen;
0447 TypeParam m({gen(), gen(), gen()});
0448 TypeParam n({gen()});
0449 n = m;
0450 EXPECT_EQ(m, n);
0451 }
0452
0453 TYPED_TEST_P(ConstructorTest, MoveAssignmentOverwritesExisting) {
0454 using T = hash_internal::GeneratedType<TypeParam>;
0455 hash_internal::Generator<T> gen;
0456 TypeParam m({gen(), gen(), gen()});
0457 TypeParam t(m);
0458 TypeParam n({gen()});
0459 n = std::move(t);
0460 EXPECT_EQ(m, n);
0461 }
0462
0463 TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerListOverwritesExisting) {
0464 using T = hash_internal::GeneratedType<TypeParam>;
0465 hash_internal::Generator<T> gen;
0466 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
0467 TypeParam m;
0468 m = values;
0469 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
0470 }
0471
0472 TYPED_TEST_P(ConstructorTest, AssignmentOnSelf) {
0473 using T = hash_internal::GeneratedType<TypeParam>;
0474 hash_internal::Generator<T> gen;
0475 std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()};
0476 TypeParam m(values);
0477 m = *&m;
0478 EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
0479 }
0480
0481 REGISTER_TYPED_TEST_SUITE_P(
0482 ConstructorTest, NoArgs, BucketCount, BucketCountHash, BucketCountHashEqual,
0483 BucketCountHashEqualAlloc, BucketCountAlloc, BucketCountHashAlloc, Alloc,
0484 InputIteratorBucketHashEqualAlloc, InputIteratorBucketAlloc,
0485 InputIteratorBucketHashAlloc, CopyConstructor, CopyConstructorAlloc,
0486 MoveConstructor, MoveConstructorAlloc, InitializerListBucketHashEqualAlloc,
0487 InitializerListBucketAlloc, InitializerListBucketHashAlloc, CopyAssignment,
0488 MoveAssignment, AssignmentFromInitializerList, AssignmentOverwritesExisting,
0489 MoveAssignmentOverwritesExisting,
0490 AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf);
0491
0492 }
0493 ABSL_NAMESPACE_END
0494 }
0495
0496 #endif