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 |