1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/containers/flat_tree.h"
6
7 // Following tests are ported and extended tests from libcpp for std::set.
8 // They can be found here:
9 // https://github.com/llvm/llvm-project/tree/main/libcxx/test/std/containers/associative/set
10 //
11 // Not ported tests:
12 // * No tests with PrivateConstructor and std::less<> changed to std::less<T>
13 // These tests have to do with C++14 std::less<>
14 // http://en.cppreference.com/w/cpp/utility/functional/less_void
15 // and add support for templated versions of lookup functions.
16 // Because we use same implementation, we figured that it's OK just to check
17 // compilation and this is what we do in flat_set_unittest/flat_map_unittest.
18 // * No tests for max_size()
19 // Has to do with allocator support.
20 // * No tests with DefaultOnly.
21 // Standard containers allocate each element in the separate node on the heap
22 // and then manipulate these nodes. Flat containers store their elements in
23 // contiguous memory and move them around, type is required to be movable.
24 // * No tests for N3644.
25 // This proposal suggests that all default constructed iterators compare
26 // equal. Currently we use std::vector iterators and they don't implement
27 // this.
28 // * No tests with min_allocator and no tests counting allocations.
29 // Flat sets currently don't support allocators.
30
31 #include <deque>
32 #include <forward_list>
33 #include <functional>
34 #include <iterator>
35 #include <list>
36 #include <string>
37 #include <vector>
38
39 #include "base/ranges/algorithm.h"
40 #include "base/template_util.h"
41 #include "base/test/gtest_util.h"
42 #include "base/test/move_only_int.h"
43 #include "testing/gmock/include/gmock/gmock.h"
44 #include "testing/gtest/include/gtest/gtest.h"
45
46 namespace base {
47 namespace internal {
48
49 namespace {
50
51 template <class It>
52 class InputIterator {
53 public:
54 using iterator_category = std::input_iterator_tag;
55 using value_type = typename std::iterator_traits<It>::value_type;
56 using difference_type = typename std::iterator_traits<It>::difference_type;
57 using pointer = It;
58 using reference = typename std::iterator_traits<It>::reference;
59
InputIterator()60 InputIterator() : it_() {}
InputIterator(It it)61 explicit InputIterator(It it) : it_(it) {}
62
operator *() const63 reference operator*() const { return *it_; }
operator ->() const64 pointer operator->() const { return it_; }
65
operator ++()66 InputIterator& operator++() {
67 ++it_;
68 return *this;
69 }
operator ++(int)70 InputIterator operator++(int) {
71 InputIterator tmp(*this);
72 ++(*this);
73 return tmp;
74 }
75
operator ==(const InputIterator & lhs,const InputIterator & rhs)76 friend bool operator==(const InputIterator& lhs, const InputIterator& rhs) {
77 return lhs.it_ == rhs.it_;
78 }
operator !=(const InputIterator & lhs,const InputIterator & rhs)79 friend bool operator!=(const InputIterator& lhs, const InputIterator& rhs) {
80 return !(lhs == rhs);
81 }
82
83 private:
84 It it_;
85 };
86
87 template <typename It>
MakeInputIterator(It it)88 InputIterator<It> MakeInputIterator(It it) {
89 return InputIterator<It>(it);
90 }
91
92 class Emplaceable {
93 public:
Emplaceable()94 Emplaceable() : Emplaceable(0, 0.0) {}
Emplaceable(int i,double d)95 Emplaceable(int i, double d) : int_(i), double_(d) {}
Emplaceable(Emplaceable && other)96 Emplaceable(Emplaceable&& other) : int_(other.int_), double_(other.double_) {
97 other.int_ = 0;
98 other.double_ = 0.0;
99 }
100 Emplaceable(const Emplaceable&) = delete;
101 Emplaceable& operator=(const Emplaceable&) = delete;
102
operator =(Emplaceable && other)103 Emplaceable& operator=(Emplaceable&& other) {
104 int_ = other.int_;
105 other.int_ = 0;
106 double_ = other.double_;
107 other.double_ = 0.0;
108 return *this;
109 }
110
operator ==(const Emplaceable & lhs,const Emplaceable & rhs)111 friend bool operator==(const Emplaceable& lhs, const Emplaceable& rhs) {
112 return std::tie(lhs.int_, lhs.double_) == std::tie(rhs.int_, rhs.double_);
113 }
114
operator <(const Emplaceable & lhs,const Emplaceable & rhs)115 friend bool operator<(const Emplaceable& lhs, const Emplaceable& rhs) {
116 return std::tie(lhs.int_, lhs.double_) < std::tie(rhs.int_, rhs.double_);
117 }
118
119 private:
120 int int_;
121 double double_;
122 };
123
124 struct TemplateConstructor {
125 template <typename T>
TemplateConstructorbase::internal::__anonabfb52190111::TemplateConstructor126 TemplateConstructor(const T&) {}
127
operator <(const TemplateConstructor &,const TemplateConstructor &)128 friend bool operator<(const TemplateConstructor&,
129 const TemplateConstructor&) {
130 return false;
131 }
132 };
133
134 class NonDefaultConstructibleCompare {
135 public:
NonDefaultConstructibleCompare(int)136 explicit NonDefaultConstructibleCompare(int) {}
137
138 template <typename T>
operator ()(const T & lhs,const T & rhs) const139 bool operator()(const T& lhs, const T& rhs) const {
140 return std::less<T>()(lhs, rhs);
141 }
142 };
143
144 template <class PairType>
145 struct LessByFirst {
operator ()base::internal::__anonabfb52190111::LessByFirst146 bool operator()(const PairType& lhs, const PairType& rhs) const {
147 return lhs.first < rhs.first;
148 }
149 };
150
151 // Common test trees.
152 template <typename ContainerT>
153 using TypedTree = flat_tree<typename ContainerT::value_type,
154 std::identity,
155 std::less<>,
156 ContainerT>;
157 using IntTree = TypedTree<std::vector<int>>;
158 using IntPair = std::pair<int, int>;
159 using IntPairTree = flat_tree<IntPair,
160 std::identity,
161 LessByFirst<IntPair>,
162 std::vector<IntPair>>;
163 using MoveOnlyTree = flat_tree<MoveOnlyInt,
164 std::identity,
165 std::less<>,
166 std::vector<MoveOnlyInt>>;
167 using EmplaceableTree = flat_tree<Emplaceable,
168 std::identity,
169 std::less<>,
170 std::vector<Emplaceable>>;
171 using ReversedTree =
172 flat_tree<int, std::identity, std::greater<int>, std::vector<int>>;
173
174 using TreeWithStrangeCompare = flat_tree<int,
175 std::identity,
176 NonDefaultConstructibleCompare,
177 std::vector<int>>;
178
179 using ::testing::ElementsAre;
180 using ::testing::IsEmpty;
181
182 } // namespace
183
184 template <typename T>
185 class FlatTreeTest : public testing::Test {};
186 TYPED_TEST_SUITE_P(FlatTreeTest);
187
188 // Tests that the compiler generated move operators propagrate noexcept
189 // specifiers.
TEST(FlatTree,NoExcept)190 TEST(FlatTree, NoExcept) {
191 struct MoveThrows {
192 MoveThrows(MoveThrows&&) noexcept(false) {}
193 MoveThrows& operator=(MoveThrows&&) noexcept(false) { return *this; }
194 };
195
196 using MoveThrowsTree = flat_tree<MoveThrows, std::identity, std::less<>,
197 std::array<MoveThrows, 1>>;
198
199 static_assert(std::is_nothrow_move_constructible_v<IntTree>,
200 "Error: IntTree is not nothrow move constructible");
201 static_assert(std::is_nothrow_move_assignable_v<IntTree>,
202 "Error: IntTree is not nothrow move assignable");
203
204 static_assert(!std::is_nothrow_move_constructible_v<MoveThrowsTree>,
205 "Error: MoveThrowsTree is nothrow move constructible");
206 static_assert(!std::is_nothrow_move_assignable_v<MoveThrowsTree>,
207 "Error: MoveThrowsTree is nothrow move assignable");
208 }
209
210 // ----------------------------------------------------------------------------
211 // Class.
212
213 // Check that flat_tree and its iterators can be instantiated with an
214 // incomplete type.
215
TEST(FlatTree,IncompleteType)216 TEST(FlatTree, IncompleteType) {
217 struct A {
218 using Tree = flat_tree<A, std::identity, std::less<A>, std::vector<A>>;
219 int data;
220 Tree set_with_incomplete_type;
221 Tree::iterator it;
222 Tree::const_iterator cit;
223
224 // We do not declare operator< because clang complains that it's unused.
225 };
226
227 A a;
228 }
229
TEST(FlatTree,Stability)230 TEST(FlatTree, Stability) {
231 using Pair = std::pair<int, int>;
232
233 using Tree =
234 flat_tree<Pair, std::identity, LessByFirst<Pair>, std::vector<Pair>>;
235
236 // Constructors are stable.
237 Tree cont({{0, 0}, {1, 0}, {0, 1}, {2, 0}, {0, 2}, {1, 1}});
238
239 auto AllOfSecondsAreZero = [&cont] {
240 return ranges::all_of(cont,
241 [](const Pair& elem) { return elem.second == 0; });
242 };
243
244 EXPECT_TRUE(AllOfSecondsAreZero()) << "constructor should be stable";
245
246 // Should not replace existing.
247 cont.insert(Pair(0, 2));
248 cont.insert(Pair(1, 2));
249 cont.insert(Pair(2, 2));
250
251 EXPECT_TRUE(AllOfSecondsAreZero()) << "insert should be stable";
252
253 cont.insert(Pair(3, 0));
254 cont.insert(Pair(3, 2));
255
256 EXPECT_TRUE(AllOfSecondsAreZero()) << "insert should be stable";
257 }
258
259 // ----------------------------------------------------------------------------
260 // Types.
261
262 // key_type
263 // key_compare
264 // value_type
265 // value_compare
266 // pointer
267 // const_pointer
268 // reference
269 // const_reference
270 // size_type
271 // difference_type
272 // iterator
273 // const_iterator
274 // reverse_iterator
275 // const_reverse_iterator
276
TEST(FlatTree,Types)277 TEST(FlatTree, Types) {
278 // These are guaranteed to be portable.
279 static_assert((std::is_same_v<int, IntTree::key_type>), "");
280 static_assert((std::is_same_v<int, IntTree::value_type>), "");
281 static_assert((std::is_same_v<std::less<>, IntTree::key_compare>), "");
282 static_assert((std::is_same_v<int&, IntTree::reference>), "");
283 static_assert((std::is_same_v<const int&, IntTree::const_reference>), "");
284 static_assert((std::is_same_v<int*, IntTree::pointer>), "");
285 static_assert((std::is_same_v<const int*, IntTree::const_pointer>), "");
286 }
287
288 // ----------------------------------------------------------------------------
289 // Lifetime.
290
291 // flat_tree()
292 // flat_tree(const Compare& comp)
293
TYPED_TEST_P(FlatTreeTest,DefaultConstructor)294 TYPED_TEST_P(FlatTreeTest, DefaultConstructor) {
295 {
296 TypedTree<TypeParam> cont;
297 EXPECT_THAT(cont, ElementsAre());
298 }
299
300 {
301 TreeWithStrangeCompare cont(NonDefaultConstructibleCompare(0));
302 EXPECT_THAT(cont, ElementsAre());
303 }
304 }
305
306 // flat_tree(const flat_tree& x)
307
TYPED_TEST_P(FlatTreeTest,CopyConstructor)308 TYPED_TEST_P(FlatTreeTest, CopyConstructor) {
309 TypedTree<TypeParam> original({1, 2, 3, 4});
310 TypedTree<TypeParam> copied(original);
311
312 EXPECT_THAT(copied, ElementsAre(1, 2, 3, 4));
313
314 EXPECT_THAT(copied, ElementsAre(1, 2, 3, 4));
315 EXPECT_THAT(original, ElementsAre(1, 2, 3, 4));
316 EXPECT_EQ(original, copied);
317 }
318
319 // flat_tree(flat_tree&& x)
320
TEST(FlatTree,MoveConstructor)321 TEST(FlatTree, MoveConstructor) {
322 int input_range[] = {1, 2, 3, 4};
323
324 MoveOnlyTree original(std::begin(input_range), std::end(input_range));
325 MoveOnlyTree moved(std::move(original));
326
327 EXPECT_EQ(1U, moved.count(MoveOnlyInt(1)));
328 EXPECT_EQ(1U, moved.count(MoveOnlyInt(2)));
329 EXPECT_EQ(1U, moved.count(MoveOnlyInt(3)));
330 EXPECT_EQ(1U, moved.count(MoveOnlyInt(4)));
331 }
332
333 // flat_tree(InputIterator first,
334 // InputIterator last,
335 // const Compare& comp = Compare())
336
TEST(FlatTree,RangeConstructor)337 TEST(FlatTree, RangeConstructor) {
338 {
339 IntPair input_vals[] = {{1, 1}, {1, 2}, {2, 1}, {2, 2}, {1, 3},
340 {2, 3}, {3, 1}, {3, 2}, {3, 3}};
341
342 IntPairTree first_of(MakeInputIterator(std::begin(input_vals)),
343 MakeInputIterator(std::end(input_vals)));
344 EXPECT_THAT(first_of,
345 ElementsAre(IntPair(1, 1), IntPair(2, 1), IntPair(3, 1)));
346 }
347 {
348 TreeWithStrangeCompare::value_type input_vals[] = {1, 1, 1, 2, 2,
349 2, 3, 3, 3};
350
351 TreeWithStrangeCompare cont(MakeInputIterator(std::begin(input_vals)),
352 MakeInputIterator(std::end(input_vals)),
353 NonDefaultConstructibleCompare(0));
354 EXPECT_THAT(cont, ElementsAre(1, 2, 3));
355 }
356 }
357
358 // flat_tree(const container_type&)
359
TYPED_TEST_P(FlatTreeTest,ContainerCopyConstructor)360 TYPED_TEST_P(FlatTreeTest, ContainerCopyConstructor) {
361 TypeParam items = {1, 2, 3, 4};
362 TypedTree<TypeParam> tree(items);
363
364 EXPECT_THAT(tree, ElementsAre(1, 2, 3, 4));
365 EXPECT_THAT(items, ElementsAre(1, 2, 3, 4));
366 }
367
368 // flat_tree(container_type&&)
369
TEST(FlatTree,ContainerMoveConstructor)370 TEST(FlatTree, ContainerMoveConstructor) {
371 using Pair = std::pair<int, MoveOnlyInt>;
372
373 // Construct an unsorted vector with a duplicate item in it. Sorted by the
374 // first item, the second allows us to test for stability. Using a move
375 // only type to ensure the vector is not copied.
376 std::vector<Pair> storage;
377 storage.push_back(Pair(2, MoveOnlyInt(0)));
378 storage.push_back(Pair(1, MoveOnlyInt(0)));
379 storage.push_back(Pair(2, MoveOnlyInt(1)));
380
381 using Tree =
382 flat_tree<Pair, std::identity, LessByFirst<Pair>, std::vector<Pair>>;
383 Tree tree(std::move(storage));
384
385 // The list should be two items long, with only the first "2" saved.
386 ASSERT_EQ(2u, tree.size());
387 const Pair& zeroth = *tree.begin();
388 ASSERT_EQ(1, zeroth.first);
389 ASSERT_EQ(0, zeroth.second.data());
390
391 const Pair& first = *(tree.begin() + 1);
392 ASSERT_EQ(2, first.first);
393 ASSERT_EQ(0, first.second.data());
394 }
395
396 // flat_tree(std::initializer_list<value_type> ilist,
397 // const Compare& comp = Compare())
398
TYPED_TEST_P(FlatTreeTest,InitializerListConstructor)399 TYPED_TEST_P(FlatTreeTest, InitializerListConstructor) {
400 {
401 TypedTree<TypeParam> cont({1, 2, 3, 4, 5, 6, 10, 8});
402 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 8, 10));
403 }
404 {
405 TypedTree<TypeParam> cont({1, 2, 3, 4, 5, 6, 10, 8});
406 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 8, 10));
407 }
408 {
409 TreeWithStrangeCompare cont({1, 2, 3, 4, 5, 6, 10, 8},
410 NonDefaultConstructibleCompare(0));
411 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 8, 10));
412 }
413 {
414 IntPairTree first_of({{1, 1}, {2, 1}, {1, 2}});
415 EXPECT_THAT(first_of, ElementsAre(IntPair(1, 1), IntPair(2, 1)));
416 }
417 }
418
419 // flat_tree(sorted_unique_t,
420 // InputIterator first,
421 // InputIterator last,
422 // const Compare& comp = Compare())
423
TEST(FlatTree,SortedUniqueRangeConstructor)424 TEST(FlatTree, SortedUniqueRangeConstructor) {
425 {
426 IntPair input_vals[] = {{1, 1}, {2, 1}, {3, 1}};
427
428 IntPairTree first_of(sorted_unique,
429 MakeInputIterator(std::begin(input_vals)),
430 MakeInputIterator(std::end(input_vals)));
431 EXPECT_THAT(first_of,
432 ElementsAre(IntPair(1, 1), IntPair(2, 1), IntPair(3, 1)));
433 }
434 {
435 TreeWithStrangeCompare::value_type input_vals[] = {1, 2, 3};
436
437 TreeWithStrangeCompare cont(sorted_unique,
438 MakeInputIterator(std::begin(input_vals)),
439 MakeInputIterator(std::end(input_vals)),
440 NonDefaultConstructibleCompare(0));
441 EXPECT_THAT(cont, ElementsAre(1, 2, 3));
442 }
443 }
444
445 // flat_tree(sorted_unique_t, const container_type&)
446
TYPED_TEST_P(FlatTreeTest,SortedUniqueContainerCopyConstructor)447 TYPED_TEST_P(FlatTreeTest, SortedUniqueContainerCopyConstructor) {
448 TypeParam items = {1, 2, 3, 4};
449 TypedTree<TypeParam> tree(sorted_unique, items);
450
451 EXPECT_THAT(tree, ElementsAre(1, 2, 3, 4));
452 EXPECT_THAT(items, ElementsAre(1, 2, 3, 4));
453 }
454
455 // flat_tree(sorted_unique_t, std::vector<value_type>&&)
456
TEST(FlatTree,SortedUniqueVectorMoveConstructor)457 TEST(FlatTree, SortedUniqueVectorMoveConstructor) {
458 using Pair = std::pair<int, MoveOnlyInt>;
459
460 std::vector<Pair> storage;
461 storage.push_back(Pair(1, MoveOnlyInt(0)));
462 storage.push_back(Pair(2, MoveOnlyInt(0)));
463
464 using Tree =
465 flat_tree<Pair, std::identity, LessByFirst<Pair>, std::vector<Pair>>;
466 Tree tree(sorted_unique, std::move(storage));
467
468 ASSERT_EQ(2u, tree.size());
469 const Pair& zeroth = *tree.begin();
470 ASSERT_EQ(1, zeroth.first);
471 ASSERT_EQ(0, zeroth.second.data());
472
473 const Pair& first = *(tree.begin() + 1);
474 ASSERT_EQ(2, first.first);
475 ASSERT_EQ(0, first.second.data());
476 }
477
478 // flat_tree(sorted_unique_t,
479 // std::initializer_list<value_type> ilist,
480 // const Compare& comp = Compare())
481
TYPED_TEST_P(FlatTreeTest,SortedUniqueInitializerListConstructor)482 TYPED_TEST_P(FlatTreeTest, SortedUniqueInitializerListConstructor) {
483 {
484 TypedTree<TypeParam> cont(sorted_unique, {1, 2, 3, 4, 5, 6, 8, 10});
485 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 8, 10));
486 }
487 {
488 TypedTree<TypeParam> cont(sorted_unique, {1, 2, 3, 4, 5, 6, 8, 10});
489 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 8, 10));
490 }
491 {
492 TreeWithStrangeCompare cont(sorted_unique, {1, 2, 3, 4, 5, 6, 8, 10},
493 NonDefaultConstructibleCompare(0));
494 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 8, 10));
495 }
496 {
497 IntPairTree first_of(sorted_unique, {{1, 1}, {2, 1}});
498 EXPECT_THAT(first_of, ElementsAre(IntPair(1, 1), IntPair(2, 1)));
499 }
500 }
501
502 // ----------------------------------------------------------------------------
503 // Assignments.
504
505 // flat_tree& operator=(const flat_tree&)
506
TYPED_TEST_P(FlatTreeTest,CopyAssignable)507 TYPED_TEST_P(FlatTreeTest, CopyAssignable) {
508 TypedTree<TypeParam> original({1, 2, 3, 4});
509 TypedTree<TypeParam> copied;
510 copied = original;
511
512 EXPECT_THAT(copied, ElementsAre(1, 2, 3, 4));
513 EXPECT_THAT(original, ElementsAre(1, 2, 3, 4));
514 EXPECT_EQ(original, copied);
515 }
516
517 // flat_tree& operator=(flat_tree&&)
518
TEST(FlatTree,MoveAssignable)519 TEST(FlatTree, MoveAssignable) {
520 int input_range[] = {1, 2, 3, 4};
521
522 MoveOnlyTree original(std::begin(input_range), std::end(input_range));
523 MoveOnlyTree moved;
524 moved = std::move(original);
525
526 EXPECT_EQ(1U, moved.count(MoveOnlyInt(1)));
527 EXPECT_EQ(1U, moved.count(MoveOnlyInt(2)));
528 EXPECT_EQ(1U, moved.count(MoveOnlyInt(3)));
529 EXPECT_EQ(1U, moved.count(MoveOnlyInt(4)));
530 }
531
532 // flat_tree& operator=(std::initializer_list<value_type> ilist)
533
TYPED_TEST_P(FlatTreeTest,InitializerListAssignable)534 TYPED_TEST_P(FlatTreeTest, InitializerListAssignable) {
535 TypedTree<TypeParam> cont({0});
536 cont = {1, 2, 3, 4, 5, 6, 10, 8};
537
538 EXPECT_EQ(0U, cont.count(0));
539 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 8, 10));
540 }
541
542 // --------------------------------------------------------------------------
543 // Memory management.
544
545 // void reserve(size_type new_capacity)
546
TEST(FlatTreeTest,Reserve)547 TEST(FlatTreeTest, Reserve) {
548 IntTree cont({1, 2, 3});
549
550 cont.reserve(5);
551 EXPECT_LE(5U, cont.capacity());
552 }
553
554 // size_type capacity() const
555
TEST(FlatTreeTest,Capacity)556 TEST(FlatTreeTest, Capacity) {
557 IntTree cont({1, 2, 3});
558
559 EXPECT_LE(cont.size(), cont.capacity());
560 cont.reserve(5);
561 EXPECT_LE(cont.size(), cont.capacity());
562 }
563
564 // void shrink_to_fit()
565
TEST(FlatTreeTest,ShrinkToFit)566 TEST(FlatTreeTest, ShrinkToFit) {
567 IntTree cont({1, 2, 3});
568
569 IntTree::size_type capacity_before = cont.capacity();
570 cont.shrink_to_fit();
571 EXPECT_GE(capacity_before, cont.capacity());
572 }
573
574 // ----------------------------------------------------------------------------
575 // Size management.
576
577 // void clear()
578
TYPED_TEST_P(FlatTreeTest,Clear)579 TYPED_TEST_P(FlatTreeTest, Clear) {
580 TypedTree<TypeParam> cont({1, 2, 3, 4, 5, 6, 7, 8});
581 cont.clear();
582 EXPECT_THAT(cont, ElementsAre());
583 }
584
585 // size_type size() const
586
TYPED_TEST_P(FlatTreeTest,Size)587 TYPED_TEST_P(FlatTreeTest, Size) {
588 TypedTree<TypeParam> cont;
589
590 EXPECT_EQ(0U, cont.size());
591 cont.insert(2);
592 EXPECT_EQ(1U, cont.size());
593 cont.insert(1);
594 EXPECT_EQ(2U, cont.size());
595 cont.insert(3);
596 EXPECT_EQ(3U, cont.size());
597 cont.erase(cont.begin());
598 EXPECT_EQ(2U, cont.size());
599 cont.erase(cont.begin());
600 EXPECT_EQ(1U, cont.size());
601 cont.erase(cont.begin());
602 EXPECT_EQ(0U, cont.size());
603 }
604
605 // bool empty() const
606
TYPED_TEST_P(FlatTreeTest,Empty)607 TYPED_TEST_P(FlatTreeTest, Empty) {
608 TypedTree<TypeParam> cont;
609
610 EXPECT_TRUE(cont.empty());
611 cont.insert(1);
612 EXPECT_FALSE(cont.empty());
613 cont.clear();
614 EXPECT_TRUE(cont.empty());
615 }
616
617 // ----------------------------------------------------------------------------
618 // Iterators.
619
620 // iterator begin()
621 // const_iterator begin() const
622 // iterator end()
623 // const_iterator end() const
624 //
625 // reverse_iterator rbegin()
626 // const_reverse_iterator rbegin() const
627 // reverse_iterator rend()
628 // const_reverse_iterator rend() const
629 //
630 // const_iterator cbegin() const
631 // const_iterator cend() const
632 // const_reverse_iterator crbegin() const
633 // const_reverse_iterator crend() const
634
TYPED_TEST_P(FlatTreeTest,Iterators)635 TYPED_TEST_P(FlatTreeTest, Iterators) {
636 TypedTree<TypeParam> cont({1, 2, 3, 4, 5, 6, 7, 8});
637
638 auto size =
639 static_cast<typename TypedTree<TypeParam>::difference_type>(cont.size());
640
641 EXPECT_EQ(size, std::distance(cont.begin(), cont.end()));
642 EXPECT_EQ(size, std::distance(cont.cbegin(), cont.cend()));
643 EXPECT_EQ(size, std::distance(cont.rbegin(), cont.rend()));
644 EXPECT_EQ(size, std::distance(cont.crbegin(), cont.crend()));
645
646 {
647 auto it = cont.begin();
648 auto c_it = cont.cbegin();
649 EXPECT_EQ(it, c_it);
650 for (int j = 1; it != cont.end(); ++it, ++c_it, ++j) {
651 EXPECT_EQ(j, *it);
652 EXPECT_EQ(j, *c_it);
653 }
654 }
655 {
656 auto rit = cont.rbegin();
657 auto c_rit = cont.crbegin();
658 EXPECT_EQ(rit, c_rit);
659 for (int j = static_cast<int>(size); rit != cont.rend();
660 ++rit, ++c_rit, --j) {
661 EXPECT_EQ(j, *rit);
662 EXPECT_EQ(j, *c_rit);
663 }
664 }
665 }
666
667 // ----------------------------------------------------------------------------
668 // Insert operations.
669
670 // pair<iterator, bool> insert(const value_type& val)
671
TYPED_TEST_P(FlatTreeTest,InsertLValue)672 TYPED_TEST_P(FlatTreeTest, InsertLValue) {
673 TypedTree<TypeParam> cont;
674
675 int value = 2;
676 std::pair<typename TypedTree<TypeParam>::iterator, bool> result =
677 cont.insert(value);
678 EXPECT_TRUE(result.second);
679 EXPECT_EQ(cont.begin(), result.first);
680 EXPECT_EQ(1U, cont.size());
681 EXPECT_EQ(2, *result.first);
682
683 value = 1;
684 result = cont.insert(value);
685 EXPECT_TRUE(result.second);
686 EXPECT_EQ(cont.begin(), result.first);
687 EXPECT_EQ(2U, cont.size());
688 EXPECT_EQ(1, *result.first);
689
690 value = 3;
691 result = cont.insert(value);
692 EXPECT_TRUE(result.second);
693 EXPECT_EQ(std::prev(cont.end()), result.first);
694 EXPECT_EQ(3U, cont.size());
695 EXPECT_EQ(3, *result.first);
696
697 value = 3;
698 result = cont.insert(value);
699 EXPECT_FALSE(result.second);
700 EXPECT_EQ(std::prev(cont.end()), result.first);
701 EXPECT_EQ(3U, cont.size());
702 EXPECT_EQ(3, *result.first);
703 }
704
705 // pair<iterator, bool> insert(value_type&& val)
706
TEST(FlatTree,InsertRValue)707 TEST(FlatTree, InsertRValue) {
708 MoveOnlyTree cont;
709
710 std::pair<MoveOnlyTree::iterator, bool> result = cont.insert(MoveOnlyInt(2));
711 EXPECT_TRUE(result.second);
712 EXPECT_EQ(cont.begin(), result.first);
713 EXPECT_EQ(1U, cont.size());
714 EXPECT_EQ(2, result.first->data());
715
716 result = cont.insert(MoveOnlyInt(1));
717 EXPECT_TRUE(result.second);
718 EXPECT_EQ(cont.begin(), result.first);
719 EXPECT_EQ(2U, cont.size());
720 EXPECT_EQ(1, result.first->data());
721
722 result = cont.insert(MoveOnlyInt(3));
723 EXPECT_TRUE(result.second);
724 EXPECT_EQ(std::prev(cont.end()), result.first);
725 EXPECT_EQ(3U, cont.size());
726 EXPECT_EQ(3, result.first->data());
727
728 result = cont.insert(MoveOnlyInt(3));
729 EXPECT_FALSE(result.second);
730 EXPECT_EQ(std::prev(cont.end()), result.first);
731 EXPECT_EQ(3U, cont.size());
732 EXPECT_EQ(3, result.first->data());
733 }
734
735 // iterator insert(const_iterator position_hint, const value_type& val)
736
TYPED_TEST_P(FlatTreeTest,InsertPositionLValue)737 TYPED_TEST_P(FlatTreeTest, InsertPositionLValue) {
738 TypedTree<TypeParam> cont;
739
740 auto result = cont.insert(cont.cend(), 2);
741 EXPECT_EQ(cont.begin(), result);
742 EXPECT_EQ(1U, cont.size());
743 EXPECT_EQ(2, *result);
744
745 result = cont.insert(cont.cend(), 1);
746 EXPECT_EQ(cont.begin(), result);
747 EXPECT_EQ(2U, cont.size());
748 EXPECT_EQ(1, *result);
749
750 result = cont.insert(cont.cend(), 3);
751 EXPECT_EQ(std::prev(cont.end()), result);
752 EXPECT_EQ(3U, cont.size());
753 EXPECT_EQ(3, *result);
754
755 result = cont.insert(cont.cend(), 3);
756 EXPECT_EQ(std::prev(cont.end()), result);
757 EXPECT_EQ(3U, cont.size());
758 EXPECT_EQ(3, *result);
759 }
760
761 // iterator insert(const_iterator position_hint, value_type&& val)
762
TEST(FlatTree,InsertPositionRValue)763 TEST(FlatTree, InsertPositionRValue) {
764 MoveOnlyTree cont;
765
766 auto result = cont.insert(cont.cend(), MoveOnlyInt(2));
767 EXPECT_EQ(cont.begin(), result);
768 EXPECT_EQ(1U, cont.size());
769 EXPECT_EQ(2, result->data());
770
771 result = cont.insert(cont.cend(), MoveOnlyInt(1));
772 EXPECT_EQ(cont.begin(), result);
773 EXPECT_EQ(2U, cont.size());
774 EXPECT_EQ(1, result->data());
775
776 result = cont.insert(cont.cend(), MoveOnlyInt(3));
777 EXPECT_EQ(std::prev(cont.end()), result);
778 EXPECT_EQ(3U, cont.size());
779 EXPECT_EQ(3, result->data());
780
781 result = cont.insert(cont.cend(), MoveOnlyInt(3));
782 EXPECT_EQ(std::prev(cont.end()), result);
783 EXPECT_EQ(3U, cont.size());
784 EXPECT_EQ(3, result->data());
785 }
786
787 // template <class InputIterator>
788 // void insert(InputIterator first, InputIterator last);
789
TEST(FlatTree,InsertIterIter)790 TEST(FlatTree, InsertIterIter) {
791 struct GetKeyFromIntIntPair {
792 const int& operator()(const std::pair<int, int>& p) const {
793 return p.first;
794 }
795 };
796
797 using IntIntMap = flat_tree<int, GetKeyFromIntIntPair, std::less<int>,
798 std::vector<IntPair>>;
799
800 {
801 IntIntMap cont;
802 IntPair int_pairs[] = {{3, 1}, {1, 1}, {4, 1}, {2, 1}};
803 cont.insert(std::begin(int_pairs), std::end(int_pairs));
804 EXPECT_THAT(cont, ElementsAre(IntPair(1, 1), IntPair(2, 1), IntPair(3, 1),
805 IntPair(4, 1)));
806 }
807
808 {
809 IntIntMap cont({{1, 1}, {2, 1}, {3, 1}, {4, 1}});
810 std::vector<IntPair> int_pairs;
811 cont.insert(std::begin(int_pairs), std::end(int_pairs));
812 EXPECT_THAT(cont, ElementsAre(IntPair(1, 1), IntPair(2, 1), IntPair(3, 1),
813 IntPair(4, 1)));
814 }
815
816 {
817 IntIntMap cont({{1, 1}, {2, 1}, {3, 1}, {4, 1}});
818 IntPair int_pairs[] = {{1, 1}};
819 cont.insert(std::begin(int_pairs), std::end(int_pairs));
820 EXPECT_THAT(cont, ElementsAre(IntPair(1, 1), IntPair(2, 1), IntPair(3, 1),
821 IntPair(4, 1)));
822 }
823
824 {
825 IntIntMap cont({{1, 1}, {2, 1}, {3, 1}, {4, 1}});
826 IntPair int_pairs[] = {{5, 1}};
827 cont.insert(std::begin(int_pairs), std::end(int_pairs));
828 EXPECT_THAT(cont, ElementsAre(IntPair(1, 1), IntPair(2, 1), IntPair(3, 1),
829 IntPair(4, 1), IntPair(5, 1)));
830 }
831
832 {
833 IntIntMap cont({{1, 1}, {2, 1}, {3, 1}, {4, 1}});
834 IntPair int_pairs[] = {{3, 2}, {1, 2}, {4, 2}, {2, 2}};
835 cont.insert(std::begin(int_pairs), std::end(int_pairs));
836 EXPECT_THAT(cont, ElementsAre(IntPair(1, 1), IntPair(2, 1), IntPair(3, 1),
837 IntPair(4, 1)));
838 }
839
840 {
841 IntIntMap cont({{1, 1}, {2, 1}, {3, 1}, {4, 1}});
842 IntPair int_pairs[] = {{3, 2}, {1, 2}, {4, 2}, {2, 2}, {7, 2}, {6, 2},
843 {8, 2}, {5, 2}, {5, 3}, {6, 3}, {7, 3}, {8, 3}};
844 cont.insert(std::begin(int_pairs), std::end(int_pairs));
845 EXPECT_THAT(cont, ElementsAre(IntPair(1, 1), IntPair(2, 1), IntPair(3, 1),
846 IntPair(4, 1), IntPair(5, 2), IntPair(6, 2),
847 IntPair(7, 2), IntPair(8, 2)));
848 }
849 }
850
851 // template <class... Args>
852 // pair<iterator, bool> emplace(Args&&... args)
853
TYPED_TEST_P(FlatTreeTest,Emplace)854 TYPED_TEST_P(FlatTreeTest, Emplace) {
855 {
856 EmplaceableTree cont;
857
858 std::pair<EmplaceableTree::iterator, bool> result = cont.emplace();
859 EXPECT_TRUE(result.second);
860 EXPECT_EQ(cont.begin(), result.first);
861 EXPECT_EQ(1U, cont.size());
862 EXPECT_EQ(Emplaceable(), *cont.begin());
863
864 result = cont.emplace(2, 3.5);
865 EXPECT_TRUE(result.second);
866 EXPECT_EQ(std::next(cont.begin()), result.first);
867 EXPECT_EQ(2U, cont.size());
868 EXPECT_EQ(Emplaceable(2, 3.5), *result.first);
869
870 result = cont.emplace(2, 3.5);
871 EXPECT_FALSE(result.second);
872 EXPECT_EQ(std::next(cont.begin()), result.first);
873 EXPECT_EQ(2U, cont.size());
874 EXPECT_EQ(Emplaceable(2, 3.5), *result.first);
875 }
876 {
877 TypedTree<TypeParam> cont;
878
879 std::pair<typename TypedTree<TypeParam>::iterator, bool> result =
880 cont.emplace(2);
881 EXPECT_TRUE(result.second);
882 EXPECT_EQ(cont.begin(), result.first);
883 EXPECT_EQ(1U, cont.size());
884 EXPECT_EQ(2, *result.first);
885 }
886 }
887
888 // template <class... Args>
889 // iterator emplace_hint(const_iterator position_hint, Args&&... args)
890
TYPED_TEST_P(FlatTreeTest,EmplacePosition)891 TYPED_TEST_P(FlatTreeTest, EmplacePosition) {
892 {
893 EmplaceableTree cont;
894
895 auto result = cont.emplace_hint(cont.cend());
896 EXPECT_EQ(cont.begin(), result);
897 EXPECT_EQ(1U, cont.size());
898 EXPECT_EQ(Emplaceable(), *cont.begin());
899
900 result = cont.emplace_hint(cont.cend(), 2, 3.5);
901 EXPECT_EQ(std::next(cont.begin()), result);
902 EXPECT_EQ(2U, cont.size());
903 EXPECT_EQ(Emplaceable(2, 3.5), *result);
904
905 result = cont.emplace_hint(cont.cbegin(), 2, 3.5);
906 EXPECT_EQ(std::next(cont.begin()), result);
907 EXPECT_EQ(2U, cont.size());
908 EXPECT_EQ(Emplaceable(2, 3.5), *result);
909 }
910 {
911 TypedTree<TypeParam> cont;
912
913 auto result = cont.emplace_hint(cont.cend(), 2);
914 EXPECT_EQ(cont.begin(), result);
915 EXPECT_EQ(1U, cont.size());
916 EXPECT_EQ(2, *result);
917 }
918 }
919
920 // ----------------------------------------------------------------------------
921 // Underlying type operations.
922
923 // underlying_type extract() &&
TYPED_TEST_P(FlatTreeTest,Extract)924 TYPED_TEST_P(FlatTreeTest, Extract) {
925 TypedTree<TypeParam> cont;
926 cont.emplace(3);
927 cont.emplace(1);
928 cont.emplace(2);
929 cont.emplace(4);
930
931 TypeParam body = std::move(cont).extract();
932 EXPECT_THAT(cont, IsEmpty());
933 EXPECT_THAT(body, ElementsAre(1, 2, 3, 4));
934 }
935
936 // replace(underlying_type&&)
TYPED_TEST_P(FlatTreeTest,Replace)937 TYPED_TEST_P(FlatTreeTest, Replace) {
938 TypeParam body = {1, 2, 3, 4};
939 TypedTree<TypeParam> cont;
940 cont.replace(std::move(body));
941
942 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4));
943 }
944
945 // ----------------------------------------------------------------------------
946 // Erase operations.
947
948 // iterator erase(const_iterator position_hint)
949
TYPED_TEST_P(FlatTreeTest,ErasePosition)950 TYPED_TEST_P(FlatTreeTest, ErasePosition) {
951 {
952 TypedTree<TypeParam> cont({1, 2, 3, 4, 5, 6, 7, 8});
953
954 auto it = cont.erase(std::next(cont.cbegin(), 3));
955 EXPECT_EQ(std::next(cont.begin(), 3), it);
956 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 5, 6, 7, 8));
957
958 it = cont.erase(std::next(cont.cbegin(), 0));
959 EXPECT_EQ(cont.begin(), it);
960 EXPECT_THAT(cont, ElementsAre(2, 3, 5, 6, 7, 8));
961
962 it = cont.erase(std::next(cont.cbegin(), 5));
963 EXPECT_EQ(cont.end(), it);
964 EXPECT_THAT(cont, ElementsAre(2, 3, 5, 6, 7));
965
966 it = cont.erase(std::next(cont.cbegin(), 1));
967 EXPECT_EQ(std::next(cont.begin()), it);
968 EXPECT_THAT(cont, ElementsAre(2, 5, 6, 7));
969
970 it = cont.erase(std::next(cont.cbegin(), 2));
971 EXPECT_EQ(std::next(cont.begin(), 2), it);
972 EXPECT_THAT(cont, ElementsAre(2, 5, 7));
973
974 it = cont.erase(std::next(cont.cbegin(), 2));
975 EXPECT_EQ(std::next(cont.begin(), 2), it);
976 EXPECT_THAT(cont, ElementsAre(2, 5));
977
978 it = cont.erase(std::next(cont.cbegin(), 0));
979 EXPECT_EQ(std::next(cont.begin(), 0), it);
980 EXPECT_THAT(cont, ElementsAre(5));
981
982 it = cont.erase(cont.cbegin());
983 EXPECT_EQ(cont.begin(), it);
984 EXPECT_EQ(cont.end(), it);
985 }
986 // This is LWG #2059.
987 // There is a potential ambiguity between erase with an iterator and erase
988 // with a key, if key has a templated constructor.
989 {
990 using T = TemplateConstructor;
991
992 flat_tree<T, std::identity, std::less<>, std::vector<T>> cont;
993 T v(0);
994
995 auto it = cont.find(v);
996 if (it != cont.end())
997 cont.erase(it);
998 }
999 }
1000
1001 // iterator erase(const_iterator first, const_iterator last)
1002
TYPED_TEST_P(FlatTreeTest,EraseRange)1003 TYPED_TEST_P(FlatTreeTest, EraseRange) {
1004 TypedTree<TypeParam> cont({1, 2, 3, 4, 5, 6, 7, 8});
1005
1006 auto it =
1007 cont.erase(std::next(cont.cbegin(), 5), std::next(cont.cbegin(), 5));
1008 EXPECT_EQ(std::next(cont.begin(), 5), it);
1009 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 7, 8));
1010
1011 it = cont.erase(std::next(cont.cbegin(), 3), std::next(cont.cbegin(), 4));
1012 EXPECT_EQ(std::next(cont.begin(), 3), it);
1013 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 5, 6, 7, 8));
1014
1015 it = cont.erase(std::next(cont.cbegin(), 2), std::next(cont.cbegin(), 5));
1016 EXPECT_EQ(std::next(cont.begin(), 2), it);
1017 EXPECT_THAT(cont, ElementsAre(1, 2, 7, 8));
1018
1019 it = cont.erase(std::next(cont.cbegin(), 0), std::next(cont.cbegin(), 2));
1020 EXPECT_EQ(std::next(cont.begin(), 0), it);
1021 EXPECT_THAT(cont, ElementsAre(7, 8));
1022
1023 it = cont.erase(cont.cbegin(), cont.cend());
1024 EXPECT_EQ(cont.begin(), it);
1025 EXPECT_EQ(cont.end(), it);
1026 }
1027
1028 // size_type erase(const key_type& key)
1029
TYPED_TEST_P(FlatTreeTest,EraseKey)1030 TYPED_TEST_P(FlatTreeTest, EraseKey) {
1031 TypedTree<TypeParam> cont({1, 2, 3, 4, 5, 6, 7, 8});
1032
1033 EXPECT_EQ(0U, cont.erase(9));
1034 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 4, 5, 6, 7, 8));
1035
1036 EXPECT_EQ(1U, cont.erase(4));
1037 EXPECT_THAT(cont, ElementsAre(1, 2, 3, 5, 6, 7, 8));
1038
1039 EXPECT_EQ(1U, cont.erase(1));
1040 EXPECT_THAT(cont, ElementsAre(2, 3, 5, 6, 7, 8));
1041
1042 EXPECT_EQ(1U, cont.erase(8));
1043 EXPECT_THAT(cont, ElementsAre(2, 3, 5, 6, 7));
1044
1045 EXPECT_EQ(1U, cont.erase(3));
1046 EXPECT_THAT(cont, ElementsAre(2, 5, 6, 7));
1047
1048 EXPECT_EQ(1U, cont.erase(6));
1049 EXPECT_THAT(cont, ElementsAre(2, 5, 7));
1050
1051 EXPECT_EQ(1U, cont.erase(7));
1052 EXPECT_THAT(cont, ElementsAre(2, 5));
1053
1054 EXPECT_EQ(1U, cont.erase(2));
1055 EXPECT_THAT(cont, ElementsAre(5));
1056
1057 EXPECT_EQ(1U, cont.erase(5));
1058 EXPECT_THAT(cont, ElementsAre());
1059 }
1060
TYPED_TEST_P(FlatTreeTest,EraseEndDeath)1061 TYPED_TEST_P(FlatTreeTest, EraseEndDeath) {
1062 {
1063 TypedTree<TypeParam> tree;
1064 ASSERT_DEATH_IF_SUPPORTED(tree.erase(tree.cend()), "");
1065 }
1066
1067 {
1068 TypedTree<TypeParam> tree = {1, 2, 3, 4};
1069 ASSERT_DEATH_IF_SUPPORTED(tree.erase(tree.find(5)), "");
1070 }
1071 }
1072
1073 // ----------------------------------------------------------------------------
1074 // Comparators.
1075
1076 // key_compare key_comp() const
1077
TEST(FlatTree,KeyComp)1078 TEST(FlatTree, KeyComp) {
1079 ReversedTree cont({1, 2, 3, 4, 5});
1080
1081 EXPECT_TRUE(ranges::is_sorted(cont, cont.key_comp()));
1082 int new_elements[] = {6, 7, 8, 9, 10};
1083 ranges::copy(new_elements, std::inserter(cont, cont.end()));
1084 EXPECT_TRUE(ranges::is_sorted(cont, cont.key_comp()));
1085 }
1086
1087 // value_compare value_comp() const
1088
TEST(FlatTree,ValueComp)1089 TEST(FlatTree, ValueComp) {
1090 ReversedTree cont({1, 2, 3, 4, 5});
1091
1092 EXPECT_TRUE(ranges::is_sorted(cont, cont.value_comp()));
1093 int new_elements[] = {6, 7, 8, 9, 10};
1094 ranges::copy(new_elements, std::inserter(cont, cont.end()));
1095 EXPECT_TRUE(ranges::is_sorted(cont, cont.value_comp()));
1096 }
1097
1098 // ----------------------------------------------------------------------------
1099 // Search operations.
1100
1101 // size_type count(const key_type& key) const
1102
TYPED_TEST_P(FlatTreeTest,Count)1103 TYPED_TEST_P(FlatTreeTest, Count) {
1104 const TypedTree<TypeParam> cont({5, 6, 7, 8, 9, 10, 11, 12});
1105
1106 EXPECT_EQ(1U, cont.count(5));
1107 EXPECT_EQ(1U, cont.count(6));
1108 EXPECT_EQ(1U, cont.count(7));
1109 EXPECT_EQ(1U, cont.count(8));
1110 EXPECT_EQ(1U, cont.count(9));
1111 EXPECT_EQ(1U, cont.count(10));
1112 EXPECT_EQ(1U, cont.count(11));
1113 EXPECT_EQ(1U, cont.count(12));
1114 EXPECT_EQ(0U, cont.count(4));
1115 }
1116
1117 // iterator find(const key_type& key)
1118 // const_iterator find(const key_type& key) const
1119
TYPED_TEST_P(FlatTreeTest,Find)1120 TYPED_TEST_P(FlatTreeTest, Find) {
1121 {
1122 TypedTree<TypeParam> cont({5, 6, 7, 8, 9, 10, 11, 12});
1123
1124 EXPECT_EQ(cont.begin(), cont.find(5));
1125 EXPECT_EQ(std::next(cont.begin()), cont.find(6));
1126 EXPECT_EQ(std::next(cont.begin(), 2), cont.find(7));
1127 EXPECT_EQ(std::next(cont.begin(), 3), cont.find(8));
1128 EXPECT_EQ(std::next(cont.begin(), 4), cont.find(9));
1129 EXPECT_EQ(std::next(cont.begin(), 5), cont.find(10));
1130 EXPECT_EQ(std::next(cont.begin(), 6), cont.find(11));
1131 EXPECT_EQ(std::next(cont.begin(), 7), cont.find(12));
1132 EXPECT_EQ(std::next(cont.begin(), 8), cont.find(4));
1133 }
1134 {
1135 const TypedTree<TypeParam> cont({5, 6, 7, 8, 9, 10, 11, 12});
1136
1137 EXPECT_EQ(cont.begin(), cont.find(5));
1138 EXPECT_EQ(std::next(cont.begin()), cont.find(6));
1139 EXPECT_EQ(std::next(cont.begin(), 2), cont.find(7));
1140 EXPECT_EQ(std::next(cont.begin(), 3), cont.find(8));
1141 EXPECT_EQ(std::next(cont.begin(), 4), cont.find(9));
1142 EXPECT_EQ(std::next(cont.begin(), 5), cont.find(10));
1143 EXPECT_EQ(std::next(cont.begin(), 6), cont.find(11));
1144 EXPECT_EQ(std::next(cont.begin(), 7), cont.find(12));
1145 EXPECT_EQ(std::next(cont.begin(), 8), cont.find(4));
1146 }
1147 }
1148
1149 // bool contains(const key_type& key) const
1150
TYPED_TEST_P(FlatTreeTest,Contains)1151 TYPED_TEST_P(FlatTreeTest, Contains) {
1152 const TypedTree<TypeParam> cont({5, 6, 7, 8, 9, 10, 11, 12});
1153
1154 EXPECT_TRUE(cont.contains(5));
1155 EXPECT_TRUE(cont.contains(6));
1156 EXPECT_TRUE(cont.contains(7));
1157 EXPECT_TRUE(cont.contains(8));
1158 EXPECT_TRUE(cont.contains(9));
1159 EXPECT_TRUE(cont.contains(10));
1160 EXPECT_TRUE(cont.contains(11));
1161 EXPECT_TRUE(cont.contains(12));
1162 EXPECT_FALSE(cont.contains(4));
1163 }
1164
1165 // pair<iterator, iterator> equal_range(const key_type& key)
1166 // pair<const_iterator, const_iterator> equal_range(const key_type& key) const
1167
TYPED_TEST_P(FlatTreeTest,EqualRange)1168 TYPED_TEST_P(FlatTreeTest, EqualRange) {
1169 {
1170 TypedTree<TypeParam> cont({5, 7, 9, 11, 13, 15, 17, 19});
1171
1172 std::pair<typename TypedTree<TypeParam>::iterator,
1173 typename TypedTree<TypeParam>::iterator>
1174 result = cont.equal_range(5);
1175 EXPECT_EQ(std::next(cont.begin(), 0), result.first);
1176 EXPECT_EQ(std::next(cont.begin(), 1), result.second);
1177 result = cont.equal_range(7);
1178 EXPECT_EQ(std::next(cont.begin(), 1), result.first);
1179 EXPECT_EQ(std::next(cont.begin(), 2), result.second);
1180 result = cont.equal_range(9);
1181 EXPECT_EQ(std::next(cont.begin(), 2), result.first);
1182 EXPECT_EQ(std::next(cont.begin(), 3), result.second);
1183 result = cont.equal_range(11);
1184 EXPECT_EQ(std::next(cont.begin(), 3), result.first);
1185 EXPECT_EQ(std::next(cont.begin(), 4), result.second);
1186 result = cont.equal_range(13);
1187 EXPECT_EQ(std::next(cont.begin(), 4), result.first);
1188 EXPECT_EQ(std::next(cont.begin(), 5), result.second);
1189 result = cont.equal_range(15);
1190 EXPECT_EQ(std::next(cont.begin(), 5), result.first);
1191 EXPECT_EQ(std::next(cont.begin(), 6), result.second);
1192 result = cont.equal_range(17);
1193 EXPECT_EQ(std::next(cont.begin(), 6), result.first);
1194 EXPECT_EQ(std::next(cont.begin(), 7), result.second);
1195 result = cont.equal_range(19);
1196 EXPECT_EQ(std::next(cont.begin(), 7), result.first);
1197 EXPECT_EQ(std::next(cont.begin(), 8), result.second);
1198 result = cont.equal_range(4);
1199 EXPECT_EQ(std::next(cont.begin(), 0), result.first);
1200 EXPECT_EQ(std::next(cont.begin(), 0), result.second);
1201 result = cont.equal_range(6);
1202 EXPECT_EQ(std::next(cont.begin(), 1), result.first);
1203 EXPECT_EQ(std::next(cont.begin(), 1), result.second);
1204 result = cont.equal_range(8);
1205 EXPECT_EQ(std::next(cont.begin(), 2), result.first);
1206 EXPECT_EQ(std::next(cont.begin(), 2), result.second);
1207 result = cont.equal_range(10);
1208 EXPECT_EQ(std::next(cont.begin(), 3), result.first);
1209 EXPECT_EQ(std::next(cont.begin(), 3), result.second);
1210 result = cont.equal_range(12);
1211 EXPECT_EQ(std::next(cont.begin(), 4), result.first);
1212 EXPECT_EQ(std::next(cont.begin(), 4), result.second);
1213 result = cont.equal_range(14);
1214 EXPECT_EQ(std::next(cont.begin(), 5), result.first);
1215 EXPECT_EQ(std::next(cont.begin(), 5), result.second);
1216 result = cont.equal_range(16);
1217 EXPECT_EQ(std::next(cont.begin(), 6), result.first);
1218 EXPECT_EQ(std::next(cont.begin(), 6), result.second);
1219 result = cont.equal_range(18);
1220 EXPECT_EQ(std::next(cont.begin(), 7), result.first);
1221 EXPECT_EQ(std::next(cont.begin(), 7), result.second);
1222 result = cont.equal_range(20);
1223 EXPECT_EQ(std::next(cont.begin(), 8), result.first);
1224 EXPECT_EQ(std::next(cont.begin(), 8), result.second);
1225 }
1226 {
1227 const TypedTree<TypeParam> cont({5, 7, 9, 11, 13, 15, 17, 19});
1228
1229 std::pair<typename TypedTree<TypeParam>::const_iterator,
1230 typename TypedTree<TypeParam>::const_iterator>
1231 result = cont.equal_range(5);
1232 EXPECT_EQ(std::next(cont.begin(), 0), result.first);
1233 EXPECT_EQ(std::next(cont.begin(), 1), result.second);
1234 result = cont.equal_range(7);
1235 EXPECT_EQ(std::next(cont.begin(), 1), result.first);
1236 EXPECT_EQ(std::next(cont.begin(), 2), result.second);
1237 result = cont.equal_range(9);
1238 EXPECT_EQ(std::next(cont.begin(), 2), result.first);
1239 EXPECT_EQ(std::next(cont.begin(), 3), result.second);
1240 result = cont.equal_range(11);
1241 EXPECT_EQ(std::next(cont.begin(), 3), result.first);
1242 EXPECT_EQ(std::next(cont.begin(), 4), result.second);
1243 result = cont.equal_range(13);
1244 EXPECT_EQ(std::next(cont.begin(), 4), result.first);
1245 EXPECT_EQ(std::next(cont.begin(), 5), result.second);
1246 result = cont.equal_range(15);
1247 EXPECT_EQ(std::next(cont.begin(), 5), result.first);
1248 EXPECT_EQ(std::next(cont.begin(), 6), result.second);
1249 result = cont.equal_range(17);
1250 EXPECT_EQ(std::next(cont.begin(), 6), result.first);
1251 EXPECT_EQ(std::next(cont.begin(), 7), result.second);
1252 result = cont.equal_range(19);
1253 EXPECT_EQ(std::next(cont.begin(), 7), result.first);
1254 EXPECT_EQ(std::next(cont.begin(), 8), result.second);
1255 result = cont.equal_range(4);
1256 EXPECT_EQ(std::next(cont.begin(), 0), result.first);
1257 EXPECT_EQ(std::next(cont.begin(), 0), result.second);
1258 result = cont.equal_range(6);
1259 EXPECT_EQ(std::next(cont.begin(), 1), result.first);
1260 EXPECT_EQ(std::next(cont.begin(), 1), result.second);
1261 result = cont.equal_range(8);
1262 EXPECT_EQ(std::next(cont.begin(), 2), result.first);
1263 EXPECT_EQ(std::next(cont.begin(), 2), result.second);
1264 result = cont.equal_range(10);
1265 EXPECT_EQ(std::next(cont.begin(), 3), result.first);
1266 EXPECT_EQ(std::next(cont.begin(), 3), result.second);
1267 result = cont.equal_range(12);
1268 EXPECT_EQ(std::next(cont.begin(), 4), result.first);
1269 EXPECT_EQ(std::next(cont.begin(), 4), result.second);
1270 result = cont.equal_range(14);
1271 EXPECT_EQ(std::next(cont.begin(), 5), result.first);
1272 EXPECT_EQ(std::next(cont.begin(), 5), result.second);
1273 result = cont.equal_range(16);
1274 EXPECT_EQ(std::next(cont.begin(), 6), result.first);
1275 EXPECT_EQ(std::next(cont.begin(), 6), result.second);
1276 result = cont.equal_range(18);
1277 EXPECT_EQ(std::next(cont.begin(), 7), result.first);
1278 EXPECT_EQ(std::next(cont.begin(), 7), result.second);
1279 result = cont.equal_range(20);
1280 EXPECT_EQ(std::next(cont.begin(), 8), result.first);
1281 EXPECT_EQ(std::next(cont.begin(), 8), result.second);
1282 }
1283 }
1284
1285 // iterator lower_bound(const key_type& key);
1286 // const_iterator lower_bound(const key_type& key) const;
1287
TYPED_TEST_P(FlatTreeTest,LowerBound)1288 TYPED_TEST_P(FlatTreeTest, LowerBound) {
1289 {
1290 TypedTree<TypeParam> cont({5, 7, 9, 11, 13, 15, 17, 19});
1291
1292 EXPECT_EQ(cont.begin(), cont.lower_bound(5));
1293 EXPECT_EQ(std::next(cont.begin()), cont.lower_bound(7));
1294 EXPECT_EQ(std::next(cont.begin(), 2), cont.lower_bound(9));
1295 EXPECT_EQ(std::next(cont.begin(), 3), cont.lower_bound(11));
1296 EXPECT_EQ(std::next(cont.begin(), 4), cont.lower_bound(13));
1297 EXPECT_EQ(std::next(cont.begin(), 5), cont.lower_bound(15));
1298 EXPECT_EQ(std::next(cont.begin(), 6), cont.lower_bound(17));
1299 EXPECT_EQ(std::next(cont.begin(), 7), cont.lower_bound(19));
1300 EXPECT_EQ(std::next(cont.begin(), 0), cont.lower_bound(4));
1301 EXPECT_EQ(std::next(cont.begin(), 1), cont.lower_bound(6));
1302 EXPECT_EQ(std::next(cont.begin(), 2), cont.lower_bound(8));
1303 EXPECT_EQ(std::next(cont.begin(), 3), cont.lower_bound(10));
1304 EXPECT_EQ(std::next(cont.begin(), 4), cont.lower_bound(12));
1305 EXPECT_EQ(std::next(cont.begin(), 5), cont.lower_bound(14));
1306 EXPECT_EQ(std::next(cont.begin(), 6), cont.lower_bound(16));
1307 EXPECT_EQ(std::next(cont.begin(), 7), cont.lower_bound(18));
1308 EXPECT_EQ(std::next(cont.begin(), 8), cont.lower_bound(20));
1309 }
1310 {
1311 const TypedTree<TypeParam> cont({5, 7, 9, 11, 13, 15, 17, 19});
1312
1313 EXPECT_EQ(cont.begin(), cont.lower_bound(5));
1314 EXPECT_EQ(std::next(cont.begin()), cont.lower_bound(7));
1315 EXPECT_EQ(std::next(cont.begin(), 2), cont.lower_bound(9));
1316 EXPECT_EQ(std::next(cont.begin(), 3), cont.lower_bound(11));
1317 EXPECT_EQ(std::next(cont.begin(), 4), cont.lower_bound(13));
1318 EXPECT_EQ(std::next(cont.begin(), 5), cont.lower_bound(15));
1319 EXPECT_EQ(std::next(cont.begin(), 6), cont.lower_bound(17));
1320 EXPECT_EQ(std::next(cont.begin(), 7), cont.lower_bound(19));
1321 EXPECT_EQ(std::next(cont.begin(), 0), cont.lower_bound(4));
1322 EXPECT_EQ(std::next(cont.begin(), 1), cont.lower_bound(6));
1323 EXPECT_EQ(std::next(cont.begin(), 2), cont.lower_bound(8));
1324 EXPECT_EQ(std::next(cont.begin(), 3), cont.lower_bound(10));
1325 EXPECT_EQ(std::next(cont.begin(), 4), cont.lower_bound(12));
1326 EXPECT_EQ(std::next(cont.begin(), 5), cont.lower_bound(14));
1327 EXPECT_EQ(std::next(cont.begin(), 6), cont.lower_bound(16));
1328 EXPECT_EQ(std::next(cont.begin(), 7), cont.lower_bound(18));
1329 EXPECT_EQ(std::next(cont.begin(), 8), cont.lower_bound(20));
1330 }
1331 }
1332
1333 // iterator upper_bound(const key_type& key)
1334 // const_iterator upper_bound(const key_type& key) const
1335
TYPED_TEST_P(FlatTreeTest,UpperBound)1336 TYPED_TEST_P(FlatTreeTest, UpperBound) {
1337 {
1338 TypedTree<TypeParam> cont({5, 7, 9, 11, 13, 15, 17, 19});
1339
1340 EXPECT_EQ(std::next(cont.begin(), 1), cont.upper_bound(5));
1341 EXPECT_EQ(std::next(cont.begin(), 2), cont.upper_bound(7));
1342 EXPECT_EQ(std::next(cont.begin(), 3), cont.upper_bound(9));
1343 EXPECT_EQ(std::next(cont.begin(), 4), cont.upper_bound(11));
1344 EXPECT_EQ(std::next(cont.begin(), 5), cont.upper_bound(13));
1345 EXPECT_EQ(std::next(cont.begin(), 6), cont.upper_bound(15));
1346 EXPECT_EQ(std::next(cont.begin(), 7), cont.upper_bound(17));
1347 EXPECT_EQ(std::next(cont.begin(), 8), cont.upper_bound(19));
1348 EXPECT_EQ(std::next(cont.begin(), 0), cont.upper_bound(4));
1349 EXPECT_EQ(std::next(cont.begin(), 1), cont.upper_bound(6));
1350 EXPECT_EQ(std::next(cont.begin(), 2), cont.upper_bound(8));
1351 EXPECT_EQ(std::next(cont.begin(), 3), cont.upper_bound(10));
1352 EXPECT_EQ(std::next(cont.begin(), 4), cont.upper_bound(12));
1353 EXPECT_EQ(std::next(cont.begin(), 5), cont.upper_bound(14));
1354 EXPECT_EQ(std::next(cont.begin(), 6), cont.upper_bound(16));
1355 EXPECT_EQ(std::next(cont.begin(), 7), cont.upper_bound(18));
1356 EXPECT_EQ(std::next(cont.begin(), 8), cont.upper_bound(20));
1357 }
1358 {
1359 const TypedTree<TypeParam> cont({5, 7, 9, 11, 13, 15, 17, 19});
1360
1361 EXPECT_EQ(std::next(cont.begin(), 1), cont.upper_bound(5));
1362 EXPECT_EQ(std::next(cont.begin(), 2), cont.upper_bound(7));
1363 EXPECT_EQ(std::next(cont.begin(), 3), cont.upper_bound(9));
1364 EXPECT_EQ(std::next(cont.begin(), 4), cont.upper_bound(11));
1365 EXPECT_EQ(std::next(cont.begin(), 5), cont.upper_bound(13));
1366 EXPECT_EQ(std::next(cont.begin(), 6), cont.upper_bound(15));
1367 EXPECT_EQ(std::next(cont.begin(), 7), cont.upper_bound(17));
1368 EXPECT_EQ(std::next(cont.begin(), 8), cont.upper_bound(19));
1369 EXPECT_EQ(std::next(cont.begin(), 0), cont.upper_bound(4));
1370 EXPECT_EQ(std::next(cont.begin(), 1), cont.upper_bound(6));
1371 EXPECT_EQ(std::next(cont.begin(), 2), cont.upper_bound(8));
1372 EXPECT_EQ(std::next(cont.begin(), 3), cont.upper_bound(10));
1373 EXPECT_EQ(std::next(cont.begin(), 4), cont.upper_bound(12));
1374 EXPECT_EQ(std::next(cont.begin(), 5), cont.upper_bound(14));
1375 EXPECT_EQ(std::next(cont.begin(), 6), cont.upper_bound(16));
1376 EXPECT_EQ(std::next(cont.begin(), 7), cont.upper_bound(18));
1377 EXPECT_EQ(std::next(cont.begin(), 8), cont.upper_bound(20));
1378 }
1379 }
1380
1381 // ----------------------------------------------------------------------------
1382 // General operations.
1383
1384 // void swap(flat_tree& other)
1385 // void swap(flat_tree& lhs, flat_tree& rhs)
1386
TYPED_TEST_P(FlatTreeTest,Swap)1387 TYPED_TEST_P(FlatTreeTest, Swap) {
1388 TypedTree<TypeParam> x({1, 2, 3});
1389 TypedTree<TypeParam> y({4});
1390 swap(x, y);
1391 EXPECT_THAT(x, ElementsAre(4));
1392 EXPECT_THAT(y, ElementsAre(1, 2, 3));
1393
1394 y.swap(x);
1395 EXPECT_THAT(x, ElementsAre(1, 2, 3));
1396 EXPECT_THAT(y, ElementsAre(4));
1397 }
1398
1399 // bool operator==(const flat_tree& lhs, const flat_tree& rhs)
1400 // bool operator!=(const flat_tree& lhs, const flat_tree& rhs)
1401 // bool operator<(const flat_tree& lhs, const flat_tree& rhs)
1402 // bool operator>(const flat_tree& lhs, const flat_tree& rhs)
1403 // bool operator<=(const flat_tree& lhs, const flat_tree& rhs)
1404 // bool operator>=(const flat_tree& lhs, const flat_tree& rhs)
1405
TEST(FlatTree,Comparison)1406 TEST(FlatTree, Comparison) {
1407 // Provided comparator does not participate in comparison.
1408 ReversedTree biggest({3});
1409 ReversedTree smallest({1});
1410 ReversedTree middle({1, 2});
1411
1412 EXPECT_EQ(biggest, biggest);
1413 EXPECT_NE(biggest, smallest);
1414 EXPECT_LT(smallest, middle);
1415 EXPECT_LE(smallest, middle);
1416 EXPECT_LE(middle, middle);
1417 EXPECT_GT(biggest, middle);
1418 EXPECT_GE(biggest, middle);
1419 EXPECT_GE(biggest, biggest);
1420 }
1421
TYPED_TEST_P(FlatTreeTest,EraseIf)1422 TYPED_TEST_P(FlatTreeTest, EraseIf) {
1423 TypedTree<TypeParam> x;
1424 EXPECT_EQ(0u, base::EraseIf(x, [](int) { return false; }));
1425 EXPECT_THAT(x, ElementsAre());
1426
1427 x = {1, 2, 3};
1428 EXPECT_EQ(1u, base::EraseIf(x, [](int elem) { return !(elem & 1); }));
1429 EXPECT_THAT(x, ElementsAre(1, 3));
1430
1431 x = {1, 2, 3, 4};
1432 EXPECT_EQ(2u, base::EraseIf(x, [](int elem) { return elem & 1; }));
1433 EXPECT_THAT(x, ElementsAre(2, 4));
1434 }
1435
1436 // Test unsorted containers or containers with repeated elements cause a DCHECK
1437 // if used with the sorted_unique tag.
TYPED_TEST_P(FlatTreeTest,SortedUniqueRangeConstructorDCHECKs)1438 TYPED_TEST_P(FlatTreeTest, SortedUniqueRangeConstructorDCHECKs) {
1439 int unsorted[] = {2, 1};
1440 EXPECT_DCHECK_DEATH(TypedTree<TypeParam>(sorted_unique, std::begin(unsorted),
1441 std::end(unsorted)));
1442
1443 int repeated[] = {1, 2, 2};
1444 EXPECT_DCHECK_DEATH(TypedTree<TypeParam>(sorted_unique, std::begin(repeated),
1445 std::end(repeated)));
1446 }
1447
TYPED_TEST_P(FlatTreeTest,SortedUniqueVectorCopyConstructorDCHECKs)1448 TYPED_TEST_P(FlatTreeTest, SortedUniqueVectorCopyConstructorDCHECKs) {
1449 TypeParam unsorted = {2, 1};
1450 EXPECT_DCHECK_DEATH(TypedTree<TypeParam>(sorted_unique, unsorted));
1451
1452 TypeParam repeated = {1, 2, 2};
1453 EXPECT_DCHECK_DEATH(TypedTree<TypeParam>(sorted_unique, repeated));
1454 }
1455
TYPED_TEST_P(FlatTreeTest,SortedUniqueVectorMoveConstructorDCHECKs)1456 TYPED_TEST_P(FlatTreeTest, SortedUniqueVectorMoveConstructorDCHECKs) {
1457 TypeParam unsorted = {2, 1};
1458 EXPECT_DCHECK_DEATH(TypedTree<TypeParam>(sorted_unique, std::move(unsorted)));
1459
1460 TypeParam repeated = {1, 2, 2};
1461 EXPECT_DCHECK_DEATH(TypedTree<TypeParam>(sorted_unique, std::move(repeated)));
1462 }
1463
TYPED_TEST_P(FlatTreeTest,SortedUniqueInitializerListConstructorDCHECKs)1464 TYPED_TEST_P(FlatTreeTest, SortedUniqueInitializerListConstructorDCHECKs) {
1465 std::initializer_list<int> unsorted = {2, 1};
1466 EXPECT_DCHECK_DEATH(TypedTree<TypeParam>(sorted_unique, unsorted));
1467
1468 std::initializer_list<int> repeated = {1, 2, 2};
1469 EXPECT_DCHECK_DEATH(TypedTree<TypeParam>(sorted_unique, repeated));
1470 }
1471
TYPED_TEST_P(FlatTreeTest,ReplaceDCHECKs)1472 TYPED_TEST_P(FlatTreeTest, ReplaceDCHECKs) {
1473 TypedTree<TypeParam> tree;
1474 TypeParam unsorted = {2, 1};
1475 EXPECT_DCHECK_DEATH(tree.replace(std::move(unsorted)));
1476
1477 TypeParam repeated = {1, 2, 2};
1478 EXPECT_DCHECK_DEATH(tree.replace(std::move(repeated)));
1479 }
1480
1481 REGISTER_TYPED_TEST_SUITE_P(FlatTreeTest,
1482 DefaultConstructor,
1483 CopyConstructor,
1484 ContainerCopyConstructor,
1485 InitializerListConstructor,
1486 SortedUniqueContainerCopyConstructor,
1487 SortedUniqueInitializerListConstructor,
1488 CopyAssignable,
1489 InitializerListAssignable,
1490 Clear,
1491 Size,
1492 Empty,
1493 Iterators,
1494 InsertLValue,
1495 InsertPositionLValue,
1496 Emplace,
1497 EmplacePosition,
1498 Extract,
1499 Replace,
1500 ErasePosition,
1501 EraseRange,
1502 EraseKey,
1503 EraseEndDeath,
1504 Count,
1505 Find,
1506 Contains,
1507 EqualRange,
1508 LowerBound,
1509 UpperBound,
1510 Swap,
1511 EraseIf,
1512 SortedUniqueRangeConstructorDCHECKs,
1513 SortedUniqueVectorCopyConstructorDCHECKs,
1514 SortedUniqueVectorMoveConstructorDCHECKs,
1515 SortedUniqueInitializerListConstructorDCHECKs,
1516 ReplaceDCHECKs);
1517
1518 using IntSequenceContainers =
1519 ::testing::Types<std::deque<int>, std::vector<int>>;
1520 INSTANTIATE_TYPED_TEST_SUITE_P(My, FlatTreeTest, IntSequenceContainers);
1521
1522 } // namespace internal
1523 } // namespace base
1524