| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/containers/flat_tree.h" | 5 #include "base/containers/flat_tree.h" |
| 6 | 6 |
| 7 // Following tests are ported and extended tests from libcpp for std::set. | 7 // Following tests are ported and extended tests from libcpp for std::set. |
| 8 // They can be found here: | 8 // They can be found here: |
| 9 // https://github.com/llvm-mirror/libcxx/tree/master/test/std/containers/associa
tive/set | 9 // https://github.com/llvm-mirror/libcxx/tree/master/test/std/containers/associa
tive/set |
| 10 // | 10 // |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 class NonDefaultConstructibleCompare { | 123 class NonDefaultConstructibleCompare { |
| 124 public: | 124 public: |
| 125 explicit NonDefaultConstructibleCompare(int) {} | 125 explicit NonDefaultConstructibleCompare(int) {} |
| 126 | 126 |
| 127 template <typename T> | 127 template <typename T> |
| 128 bool operator()(const T& lhs, const T& rhs) const { | 128 bool operator()(const T& lhs, const T& rhs) const { |
| 129 return std::less<T>()(lhs, rhs); | 129 return std::less<T>()(lhs, rhs); |
| 130 } | 130 } |
| 131 }; | 131 }; |
| 132 | 132 |
| 133 template <class PairType> |
| 134 struct LessByFirst { |
| 135 bool operator()(const PairType& lhs, const PairType& rhs) const { |
| 136 return lhs.first < rhs.first; |
| 137 } |
| 138 }; |
| 139 |
| 133 // Common test trees. | 140 // Common test trees. |
| 134 | 141 |
| 135 // TODO(dyaroshev): replace less<int> with less<>, once we have it | 142 // TODO(dyaroshev): replace less<int> with less<>, once we have it |
| 136 // crbug.com/682254. This will make it different than IntTree. | 143 // crbug.com/682254. This will make it different than IntTree. |
| 137 using IntTreeWithLess = | 144 using IntTreeWithLess = |
| 138 flat_tree<int, int, GetKeyFromValueIdentity<int>, std::less<int>>; | 145 flat_tree<int, int, GetKeyFromValueIdentity<int>, std::less<int>>; |
| 139 using IntTree = | 146 using IntTree = |
| 140 flat_tree<int, int, GetKeyFromValueIdentity<int>, std::less<int>>; | 147 flat_tree<int, int, GetKeyFromValueIdentity<int>, std::less<int>>; |
| 141 using MoveOnlyTree = flat_tree<MoveOnlyInt, | 148 using MoveOnlyTree = flat_tree<MoveOnlyInt, |
| 142 MoveOnlyInt, | 149 MoveOnlyInt, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 | 181 |
| 175 // We do not declare operator< because clang complains that it's unused. | 182 // We do not declare operator< because clang complains that it's unused. |
| 176 }; | 183 }; |
| 177 | 184 |
| 178 A a; | 185 A a; |
| 179 } | 186 } |
| 180 | 187 |
| 181 TEST(FlatTree, Stability) { | 188 TEST(FlatTree, Stability) { |
| 182 using Pair = std::pair<int, int>; | 189 using Pair = std::pair<int, int>; |
| 183 | 190 |
| 184 struct LessByFirst { | 191 using Tree = |
| 185 bool operator()(const Pair& lhs, const Pair& rhs) const { | 192 flat_tree<Pair, Pair, GetKeyFromValueIdentity<Pair>, LessByFirst<Pair>>; |
| 186 return lhs.first < rhs.first; | 193 |
| 187 } | 194 // Constructors are stable. |
| 195 Tree cont{{0, 0}, {1, 0}, {0, 1}, {2, 0}, {0, 2}, {1, 1}}; |
| 196 |
| 197 auto AllOfSecondsAreZero = [&cont] { |
| 198 return std::all_of(cont.begin(), cont.end(), |
| 199 [](const Pair& elem) { return elem.second == 0; }); |
| 188 }; | 200 }; |
| 189 | 201 |
| 190 using Tree = | 202 EXPECT_TRUE(AllOfSecondsAreZero()) << "constructor should be stable"; |
| 191 flat_tree<Pair, Pair, GetKeyFromValueIdentity<Pair>, LessByFirst>; | |
| 192 | |
| 193 // Constructors are not stable. | |
| 194 Tree cont{{0, 0}, {1, 0}, {0, 1}, {2, 0}, {0, 2}, {1, 1}}; | |
| 195 | |
| 196 auto NoneOfSecondsAreTwo = [&cont] { | |
| 197 return std::none_of(cont.begin(), cont.end(), | |
| 198 [](const Pair& elem) { return elem.second == 2; }); | |
| 199 }; | |
| 200 | 203 |
| 201 // Should not replace existing. | 204 // Should not replace existing. |
| 202 cont.insert(Pair(0, 2)); | 205 cont.insert(Pair(0, 2)); |
| 203 cont.insert(Pair(1, 2)); | 206 cont.insert(Pair(1, 2)); |
| 204 cont.insert(Pair(2, 2)); | 207 cont.insert(Pair(2, 2)); |
| 205 | 208 |
| 206 EXPECT_TRUE(NoneOfSecondsAreTwo()) | 209 EXPECT_TRUE(AllOfSecondsAreZero()) << "insert should be stable"; |
| 207 << "insert should be stable with respect to constructor"; | |
| 208 | 210 |
| 209 cont.insert(Pair(3, 0)); | 211 cont.insert(Pair(3, 0)); |
| 210 cont.insert(Pair(3, 2)); | 212 cont.insert(Pair(3, 2)); |
| 211 | 213 |
| 212 EXPECT_TRUE(NoneOfSecondsAreTwo()) | 214 EXPECT_TRUE(AllOfSecondsAreZero()) << "insert should be stable"; |
| 213 << "insert should be stable with respect to previous insert"; | |
| 214 } | 215 } |
| 215 | 216 |
| 216 // ---------------------------------------------------------------------------- | 217 // ---------------------------------------------------------------------------- |
| 217 // Types. | 218 // Types. |
| 218 | 219 |
| 219 // key_type | 220 // key_type |
| 220 // key_compare | 221 // key_compare |
| 221 // value_type | 222 // value_type |
| 222 // value_compare | 223 // value_compare |
| 223 // pointer | 224 // pointer |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 | 306 |
| 306 MoveOnlyTree original(std::begin(input_range), std::end(input_range)); | 307 MoveOnlyTree original(std::begin(input_range), std::end(input_range)); |
| 307 MoveOnlyTree moved(std::move(original)); | 308 MoveOnlyTree moved(std::move(original)); |
| 308 | 309 |
| 309 EXPECT_EQ(1U, moved.count(MoveOnlyInt(1))); | 310 EXPECT_EQ(1U, moved.count(MoveOnlyInt(1))); |
| 310 EXPECT_EQ(1U, moved.count(MoveOnlyInt(2))); | 311 EXPECT_EQ(1U, moved.count(MoveOnlyInt(2))); |
| 311 EXPECT_EQ(1U, moved.count(MoveOnlyInt(3))); | 312 EXPECT_EQ(1U, moved.count(MoveOnlyInt(3))); |
| 312 EXPECT_EQ(1U, moved.count(MoveOnlyInt(4))); | 313 EXPECT_EQ(1U, moved.count(MoveOnlyInt(4))); |
| 313 } | 314 } |
| 314 | 315 |
| 315 // flat_tree(std::initializer_list<value_type> ilist, | 316 // flat_tree(std::vector<value_type>&&) |
| 317 |
| 318 TEST(FlatTree, MoveVectorConstructor) { |
| 319 using Pair = std::pair<int, MoveOnlyInt>; |
| 320 |
| 321 // Construct an unsorted vector with a duplicate item in it. Sorted by the |
| 322 // first item, the second allows us to test for stability. Using a move |
| 323 // only type to ensure the vector is not copied. |
| 324 std::vector<Pair> storage; |
| 325 storage.push_back(Pair(2, MoveOnlyInt(0))); |
| 326 storage.push_back(Pair(1, MoveOnlyInt(0))); |
| 327 storage.push_back(Pair(2, MoveOnlyInt(1))); |
| 328 |
| 329 using Tree = |
| 330 flat_tree<Pair, Pair, GetKeyFromValueIdentity<Pair>, LessByFirst<Pair>>; |
| 331 Tree tree(std::move(storage)); |
| 332 |
| 333 // The list should be two items long, with only the first "2" saved. |
| 334 ASSERT_EQ(2u, tree.size()); |
| 335 const Pair& zeroth = *tree.begin(); |
| 336 ASSERT_EQ(1, zeroth.first); |
| 337 ASSERT_EQ(0, zeroth.second.data()); |
| 338 |
| 339 const Pair& first = *(tree.begin() + 1); |
| 340 ASSERT_EQ(2, first.first); |
| 341 ASSERT_EQ(0, first.second.data()); |
| 342 } |
| 343 |
| 344 // flat_tree(std::initializer_list<value_type> ilist, |
| 316 // const Compare& comp = Compare()) | 345 // const Compare& comp = Compare()) |
| 317 | 346 |
| 318 TEST(FlatTree, InitializerListConstructor) { | 347 TEST(FlatTree, InitializerListConstructor) { |
| 319 { | 348 { |
| 320 IntTree cont{1, 2, 3, 4, 5, 6, 10, 8}; | 349 IntTree cont{1, 2, 3, 4, 5, 6, 10, 8}; |
| 321 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 8, 10)); | 350 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 8, 10)); |
| 322 } | 351 } |
| 323 { | 352 { |
| 324 TreeWithStrangeCompare cont({1, 2, 3, 4, 5, 6, 10, 8}, | 353 TreeWithStrangeCompare cont({1, 2, 3, 4, 5, 6, 10, 8}, |
| 325 NonDefaultConstructibleCompare(0)); | 354 NonDefaultConstructibleCompare(0)); |
| (...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 EraseIf(x, [](int elem) { return !(elem & 1); }); | 1276 EraseIf(x, [](int elem) { return !(elem & 1); }); |
| 1248 EXPECT_THAT(x, ElementsAre(1, 3)); | 1277 EXPECT_THAT(x, ElementsAre(1, 3)); |
| 1249 | 1278 |
| 1250 x = {1, 2, 3, 4}; | 1279 x = {1, 2, 3, 4}; |
| 1251 EraseIf(x, [](int elem) { return elem & 1; }); | 1280 EraseIf(x, [](int elem) { return elem & 1; }); |
| 1252 EXPECT_THAT(x, ElementsAre(2, 4)); | 1281 EXPECT_THAT(x, ElementsAre(2, 4)); |
| 1253 } | 1282 } |
| 1254 | 1283 |
| 1255 } // namespace internal | 1284 } // namespace internal |
| 1256 } // namespace base | 1285 } // namespace base |
| OLD | NEW |