xref: /aosp_15_r20/external/cronet/base/containers/flat_tree_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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