Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:31:40

0001 // Copyright 2018 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
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 // TODO(alkis): Test non-propagating allocators on copy constructors.
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 // TODO(alkis): Test non-propagating allocators on move constructors.
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 // TODO(alkis): Test [non-]propagating allocators on move/copy assignments
0415 // (it depends on traits).
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;  // Avoid -Wself-assign.
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 }  // namespace container_internal
0493 ABSL_NAMESPACE_END
0494 }  // namespace absl
0495 
0496 #endif  // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_