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