Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: base/containers/flat_tree_unittest.cc

Issue 2776793002: Make flat containers stable, allow constructing from vector. (Closed)
Patch Set: Checkpoint Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« base/containers/flat_tree.h ('K') | « base/containers/flat_tree.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« base/containers/flat_tree.h ('K') | « base/containers/flat_tree.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698