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


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:16