• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/container/btree_test.h"
16 
17 #include <algorithm>
18 #include <array>
19 #include <cstdint>
20 #include <functional>
21 #include <iostream>
22 #include <iterator>
23 #include <limits>
24 #include <map>
25 #include <memory>
26 #include <numeric>
27 #include <stdexcept>
28 #include <string>
29 #include <type_traits>
30 #include <utility>
31 #include <vector>
32 
33 #include "gmock/gmock.h"
34 #include "gtest/gtest.h"
35 #include "absl/algorithm/container.h"
36 #include "absl/base/internal/raw_logging.h"
37 #include "absl/base/macros.h"
38 #include "absl/container/btree_map.h"
39 #include "absl/container/btree_set.h"
40 #include "absl/container/internal/counting_allocator.h"
41 #include "absl/container/internal/test_instance_tracker.h"
42 #include "absl/flags/flag.h"
43 #include "absl/hash/hash_testing.h"
44 #include "absl/memory/memory.h"
45 #include "absl/random/random.h"
46 #include "absl/strings/str_cat.h"
47 #include "absl/strings/str_split.h"
48 #include "absl/strings/string_view.h"
49 #include "absl/types/compare.h"
50 #include "absl/types/optional.h"
51 
52 ABSL_FLAG(int, test_values, 10000, "The number of values to use for tests");
53 
54 namespace absl {
55 ABSL_NAMESPACE_BEGIN
56 namespace container_internal {
57 namespace {
58 
59 using ::absl::test_internal::CopyableMovableInstance;
60 using ::absl::test_internal::InstanceTracker;
61 using ::absl::test_internal::MovableOnlyInstance;
62 using ::testing::ElementsAre;
63 using ::testing::ElementsAreArray;
64 using ::testing::IsEmpty;
65 using ::testing::IsNull;
66 using ::testing::Pair;
67 using ::testing::SizeIs;
68 
69 template <typename T, typename U>
CheckPairEquals(const T & x,const U & y)70 void CheckPairEquals(const T &x, const U &y) {
71   ABSL_INTERNAL_CHECK(x == y, "Values are unequal.");
72 }
73 
74 template <typename T, typename U, typename V, typename W>
CheckPairEquals(const std::pair<T,U> & x,const std::pair<V,W> & y)75 void CheckPairEquals(const std::pair<T, U> &x, const std::pair<V, W> &y) {
76   CheckPairEquals(x.first, y.first);
77   CheckPairEquals(x.second, y.second);
78 }
79 
IsAssertEnabled()80 bool IsAssertEnabled() {
81   // Use an assert with side-effects to figure out if they are actually enabled.
82   bool assert_enabled = false;
83   assert([&]() {  // NOLINT
84     assert_enabled = true;
85     return true;
86   }());
87   return assert_enabled;
88 }
89 }  // namespace
90 
91 // The base class for a sorted associative container checker. TreeType is the
92 // container type to check and CheckerType is the container type to check
93 // against. TreeType is expected to be btree_{set,map,multiset,multimap} and
94 // CheckerType is expected to be {set,map,multiset,multimap}.
95 template <typename TreeType, typename CheckerType>
96 class base_checker {
97  public:
98   using key_type = typename TreeType::key_type;
99   using value_type = typename TreeType::value_type;
100   using key_compare = typename TreeType::key_compare;
101   using pointer = typename TreeType::pointer;
102   using const_pointer = typename TreeType::const_pointer;
103   using reference = typename TreeType::reference;
104   using const_reference = typename TreeType::const_reference;
105   using size_type = typename TreeType::size_type;
106   using difference_type = typename TreeType::difference_type;
107   using iterator = typename TreeType::iterator;
108   using const_iterator = typename TreeType::const_iterator;
109   using reverse_iterator = typename TreeType::reverse_iterator;
110   using const_reverse_iterator = typename TreeType::const_reverse_iterator;
111 
112  public:
base_checker()113   base_checker() : const_tree_(tree_) {}
base_checker(const base_checker & other)114   base_checker(const base_checker &other)
115       : tree_(other.tree_), const_tree_(tree_), checker_(other.checker_) {}
116   template <typename InputIterator>
base_checker(InputIterator b,InputIterator e)117   base_checker(InputIterator b, InputIterator e)
118       : tree_(b, e), const_tree_(tree_), checker_(b, e) {}
119 
begin()120   iterator begin() { return tree_.begin(); }
begin() const121   const_iterator begin() const { return tree_.begin(); }
end()122   iterator end() { return tree_.end(); }
end() const123   const_iterator end() const { return tree_.end(); }
rbegin()124   reverse_iterator rbegin() { return tree_.rbegin(); }
rbegin() const125   const_reverse_iterator rbegin() const { return tree_.rbegin(); }
rend()126   reverse_iterator rend() { return tree_.rend(); }
rend() const127   const_reverse_iterator rend() const { return tree_.rend(); }
128 
129   template <typename IterType, typename CheckerIterType>
iter_check(IterType tree_iter,CheckerIterType checker_iter) const130   IterType iter_check(IterType tree_iter, CheckerIterType checker_iter) const {
131     if (tree_iter == tree_.end()) {
132       ABSL_INTERNAL_CHECK(checker_iter == checker_.end(),
133                           "Checker iterator not at end.");
134     } else {
135       CheckPairEquals(*tree_iter, *checker_iter);
136     }
137     return tree_iter;
138   }
139   template <typename IterType, typename CheckerIterType>
riter_check(IterType tree_iter,CheckerIterType checker_iter) const140   IterType riter_check(IterType tree_iter, CheckerIterType checker_iter) const {
141     if (tree_iter == tree_.rend()) {
142       ABSL_INTERNAL_CHECK(checker_iter == checker_.rend(),
143                           "Checker iterator not at rend.");
144     } else {
145       CheckPairEquals(*tree_iter, *checker_iter);
146     }
147     return tree_iter;
148   }
value_check(const value_type & v)149   void value_check(const value_type &v) {
150     typename KeyOfValue<typename TreeType::key_type,
151                         typename TreeType::value_type>::type key_of_value;
152     const key_type &key = key_of_value(v);
153     CheckPairEquals(*find(key), v);
154     lower_bound(key);
155     upper_bound(key);
156     equal_range(key);
157     contains(key);
158     count(key);
159   }
erase_check(const key_type & key)160   void erase_check(const key_type &key) {
161     EXPECT_FALSE(tree_.contains(key));
162     EXPECT_EQ(tree_.find(key), const_tree_.end());
163     EXPECT_FALSE(const_tree_.contains(key));
164     EXPECT_EQ(const_tree_.find(key), tree_.end());
165     EXPECT_EQ(tree_.equal_range(key).first,
166               const_tree_.equal_range(key).second);
167   }
168 
lower_bound(const key_type & key)169   iterator lower_bound(const key_type &key) {
170     return iter_check(tree_.lower_bound(key), checker_.lower_bound(key));
171   }
lower_bound(const key_type & key) const172   const_iterator lower_bound(const key_type &key) const {
173     return iter_check(tree_.lower_bound(key), checker_.lower_bound(key));
174   }
upper_bound(const key_type & key)175   iterator upper_bound(const key_type &key) {
176     return iter_check(tree_.upper_bound(key), checker_.upper_bound(key));
177   }
upper_bound(const key_type & key) const178   const_iterator upper_bound(const key_type &key) const {
179     return iter_check(tree_.upper_bound(key), checker_.upper_bound(key));
180   }
equal_range(const key_type & key)181   std::pair<iterator, iterator> equal_range(const key_type &key) {
182     std::pair<typename CheckerType::iterator, typename CheckerType::iterator>
183         checker_res = checker_.equal_range(key);
184     std::pair<iterator, iterator> tree_res = tree_.equal_range(key);
185     iter_check(tree_res.first, checker_res.first);
186     iter_check(tree_res.second, checker_res.second);
187     return tree_res;
188   }
equal_range(const key_type & key) const189   std::pair<const_iterator, const_iterator> equal_range(
190       const key_type &key) const {
191     std::pair<typename CheckerType::const_iterator,
192               typename CheckerType::const_iterator>
193         checker_res = checker_.equal_range(key);
194     std::pair<const_iterator, const_iterator> tree_res = tree_.equal_range(key);
195     iter_check(tree_res.first, checker_res.first);
196     iter_check(tree_res.second, checker_res.second);
197     return tree_res;
198   }
find(const key_type & key)199   iterator find(const key_type &key) {
200     return iter_check(tree_.find(key), checker_.find(key));
201   }
find(const key_type & key) const202   const_iterator find(const key_type &key) const {
203     return iter_check(tree_.find(key), checker_.find(key));
204   }
contains(const key_type & key) const205   bool contains(const key_type &key) const { return find(key) != end(); }
count(const key_type & key) const206   size_type count(const key_type &key) const {
207     size_type res = checker_.count(key);
208     EXPECT_EQ(res, tree_.count(key));
209     return res;
210   }
211 
operator =(const base_checker & other)212   base_checker &operator=(const base_checker &other) {
213     tree_ = other.tree_;
214     checker_ = other.checker_;
215     return *this;
216   }
217 
erase(const key_type & key)218   int erase(const key_type &key) {
219     int size = tree_.size();
220     int res = checker_.erase(key);
221     EXPECT_EQ(res, tree_.count(key));
222     EXPECT_EQ(res, tree_.erase(key));
223     EXPECT_EQ(tree_.count(key), 0);
224     EXPECT_EQ(tree_.size(), size - res);
225     erase_check(key);
226     return res;
227   }
erase(iterator iter)228   iterator erase(iterator iter) {
229     key_type key = iter.key();
230     int size = tree_.size();
231     int count = tree_.count(key);
232     auto checker_iter = checker_.lower_bound(key);
233     for (iterator tmp(tree_.lower_bound(key)); tmp != iter; ++tmp) {
234       ++checker_iter;
235     }
236     auto checker_next = checker_iter;
237     ++checker_next;
238     checker_.erase(checker_iter);
239     iter = tree_.erase(iter);
240     EXPECT_EQ(tree_.size(), checker_.size());
241     EXPECT_EQ(tree_.size(), size - 1);
242     EXPECT_EQ(tree_.count(key), count - 1);
243     if (count == 1) {
244       erase_check(key);
245     }
246     return iter_check(iter, checker_next);
247   }
248 
erase(iterator begin,iterator end)249   void erase(iterator begin, iterator end) {
250     int size = tree_.size();
251     int count = std::distance(begin, end);
252     auto checker_begin = checker_.lower_bound(begin.key());
253     for (iterator tmp(tree_.lower_bound(begin.key())); tmp != begin; ++tmp) {
254       ++checker_begin;
255     }
256     auto checker_end =
257         end == tree_.end() ? checker_.end() : checker_.lower_bound(end.key());
258     if (end != tree_.end()) {
259       for (iterator tmp(tree_.lower_bound(end.key())); tmp != end; ++tmp) {
260         ++checker_end;
261       }
262     }
263     const auto checker_ret = checker_.erase(checker_begin, checker_end);
264     const auto tree_ret = tree_.erase(begin, end);
265     EXPECT_EQ(std::distance(checker_.begin(), checker_ret),
266               std::distance(tree_.begin(), tree_ret));
267     EXPECT_EQ(tree_.size(), checker_.size());
268     EXPECT_EQ(tree_.size(), size - count);
269   }
270 
clear()271   void clear() {
272     tree_.clear();
273     checker_.clear();
274   }
swap(base_checker & other)275   void swap(base_checker &other) {
276     tree_.swap(other.tree_);
277     checker_.swap(other.checker_);
278   }
279 
verify() const280   void verify() const {
281     tree_.verify();
282     EXPECT_EQ(tree_.size(), checker_.size());
283 
284     // Move through the forward iterators using increment.
285     auto checker_iter = checker_.begin();
286     const_iterator tree_iter(tree_.begin());
287     for (; tree_iter != tree_.end(); ++tree_iter, ++checker_iter) {
288       CheckPairEquals(*tree_iter, *checker_iter);
289     }
290 
291     // Move through the forward iterators using decrement.
292     for (int n = tree_.size() - 1; n >= 0; --n) {
293       iter_check(tree_iter, checker_iter);
294       --tree_iter;
295       --checker_iter;
296     }
297     EXPECT_EQ(tree_iter, tree_.begin());
298     EXPECT_EQ(checker_iter, checker_.begin());
299 
300     // Move through the reverse iterators using increment.
301     auto checker_riter = checker_.rbegin();
302     const_reverse_iterator tree_riter(tree_.rbegin());
303     for (; tree_riter != tree_.rend(); ++tree_riter, ++checker_riter) {
304       CheckPairEquals(*tree_riter, *checker_riter);
305     }
306 
307     // Move through the reverse iterators using decrement.
308     for (int n = tree_.size() - 1; n >= 0; --n) {
309       riter_check(tree_riter, checker_riter);
310       --tree_riter;
311       --checker_riter;
312     }
313     EXPECT_EQ(tree_riter, tree_.rbegin());
314     EXPECT_EQ(checker_riter, checker_.rbegin());
315   }
316 
tree() const317   const TreeType &tree() const { return tree_; }
318 
size() const319   size_type size() const {
320     EXPECT_EQ(tree_.size(), checker_.size());
321     return tree_.size();
322   }
max_size() const323   size_type max_size() const { return tree_.max_size(); }
empty() const324   bool empty() const {
325     EXPECT_EQ(tree_.empty(), checker_.empty());
326     return tree_.empty();
327   }
328 
329  protected:
330   TreeType tree_;
331   const TreeType &const_tree_;
332   CheckerType checker_;
333 };
334 
335 namespace {
336 // A checker for unique sorted associative containers. TreeType is expected to
337 // be btree_{set,map} and CheckerType is expected to be {set,map}.
338 template <typename TreeType, typename CheckerType>
339 class unique_checker : public base_checker<TreeType, CheckerType> {
340   using super_type = base_checker<TreeType, CheckerType>;
341 
342  public:
343   using iterator = typename super_type::iterator;
344   using value_type = typename super_type::value_type;
345 
346  public:
unique_checker()347   unique_checker() : super_type() {}
unique_checker(const unique_checker & other)348   unique_checker(const unique_checker &other) : super_type(other) {}
349   template <class InputIterator>
unique_checker(InputIterator b,InputIterator e)350   unique_checker(InputIterator b, InputIterator e) : super_type(b, e) {}
351   unique_checker &operator=(const unique_checker &) = default;
352 
353   // Insertion routines.
insert(const value_type & v)354   std::pair<iterator, bool> insert(const value_type &v) {
355     int size = this->tree_.size();
356     std::pair<typename CheckerType::iterator, bool> checker_res =
357         this->checker_.insert(v);
358     std::pair<iterator, bool> tree_res = this->tree_.insert(v);
359     CheckPairEquals(*tree_res.first, *checker_res.first);
360     EXPECT_EQ(tree_res.second, checker_res.second);
361     EXPECT_EQ(this->tree_.size(), this->checker_.size());
362     EXPECT_EQ(this->tree_.size(), size + tree_res.second);
363     return tree_res;
364   }
insert(iterator position,const value_type & v)365   iterator insert(iterator position, const value_type &v) {
366     int size = this->tree_.size();
367     std::pair<typename CheckerType::iterator, bool> checker_res =
368         this->checker_.insert(v);
369     iterator tree_res = this->tree_.insert(position, v);
370     CheckPairEquals(*tree_res, *checker_res.first);
371     EXPECT_EQ(this->tree_.size(), this->checker_.size());
372     EXPECT_EQ(this->tree_.size(), size + checker_res.second);
373     return tree_res;
374   }
375   template <typename InputIterator>
insert(InputIterator b,InputIterator e)376   void insert(InputIterator b, InputIterator e) {
377     for (; b != e; ++b) {
378       insert(*b);
379     }
380   }
381 };
382 
383 // A checker for multiple sorted associative containers. TreeType is expected
384 // to be btree_{multiset,multimap} and CheckerType is expected to be
385 // {multiset,multimap}.
386 template <typename TreeType, typename CheckerType>
387 class multi_checker : public base_checker<TreeType, CheckerType> {
388   using super_type = base_checker<TreeType, CheckerType>;
389 
390  public:
391   using iterator = typename super_type::iterator;
392   using value_type = typename super_type::value_type;
393 
394  public:
multi_checker()395   multi_checker() : super_type() {}
multi_checker(const multi_checker & other)396   multi_checker(const multi_checker &other) : super_type(other) {}
397   template <class InputIterator>
multi_checker(InputIterator b,InputIterator e)398   multi_checker(InputIterator b, InputIterator e) : super_type(b, e) {}
399   multi_checker &operator=(const multi_checker &) = default;
400 
401   // Insertion routines.
insert(const value_type & v)402   iterator insert(const value_type &v) {
403     int size = this->tree_.size();
404     auto checker_res = this->checker_.insert(v);
405     iterator tree_res = this->tree_.insert(v);
406     CheckPairEquals(*tree_res, *checker_res);
407     EXPECT_EQ(this->tree_.size(), this->checker_.size());
408     EXPECT_EQ(this->tree_.size(), size + 1);
409     return tree_res;
410   }
insert(iterator position,const value_type & v)411   iterator insert(iterator position, const value_type &v) {
412     int size = this->tree_.size();
413     auto checker_res = this->checker_.insert(v);
414     iterator tree_res = this->tree_.insert(position, v);
415     CheckPairEquals(*tree_res, *checker_res);
416     EXPECT_EQ(this->tree_.size(), this->checker_.size());
417     EXPECT_EQ(this->tree_.size(), size + 1);
418     return tree_res;
419   }
420   template <typename InputIterator>
insert(InputIterator b,InputIterator e)421   void insert(InputIterator b, InputIterator e) {
422     for (; b != e; ++b) {
423       insert(*b);
424     }
425   }
426 };
427 
428 template <typename T, typename V>
DoTest(const char * name,T * b,const std::vector<V> & values)429 void DoTest(const char *name, T *b, const std::vector<V> &values) {
430   typename KeyOfValue<typename T::key_type, V>::type key_of_value;
431 
432   T &mutable_b = *b;
433   const T &const_b = *b;
434 
435   // Test insert.
436   for (int i = 0; i < values.size(); ++i) {
437     mutable_b.insert(values[i]);
438     mutable_b.value_check(values[i]);
439   }
440   ASSERT_EQ(mutable_b.size(), values.size());
441 
442   const_b.verify();
443 
444   // Test copy constructor.
445   T b_copy(const_b);
446   EXPECT_EQ(b_copy.size(), const_b.size());
447   for (int i = 0; i < values.size(); ++i) {
448     CheckPairEquals(*b_copy.find(key_of_value(values[i])), values[i]);
449   }
450 
451   // Test range constructor.
452   T b_range(const_b.begin(), const_b.end());
453   EXPECT_EQ(b_range.size(), const_b.size());
454   for (int i = 0; i < values.size(); ++i) {
455     CheckPairEquals(*b_range.find(key_of_value(values[i])), values[i]);
456   }
457 
458   // Test range insertion for values that already exist.
459   b_range.insert(b_copy.begin(), b_copy.end());
460   b_range.verify();
461 
462   // Test range insertion for new values.
463   b_range.clear();
464   b_range.insert(b_copy.begin(), b_copy.end());
465   EXPECT_EQ(b_range.size(), b_copy.size());
466   for (int i = 0; i < values.size(); ++i) {
467     CheckPairEquals(*b_range.find(key_of_value(values[i])), values[i]);
468   }
469 
470   // Test assignment to self. Nothing should change.
471   b_range.operator=(b_range);
472   EXPECT_EQ(b_range.size(), b_copy.size());
473 
474   // Test assignment of new values.
475   b_range.clear();
476   b_range = b_copy;
477   EXPECT_EQ(b_range.size(), b_copy.size());
478 
479   // Test swap.
480   b_range.clear();
481   b_range.swap(b_copy);
482   EXPECT_EQ(b_copy.size(), 0);
483   EXPECT_EQ(b_range.size(), const_b.size());
484   for (int i = 0; i < values.size(); ++i) {
485     CheckPairEquals(*b_range.find(key_of_value(values[i])), values[i]);
486   }
487   b_range.swap(b_copy);
488 
489   // Test non-member function swap.
490   swap(b_range, b_copy);
491   EXPECT_EQ(b_copy.size(), 0);
492   EXPECT_EQ(b_range.size(), const_b.size());
493   for (int i = 0; i < values.size(); ++i) {
494     CheckPairEquals(*b_range.find(key_of_value(values[i])), values[i]);
495   }
496   swap(b_range, b_copy);
497 
498   // Test erase via values.
499   for (int i = 0; i < values.size(); ++i) {
500     mutable_b.erase(key_of_value(values[i]));
501     // Erasing a non-existent key should have no effect.
502     ASSERT_EQ(mutable_b.erase(key_of_value(values[i])), 0);
503   }
504 
505   const_b.verify();
506   EXPECT_EQ(const_b.size(), 0);
507 
508   // Test erase via iterators.
509   mutable_b = b_copy;
510   for (int i = 0; i < values.size(); ++i) {
511     mutable_b.erase(mutable_b.find(key_of_value(values[i])));
512   }
513 
514   const_b.verify();
515   EXPECT_EQ(const_b.size(), 0);
516 
517   // Test insert with hint.
518   for (int i = 0; i < values.size(); i++) {
519     mutable_b.insert(mutable_b.upper_bound(key_of_value(values[i])), values[i]);
520   }
521 
522   const_b.verify();
523 
524   // Test range erase.
525   mutable_b.erase(mutable_b.begin(), mutable_b.end());
526   EXPECT_EQ(mutable_b.size(), 0);
527   const_b.verify();
528 
529   // First half.
530   mutable_b = b_copy;
531   typename T::iterator mutable_iter_end = mutable_b.begin();
532   for (int i = 0; i < values.size() / 2; ++i) ++mutable_iter_end;
533   mutable_b.erase(mutable_b.begin(), mutable_iter_end);
534   EXPECT_EQ(mutable_b.size(), values.size() - values.size() / 2);
535   const_b.verify();
536 
537   // Second half.
538   mutable_b = b_copy;
539   typename T::iterator mutable_iter_begin = mutable_b.begin();
540   for (int i = 0; i < values.size() / 2; ++i) ++mutable_iter_begin;
541   mutable_b.erase(mutable_iter_begin, mutable_b.end());
542   EXPECT_EQ(mutable_b.size(), values.size() / 2);
543   const_b.verify();
544 
545   // Second quarter.
546   mutable_b = b_copy;
547   mutable_iter_begin = mutable_b.begin();
548   for (int i = 0; i < values.size() / 4; ++i) ++mutable_iter_begin;
549   mutable_iter_end = mutable_iter_begin;
550   for (int i = 0; i < values.size() / 4; ++i) ++mutable_iter_end;
551   mutable_b.erase(mutable_iter_begin, mutable_iter_end);
552   EXPECT_EQ(mutable_b.size(), values.size() - values.size() / 4);
553   const_b.verify();
554 
555   mutable_b.clear();
556 }
557 
558 template <typename T>
ConstTest()559 void ConstTest() {
560   using value_type = typename T::value_type;
561   typename KeyOfValue<typename T::key_type, value_type>::type key_of_value;
562 
563   T mutable_b;
564   const T &const_b = mutable_b;
565 
566   // Insert a single value into the container and test looking it up.
567   value_type value = Generator<value_type>(2)(2);
568   mutable_b.insert(value);
569   EXPECT_TRUE(mutable_b.contains(key_of_value(value)));
570   EXPECT_NE(mutable_b.find(key_of_value(value)), const_b.end());
571   EXPECT_TRUE(const_b.contains(key_of_value(value)));
572   EXPECT_NE(const_b.find(key_of_value(value)), mutable_b.end());
573   EXPECT_EQ(*const_b.lower_bound(key_of_value(value)), value);
574   EXPECT_EQ(const_b.upper_bound(key_of_value(value)), const_b.end());
575   EXPECT_EQ(*const_b.equal_range(key_of_value(value)).first, value);
576 
577   // We can only create a non-const iterator from a non-const container.
578   typename T::iterator mutable_iter(mutable_b.begin());
579   EXPECT_EQ(mutable_iter, const_b.begin());
580   EXPECT_NE(mutable_iter, const_b.end());
581   EXPECT_EQ(const_b.begin(), mutable_iter);
582   EXPECT_NE(const_b.end(), mutable_iter);
583   typename T::reverse_iterator mutable_riter(mutable_b.rbegin());
584   EXPECT_EQ(mutable_riter, const_b.rbegin());
585   EXPECT_NE(mutable_riter, const_b.rend());
586   EXPECT_EQ(const_b.rbegin(), mutable_riter);
587   EXPECT_NE(const_b.rend(), mutable_riter);
588 
589   // We can create a const iterator from a non-const iterator.
590   typename T::const_iterator const_iter(mutable_iter);
591   EXPECT_EQ(const_iter, mutable_b.begin());
592   EXPECT_NE(const_iter, mutable_b.end());
593   EXPECT_EQ(mutable_b.begin(), const_iter);
594   EXPECT_NE(mutable_b.end(), const_iter);
595   typename T::const_reverse_iterator const_riter(mutable_riter);
596   EXPECT_EQ(const_riter, mutable_b.rbegin());
597   EXPECT_NE(const_riter, mutable_b.rend());
598   EXPECT_EQ(mutable_b.rbegin(), const_riter);
599   EXPECT_NE(mutable_b.rend(), const_riter);
600 
601   // Make sure various methods can be invoked on a const container.
602   const_b.verify();
603   ASSERT_TRUE(!const_b.empty());
604   EXPECT_EQ(const_b.size(), 1);
605   EXPECT_GT(const_b.max_size(), 0);
606   EXPECT_TRUE(const_b.contains(key_of_value(value)));
607   EXPECT_EQ(const_b.count(key_of_value(value)), 1);
608 }
609 
610 template <typename T, typename C>
BtreeTest()611 void BtreeTest() {
612   ConstTest<T>();
613 
614   using V = typename remove_pair_const<typename T::value_type>::type;
615   const std::vector<V> random_values = GenerateValuesWithSeed<V>(
616       absl::GetFlag(FLAGS_test_values), 4 * absl::GetFlag(FLAGS_test_values),
617       GTEST_FLAG_GET(random_seed));
618 
619   unique_checker<T, C> container;
620 
621   // Test key insertion/deletion in sorted order.
622   std::vector<V> sorted_values(random_values);
623   std::sort(sorted_values.begin(), sorted_values.end());
624   DoTest("sorted:    ", &container, sorted_values);
625 
626   // Test key insertion/deletion in reverse sorted order.
627   std::reverse(sorted_values.begin(), sorted_values.end());
628   DoTest("rsorted:   ", &container, sorted_values);
629 
630   // Test key insertion/deletion in random order.
631   DoTest("random:    ", &container, random_values);
632 }
633 
634 template <typename T, typename C>
BtreeMultiTest()635 void BtreeMultiTest() {
636   ConstTest<T>();
637 
638   using V = typename remove_pair_const<typename T::value_type>::type;
639   const std::vector<V> random_values = GenerateValuesWithSeed<V>(
640       absl::GetFlag(FLAGS_test_values), 4 * absl::GetFlag(FLAGS_test_values),
641       GTEST_FLAG_GET(random_seed));
642 
643   multi_checker<T, C> container;
644 
645   // Test keys in sorted order.
646   std::vector<V> sorted_values(random_values);
647   std::sort(sorted_values.begin(), sorted_values.end());
648   DoTest("sorted:    ", &container, sorted_values);
649 
650   // Test keys in reverse sorted order.
651   std::reverse(sorted_values.begin(), sorted_values.end());
652   DoTest("rsorted:   ", &container, sorted_values);
653 
654   // Test keys in random order.
655   DoTest("random:    ", &container, random_values);
656 
657   // Test keys in random order w/ duplicates.
658   std::vector<V> duplicate_values(random_values);
659   duplicate_values.insert(duplicate_values.end(), random_values.begin(),
660                           random_values.end());
661   DoTest("duplicates:", &container, duplicate_values);
662 
663   // Test all identical keys.
664   std::vector<V> identical_values(100);
665   std::fill(identical_values.begin(), identical_values.end(),
666             Generator<V>(2)(2));
667   DoTest("identical: ", &container, identical_values);
668 }
669 
670 template <typename T>
671 struct PropagatingCountingAlloc : public CountingAllocator<T> {
672   using propagate_on_container_copy_assignment = std::true_type;
673   using propagate_on_container_move_assignment = std::true_type;
674   using propagate_on_container_swap = std::true_type;
675 
676   using Base = CountingAllocator<T>;
677   using Base::Base;
678 
679   template <typename U>
PropagatingCountingAllocabsl::container_internal::__anona1fef86c0311::PropagatingCountingAlloc680   explicit PropagatingCountingAlloc(const PropagatingCountingAlloc<U> &other)
681       : Base(other.bytes_used_) {}
682 
683   template <typename U>
684   struct rebind {
685     using other = PropagatingCountingAlloc<U>;
686   };
687 };
688 
689 template <typename T>
BtreeAllocatorTest()690 void BtreeAllocatorTest() {
691   using value_type = typename T::value_type;
692 
693   int64_t bytes1 = 0, bytes2 = 0;
694   PropagatingCountingAlloc<T> allocator1(&bytes1);
695   PropagatingCountingAlloc<T> allocator2(&bytes2);
696   Generator<value_type> generator(1000);
697 
698   // Test that we allocate properly aligned memory. If we don't, then Layout
699   // will assert fail.
700   auto unused1 = allocator1.allocate(1);
701   auto unused2 = allocator2.allocate(1);
702 
703   // Test copy assignment
704   {
705     T b1(typename T::key_compare(), allocator1);
706     T b2(typename T::key_compare(), allocator2);
707 
708     int64_t original_bytes1 = bytes1;
709     b1.insert(generator(0));
710     EXPECT_GT(bytes1, original_bytes1);
711 
712     // This should propagate the allocator.
713     b1 = b2;
714     EXPECT_EQ(b1.size(), 0);
715     EXPECT_EQ(b2.size(), 0);
716     EXPECT_EQ(bytes1, original_bytes1);
717 
718     for (int i = 1; i < 1000; i++) {
719       b1.insert(generator(i));
720     }
721 
722     // We should have allocated out of allocator2.
723     EXPECT_GT(bytes2, bytes1);
724   }
725 
726   // Test move assignment
727   {
728     T b1(typename T::key_compare(), allocator1);
729     T b2(typename T::key_compare(), allocator2);
730 
731     int64_t original_bytes1 = bytes1;
732     b1.insert(generator(0));
733     EXPECT_GT(bytes1, original_bytes1);
734 
735     // This should propagate the allocator.
736     b1 = std::move(b2);
737     EXPECT_EQ(b1.size(), 0);
738     EXPECT_EQ(bytes1, original_bytes1);
739 
740     for (int i = 1; i < 1000; i++) {
741       b1.insert(generator(i));
742     }
743 
744     // We should have allocated out of allocator2.
745     EXPECT_GT(bytes2, bytes1);
746   }
747 
748   // Test swap
749   {
750     T b1(typename T::key_compare(), allocator1);
751     T b2(typename T::key_compare(), allocator2);
752 
753     int64_t original_bytes1 = bytes1;
754     b1.insert(generator(0));
755     EXPECT_GT(bytes1, original_bytes1);
756 
757     // This should swap the allocators.
758     swap(b1, b2);
759     EXPECT_EQ(b1.size(), 0);
760     EXPECT_EQ(b2.size(), 1);
761     EXPECT_GT(bytes1, original_bytes1);
762 
763     for (int i = 1; i < 1000; i++) {
764       b1.insert(generator(i));
765     }
766 
767     // We should have allocated out of allocator2.
768     EXPECT_GT(bytes2, bytes1);
769   }
770 
771   allocator1.deallocate(unused1, 1);
772   allocator2.deallocate(unused2, 1);
773 }
774 
775 template <typename T>
BtreeMapTest()776 void BtreeMapTest() {
777   using value_type = typename T::value_type;
778   using mapped_type = typename T::mapped_type;
779 
780   mapped_type m = Generator<mapped_type>(0)(0);
781   (void)m;
782 
783   T b;
784 
785   // Verify we can insert using operator[].
786   for (int i = 0; i < 1000; i++) {
787     value_type v = Generator<value_type>(1000)(i);
788     b[v.first] = v.second;
789   }
790   EXPECT_EQ(b.size(), 1000);
791 
792   // Test whether we can use the "->" operator on iterators and
793   // reverse_iterators. This stresses the btree_map_params::pair_pointer
794   // mechanism.
795   EXPECT_EQ(b.begin()->first, Generator<value_type>(1000)(0).first);
796   EXPECT_EQ(b.begin()->second, Generator<value_type>(1000)(0).second);
797   EXPECT_EQ(b.rbegin()->first, Generator<value_type>(1000)(999).first);
798   EXPECT_EQ(b.rbegin()->second, Generator<value_type>(1000)(999).second);
799 }
800 
801 template <typename T>
BtreeMultiMapTest()802 void BtreeMultiMapTest() {
803   using mapped_type = typename T::mapped_type;
804   mapped_type m = Generator<mapped_type>(0)(0);
805   (void)m;
806 }
807 
808 template <typename K, int N = 256>
SetTest()809 void SetTest() {
810   EXPECT_EQ(
811       sizeof(absl::btree_set<K>),
812       2 * sizeof(void *) + sizeof(typename absl::btree_set<K>::size_type));
813   using BtreeSet = absl::btree_set<K>;
814   using CountingBtreeSet =
815       absl::btree_set<K, std::less<K>, PropagatingCountingAlloc<K>>;
816   BtreeTest<BtreeSet, std::set<K>>();
817   BtreeAllocatorTest<CountingBtreeSet>();
818 }
819 
820 template <typename K, int N = 256>
MapTest()821 void MapTest() {
822   EXPECT_EQ(
823       sizeof(absl::btree_map<K, K>),
824       2 * sizeof(void *) + sizeof(typename absl::btree_map<K, K>::size_type));
825   using BtreeMap = absl::btree_map<K, K>;
826   using CountingBtreeMap =
827       absl::btree_map<K, K, std::less<K>,
828                       PropagatingCountingAlloc<std::pair<const K, K>>>;
829   BtreeTest<BtreeMap, std::map<K, K>>();
830   BtreeAllocatorTest<CountingBtreeMap>();
831   BtreeMapTest<BtreeMap>();
832 }
833 
TEST(Btree,set_int32)834 TEST(Btree, set_int32) { SetTest<int32_t>(); }
TEST(Btree,set_int64)835 TEST(Btree, set_int64) { SetTest<int64_t>(); }
TEST(Btree,set_string)836 TEST(Btree, set_string) { SetTest<std::string>(); }
TEST(Btree,set_cord)837 TEST(Btree, set_cord) { SetTest<absl::Cord>(); }
TEST(Btree,set_pair)838 TEST(Btree, set_pair) { SetTest<std::pair<int, int>>(); }
TEST(Btree,map_int32)839 TEST(Btree, map_int32) { MapTest<int32_t>(); }
TEST(Btree,map_int64)840 TEST(Btree, map_int64) { MapTest<int64_t>(); }
TEST(Btree,map_string)841 TEST(Btree, map_string) { MapTest<std::string>(); }
TEST(Btree,map_cord)842 TEST(Btree, map_cord) { MapTest<absl::Cord>(); }
TEST(Btree,map_pair)843 TEST(Btree, map_pair) { MapTest<std::pair<int, int>>(); }
844 
845 template <typename K, int N = 256>
MultiSetTest()846 void MultiSetTest() {
847   EXPECT_EQ(
848       sizeof(absl::btree_multiset<K>),
849       2 * sizeof(void *) + sizeof(typename absl::btree_multiset<K>::size_type));
850   using BtreeMSet = absl::btree_multiset<K>;
851   using CountingBtreeMSet =
852       absl::btree_multiset<K, std::less<K>, PropagatingCountingAlloc<K>>;
853   BtreeMultiTest<BtreeMSet, std::multiset<K>>();
854   BtreeAllocatorTest<CountingBtreeMSet>();
855 }
856 
857 template <typename K, int N = 256>
MultiMapTest()858 void MultiMapTest() {
859   EXPECT_EQ(sizeof(absl::btree_multimap<K, K>),
860             2 * sizeof(void *) +
861                 sizeof(typename absl::btree_multimap<K, K>::size_type));
862   using BtreeMMap = absl::btree_multimap<K, K>;
863   using CountingBtreeMMap =
864       absl::btree_multimap<K, K, std::less<K>,
865                            PropagatingCountingAlloc<std::pair<const K, K>>>;
866   BtreeMultiTest<BtreeMMap, std::multimap<K, K>>();
867   BtreeMultiMapTest<BtreeMMap>();
868   BtreeAllocatorTest<CountingBtreeMMap>();
869 }
870 
TEST(Btree,multiset_int32)871 TEST(Btree, multiset_int32) { MultiSetTest<int32_t>(); }
TEST(Btree,multiset_int64)872 TEST(Btree, multiset_int64) { MultiSetTest<int64_t>(); }
TEST(Btree,multiset_string)873 TEST(Btree, multiset_string) { MultiSetTest<std::string>(); }
TEST(Btree,multiset_cord)874 TEST(Btree, multiset_cord) { MultiSetTest<absl::Cord>(); }
TEST(Btree,multiset_pair)875 TEST(Btree, multiset_pair) { MultiSetTest<std::pair<int, int>>(); }
TEST(Btree,multimap_int32)876 TEST(Btree, multimap_int32) { MultiMapTest<int32_t>(); }
TEST(Btree,multimap_int64)877 TEST(Btree, multimap_int64) { MultiMapTest<int64_t>(); }
TEST(Btree,multimap_string)878 TEST(Btree, multimap_string) { MultiMapTest<std::string>(); }
TEST(Btree,multimap_cord)879 TEST(Btree, multimap_cord) { MultiMapTest<absl::Cord>(); }
TEST(Btree,multimap_pair)880 TEST(Btree, multimap_pair) { MultiMapTest<std::pair<int, int>>(); }
881 
882 struct CompareIntToString {
operator ()absl::container_internal::__anona1fef86c0311::CompareIntToString883   bool operator()(const std::string &a, const std::string &b) const {
884     return a < b;
885   }
operator ()absl::container_internal::__anona1fef86c0311::CompareIntToString886   bool operator()(const std::string &a, int b) const {
887     return a < absl::StrCat(b);
888   }
operator ()absl::container_internal::__anona1fef86c0311::CompareIntToString889   bool operator()(int a, const std::string &b) const {
890     return absl::StrCat(a) < b;
891   }
892   using is_transparent = void;
893 };
894 
895 struct NonTransparentCompare {
896   template <typename T, typename U>
operator ()absl::container_internal::__anona1fef86c0311::NonTransparentCompare897   bool operator()(const T &t, const U &u) const {
898     // Treating all comparators as transparent can cause inefficiencies (see
899     // N3657 C++ proposal). Test that for comparators without 'is_transparent'
900     // alias (like this one), we do not attempt heterogeneous lookup.
901     EXPECT_TRUE((std::is_same<T, U>()));
902     return t < u;
903   }
904 };
905 
906 template <typename T>
907 bool CanEraseWithEmptyBrace(T t, decltype(t.erase({})) *) {
908   return true;
909 }
910 
911 template <typename T>
CanEraseWithEmptyBrace(T,...)912 bool CanEraseWithEmptyBrace(T, ...) {
913   return false;
914 }
915 
916 template <typename T>
TestHeterogeneous(T table)917 void TestHeterogeneous(T table) {
918   auto lb = table.lower_bound("3");
919   EXPECT_EQ(lb, table.lower_bound(3));
920   EXPECT_NE(lb, table.lower_bound(4));
921   EXPECT_EQ(lb, table.lower_bound({"3"}));
922   EXPECT_NE(lb, table.lower_bound({}));
923 
924   auto ub = table.upper_bound("3");
925   EXPECT_EQ(ub, table.upper_bound(3));
926   EXPECT_NE(ub, table.upper_bound(5));
927   EXPECT_EQ(ub, table.upper_bound({"3"}));
928   EXPECT_NE(ub, table.upper_bound({}));
929 
930   auto er = table.equal_range("3");
931   EXPECT_EQ(er, table.equal_range(3));
932   EXPECT_NE(er, table.equal_range(4));
933   EXPECT_EQ(er, table.equal_range({"3"}));
934   EXPECT_NE(er, table.equal_range({}));
935 
936   auto it = table.find("3");
937   EXPECT_EQ(it, table.find(3));
938   EXPECT_NE(it, table.find(4));
939   EXPECT_EQ(it, table.find({"3"}));
940   EXPECT_NE(it, table.find({}));
941 
942   EXPECT_TRUE(table.contains(3));
943   EXPECT_FALSE(table.contains(4));
944   EXPECT_TRUE(table.count({"3"}));
945   EXPECT_FALSE(table.contains({}));
946 
947   EXPECT_EQ(1, table.count(3));
948   EXPECT_EQ(0, table.count(4));
949   EXPECT_EQ(1, table.count({"3"}));
950   EXPECT_EQ(0, table.count({}));
951 
952   auto copy = table;
953   copy.erase(3);
954   EXPECT_EQ(table.size() - 1, copy.size());
955   copy.erase(4);
956   EXPECT_EQ(table.size() - 1, copy.size());
957   copy.erase({"5"});
958   EXPECT_EQ(table.size() - 2, copy.size());
959   EXPECT_FALSE(CanEraseWithEmptyBrace(table, nullptr));
960 
961   // Also run it with const T&.
962   if (std::is_class<T>()) TestHeterogeneous<const T &>(table);
963 }
964 
TEST(Btree,HeterogeneousLookup)965 TEST(Btree, HeterogeneousLookup) {
966   TestHeterogeneous(btree_set<std::string, CompareIntToString>{"1", "3", "5"});
967   TestHeterogeneous(btree_map<std::string, int, CompareIntToString>{
968       {"1", 1}, {"3", 3}, {"5", 5}});
969   TestHeterogeneous(
970       btree_multiset<std::string, CompareIntToString>{"1", "3", "5"});
971   TestHeterogeneous(btree_multimap<std::string, int, CompareIntToString>{
972       {"1", 1}, {"3", 3}, {"5", 5}});
973 
974   // Only maps have .at()
975   btree_map<std::string, int, CompareIntToString> map{
976       {"", -1}, {"1", 1}, {"3", 3}, {"5", 5}};
977   EXPECT_EQ(1, map.at(1));
978   EXPECT_EQ(3, map.at({"3"}));
979   EXPECT_EQ(-1, map.at({}));
980   const auto &cmap = map;
981   EXPECT_EQ(1, cmap.at(1));
982   EXPECT_EQ(3, cmap.at({"3"}));
983   EXPECT_EQ(-1, cmap.at({}));
984 }
985 
TEST(Btree,NoHeterogeneousLookupWithoutAlias)986 TEST(Btree, NoHeterogeneousLookupWithoutAlias) {
987   using StringSet = absl::btree_set<std::string, NonTransparentCompare>;
988   StringSet s;
989   ASSERT_TRUE(s.insert("hello").second);
990   ASSERT_TRUE(s.insert("world").second);
991   EXPECT_TRUE(s.end() == s.find("blah"));
992   EXPECT_TRUE(s.begin() == s.lower_bound("hello"));
993   EXPECT_EQ(1, s.count("world"));
994   EXPECT_TRUE(s.contains("hello"));
995   EXPECT_TRUE(s.contains("world"));
996   EXPECT_FALSE(s.contains("blah"));
997 
998   using StringMultiSet =
999       absl::btree_multiset<std::string, NonTransparentCompare>;
1000   StringMultiSet ms;
1001   ms.insert("hello");
1002   ms.insert("world");
1003   ms.insert("world");
1004   EXPECT_TRUE(ms.end() == ms.find("blah"));
1005   EXPECT_TRUE(ms.begin() == ms.lower_bound("hello"));
1006   EXPECT_EQ(2, ms.count("world"));
1007   EXPECT_TRUE(ms.contains("hello"));
1008   EXPECT_TRUE(ms.contains("world"));
1009   EXPECT_FALSE(ms.contains("blah"));
1010 }
1011 
TEST(Btree,DefaultTransparent)1012 TEST(Btree, DefaultTransparent) {
1013   {
1014     // `int` does not have a default transparent comparator.
1015     // The input value is converted to key_type.
1016     btree_set<int> s = {1};
1017     double d = 1.1;
1018     EXPECT_EQ(s.begin(), s.find(d));
1019     EXPECT_TRUE(s.contains(d));
1020   }
1021 
1022   {
1023     // `std::string` has heterogeneous support.
1024     btree_set<std::string> s = {"A"};
1025     EXPECT_EQ(s.begin(), s.find(absl::string_view("A")));
1026     EXPECT_TRUE(s.contains(absl::string_view("A")));
1027   }
1028 }
1029 
1030 class StringLike {
1031  public:
1032   StringLike() = default;
1033 
StringLike(const char * s)1034   StringLike(const char *s) : s_(s) {  // NOLINT
1035     ++constructor_calls_;
1036   }
1037 
operator <(const StringLike & a) const1038   bool operator<(const StringLike &a) const { return s_ < a.s_; }
1039 
clear_constructor_call_count()1040   static void clear_constructor_call_count() { constructor_calls_ = 0; }
1041 
constructor_calls()1042   static int constructor_calls() { return constructor_calls_; }
1043 
1044  private:
1045   static int constructor_calls_;
1046   std::string s_;
1047 };
1048 
1049 int StringLike::constructor_calls_ = 0;
1050 
TEST(Btree,HeterogeneousLookupDoesntDegradePerformance)1051 TEST(Btree, HeterogeneousLookupDoesntDegradePerformance) {
1052   using StringSet = absl::btree_set<StringLike>;
1053   StringSet s;
1054   for (int i = 0; i < 100; ++i) {
1055     ASSERT_TRUE(s.insert(absl::StrCat(i).c_str()).second);
1056   }
1057   StringLike::clear_constructor_call_count();
1058   s.find("50");
1059   ASSERT_EQ(1, StringLike::constructor_calls());
1060 
1061   StringLike::clear_constructor_call_count();
1062   s.contains("50");
1063   ASSERT_EQ(1, StringLike::constructor_calls());
1064 
1065   StringLike::clear_constructor_call_count();
1066   s.count("50");
1067   ASSERT_EQ(1, StringLike::constructor_calls());
1068 
1069   StringLike::clear_constructor_call_count();
1070   s.lower_bound("50");
1071   ASSERT_EQ(1, StringLike::constructor_calls());
1072 
1073   StringLike::clear_constructor_call_count();
1074   s.upper_bound("50");
1075   ASSERT_EQ(1, StringLike::constructor_calls());
1076 
1077   StringLike::clear_constructor_call_count();
1078   s.equal_range("50");
1079   ASSERT_EQ(1, StringLike::constructor_calls());
1080 
1081   StringLike::clear_constructor_call_count();
1082   s.erase("50");
1083   ASSERT_EQ(1, StringLike::constructor_calls());
1084 }
1085 
1086 // Verify that swapping btrees swaps the key comparison functors and that we can
1087 // use non-default constructible comparators.
1088 struct SubstringLess {
1089   SubstringLess() = delete;
SubstringLessabsl::container_internal::__anona1fef86c0311::SubstringLess1090   explicit SubstringLess(int length) : n(length) {}
operator ()absl::container_internal::__anona1fef86c0311::SubstringLess1091   bool operator()(const std::string &a, const std::string &b) const {
1092     return absl::string_view(a).substr(0, n) <
1093            absl::string_view(b).substr(0, n);
1094   }
1095   int n;
1096 };
1097 
TEST(Btree,SwapKeyCompare)1098 TEST(Btree, SwapKeyCompare) {
1099   using SubstringSet = absl::btree_set<std::string, SubstringLess>;
1100   SubstringSet s1(SubstringLess(1), SubstringSet::allocator_type());
1101   SubstringSet s2(SubstringLess(2), SubstringSet::allocator_type());
1102 
1103   ASSERT_TRUE(s1.insert("a").second);
1104   ASSERT_FALSE(s1.insert("aa").second);
1105 
1106   ASSERT_TRUE(s2.insert("a").second);
1107   ASSERT_TRUE(s2.insert("aa").second);
1108   ASSERT_FALSE(s2.insert("aaa").second);
1109 
1110   swap(s1, s2);
1111 
1112   ASSERT_TRUE(s1.insert("b").second);
1113   ASSERT_TRUE(s1.insert("bb").second);
1114   ASSERT_FALSE(s1.insert("bbb").second);
1115 
1116   ASSERT_TRUE(s2.insert("b").second);
1117   ASSERT_FALSE(s2.insert("bb").second);
1118 }
1119 
TEST(Btree,UpperBoundRegression)1120 TEST(Btree, UpperBoundRegression) {
1121   // Regress a bug where upper_bound would default-construct a new key_compare
1122   // instead of copying the existing one.
1123   using SubstringSet = absl::btree_set<std::string, SubstringLess>;
1124   SubstringSet my_set(SubstringLess(3));
1125   my_set.insert("aab");
1126   my_set.insert("abb");
1127   // We call upper_bound("aaa").  If this correctly uses the length 3
1128   // comparator, aaa < aab < abb, so we should get aab as the result.
1129   // If it instead uses the default-constructed length 2 comparator,
1130   // aa == aa < ab, so we'll get abb as our result.
1131   SubstringSet::iterator it = my_set.upper_bound("aaa");
1132   ASSERT_TRUE(it != my_set.end());
1133   EXPECT_EQ("aab", *it);
1134 }
1135 
TEST(Btree,Comparison)1136 TEST(Btree, Comparison) {
1137   const int kSetSize = 1201;
1138   absl::btree_set<int64_t> my_set;
1139   for (int i = 0; i < kSetSize; ++i) {
1140     my_set.insert(i);
1141   }
1142   absl::btree_set<int64_t> my_set_copy(my_set);
1143   EXPECT_TRUE(my_set_copy == my_set);
1144   EXPECT_TRUE(my_set == my_set_copy);
1145   EXPECT_FALSE(my_set_copy != my_set);
1146   EXPECT_FALSE(my_set != my_set_copy);
1147 
1148   my_set.insert(kSetSize);
1149   EXPECT_FALSE(my_set_copy == my_set);
1150   EXPECT_FALSE(my_set == my_set_copy);
1151   EXPECT_TRUE(my_set_copy != my_set);
1152   EXPECT_TRUE(my_set != my_set_copy);
1153 
1154   my_set.erase(kSetSize - 1);
1155   EXPECT_FALSE(my_set_copy == my_set);
1156   EXPECT_FALSE(my_set == my_set_copy);
1157   EXPECT_TRUE(my_set_copy != my_set);
1158   EXPECT_TRUE(my_set != my_set_copy);
1159 
1160   absl::btree_map<std::string, int64_t> my_map;
1161   for (int i = 0; i < kSetSize; ++i) {
1162     my_map[std::string(i, 'a')] = i;
1163   }
1164   absl::btree_map<std::string, int64_t> my_map_copy(my_map);
1165   EXPECT_TRUE(my_map_copy == my_map);
1166   EXPECT_TRUE(my_map == my_map_copy);
1167   EXPECT_FALSE(my_map_copy != my_map);
1168   EXPECT_FALSE(my_map != my_map_copy);
1169 
1170   ++my_map_copy[std::string(7, 'a')];
1171   EXPECT_FALSE(my_map_copy == my_map);
1172   EXPECT_FALSE(my_map == my_map_copy);
1173   EXPECT_TRUE(my_map_copy != my_map);
1174   EXPECT_TRUE(my_map != my_map_copy);
1175 
1176   my_map_copy = my_map;
1177   my_map["hello"] = kSetSize;
1178   EXPECT_FALSE(my_map_copy == my_map);
1179   EXPECT_FALSE(my_map == my_map_copy);
1180   EXPECT_TRUE(my_map_copy != my_map);
1181   EXPECT_TRUE(my_map != my_map_copy);
1182 
1183   my_map.erase(std::string(kSetSize - 1, 'a'));
1184   EXPECT_FALSE(my_map_copy == my_map);
1185   EXPECT_FALSE(my_map == my_map_copy);
1186   EXPECT_TRUE(my_map_copy != my_map);
1187   EXPECT_TRUE(my_map != my_map_copy);
1188 }
1189 
TEST(Btree,RangeCtorSanity)1190 TEST(Btree, RangeCtorSanity) {
1191   std::vector<int> ivec;
1192   ivec.push_back(1);
1193   std::map<int, int> imap;
1194   imap.insert(std::make_pair(1, 2));
1195   absl::btree_multiset<int> tmset(ivec.begin(), ivec.end());
1196   absl::btree_multimap<int, int> tmmap(imap.begin(), imap.end());
1197   absl::btree_set<int> tset(ivec.begin(), ivec.end());
1198   absl::btree_map<int, int> tmap(imap.begin(), imap.end());
1199   EXPECT_EQ(1, tmset.size());
1200   EXPECT_EQ(1, tmmap.size());
1201   EXPECT_EQ(1, tset.size());
1202   EXPECT_EQ(1, tmap.size());
1203 }
1204 
1205 }  // namespace
1206 
1207 class BtreeNodePeer {
1208  public:
1209   // Yields the size of a leaf node with a specific number of values.
1210   template <typename ValueType>
GetTargetNodeSize(size_t target_values_per_node)1211   constexpr static size_t GetTargetNodeSize(size_t target_values_per_node) {
1212     return btree_node<
1213         set_params<ValueType, std::less<ValueType>, std::allocator<ValueType>,
1214                    /*TargetNodeSize=*/256,  // This parameter isn't used here.
1215                    /*Multi=*/false>>::SizeWithNSlots(target_values_per_node);
1216   }
1217 
1218   // Yields the number of slots in a (non-root) leaf node for this btree.
1219   template <typename Btree>
GetNumSlotsPerNode()1220   constexpr static size_t GetNumSlotsPerNode() {
1221     return btree_node<typename Btree::params_type>::kNodeSlots;
1222   }
1223 
1224   template <typename Btree>
GetMaxFieldType()1225   constexpr static size_t GetMaxFieldType() {
1226     return std::numeric_limits<
1227         typename btree_node<typename Btree::params_type>::field_type>::max();
1228   }
1229 
1230   template <typename Btree>
UsesLinearNodeSearch()1231   constexpr static bool UsesLinearNodeSearch() {
1232     return btree_node<typename Btree::params_type>::use_linear_search::value;
1233   }
1234 
1235   template <typename Btree>
FieldTypeEqualsSlotType()1236   constexpr static bool FieldTypeEqualsSlotType() {
1237     return std::is_same<
1238         typename btree_node<typename Btree::params_type>::field_type,
1239         typename btree_node<typename Btree::params_type>::slot_type>::value;
1240   }
1241 };
1242 
1243 namespace {
1244 
1245 class BtreeMapTest : public ::testing::Test {
1246  public:
1247   struct Key {};
1248   struct Cmp {
1249     template <typename T>
operator ()absl::container_internal::__anona1fef86c0411::BtreeMapTest::Cmp1250     bool operator()(T, T) const {
1251       return false;
1252     }
1253   };
1254 
1255   struct KeyLin {
1256     using absl_btree_prefer_linear_node_search = std::true_type;
1257   };
1258   struct CmpLin : Cmp {
1259     using absl_btree_prefer_linear_node_search = std::true_type;
1260   };
1261 
1262   struct KeyBin {
1263     using absl_btree_prefer_linear_node_search = std::false_type;
1264   };
1265   struct CmpBin : Cmp {
1266     using absl_btree_prefer_linear_node_search = std::false_type;
1267   };
1268 
1269   template <typename K, typename C>
IsLinear()1270   static bool IsLinear() {
1271     return BtreeNodePeer::UsesLinearNodeSearch<absl::btree_map<K, int, C>>();
1272   }
1273 };
1274 
TEST_F(BtreeMapTest,TestLinearSearchPreferredForKeyLinearViaAlias)1275 TEST_F(BtreeMapTest, TestLinearSearchPreferredForKeyLinearViaAlias) {
1276   // Test requesting linear search by directly exporting an alias.
1277   EXPECT_FALSE((IsLinear<Key, Cmp>()));
1278   EXPECT_TRUE((IsLinear<KeyLin, Cmp>()));
1279   EXPECT_TRUE((IsLinear<Key, CmpLin>()));
1280   EXPECT_TRUE((IsLinear<KeyLin, CmpLin>()));
1281 }
1282 
TEST_F(BtreeMapTest,LinearChoiceTree)1283 TEST_F(BtreeMapTest, LinearChoiceTree) {
1284   // Cmp has precedence, and is forcing binary
1285   EXPECT_FALSE((IsLinear<Key, CmpBin>()));
1286   EXPECT_FALSE((IsLinear<KeyLin, CmpBin>()));
1287   EXPECT_FALSE((IsLinear<KeyBin, CmpBin>()));
1288   EXPECT_FALSE((IsLinear<int, CmpBin>()));
1289   EXPECT_FALSE((IsLinear<std::string, CmpBin>()));
1290   // Cmp has precedence, and is forcing linear
1291   EXPECT_TRUE((IsLinear<Key, CmpLin>()));
1292   EXPECT_TRUE((IsLinear<KeyLin, CmpLin>()));
1293   EXPECT_TRUE((IsLinear<KeyBin, CmpLin>()));
1294   EXPECT_TRUE((IsLinear<int, CmpLin>()));
1295   EXPECT_TRUE((IsLinear<std::string, CmpLin>()));
1296   // Cmp has no preference, Key determines linear vs binary.
1297   EXPECT_FALSE((IsLinear<Key, Cmp>()));
1298   EXPECT_TRUE((IsLinear<KeyLin, Cmp>()));
1299   EXPECT_FALSE((IsLinear<KeyBin, Cmp>()));
1300   // arithmetic key w/ std::less or std::greater: linear
1301   EXPECT_TRUE((IsLinear<int, std::less<int>>()));
1302   EXPECT_TRUE((IsLinear<double, std::greater<double>>()));
1303   // arithmetic key w/ custom compare: binary
1304   EXPECT_FALSE((IsLinear<int, Cmp>()));
1305   // non-arithmetic key: binary
1306   EXPECT_FALSE((IsLinear<std::string, std::less<std::string>>()));
1307 }
1308 
TEST(Btree,BtreeMapCanHoldMoveOnlyTypes)1309 TEST(Btree, BtreeMapCanHoldMoveOnlyTypes) {
1310   absl::btree_map<std::string, std::unique_ptr<std::string>> m;
1311 
1312   std::unique_ptr<std::string> &v = m["A"];
1313   EXPECT_TRUE(v == nullptr);
1314   v = absl::make_unique<std::string>("X");
1315 
1316   auto iter = m.find("A");
1317   EXPECT_EQ("X", *iter->second);
1318 }
1319 
TEST(Btree,InitializerListConstructor)1320 TEST(Btree, InitializerListConstructor) {
1321   absl::btree_set<std::string> set({"a", "b"});
1322   EXPECT_EQ(set.count("a"), 1);
1323   EXPECT_EQ(set.count("b"), 1);
1324 
1325   absl::btree_multiset<int> mset({1, 1, 4});
1326   EXPECT_EQ(mset.count(1), 2);
1327   EXPECT_EQ(mset.count(4), 1);
1328 
1329   absl::btree_map<int, int> map({{1, 5}, {2, 10}});
1330   EXPECT_EQ(map[1], 5);
1331   EXPECT_EQ(map[2], 10);
1332 
1333   absl::btree_multimap<int, int> mmap({{1, 5}, {1, 10}});
1334   auto range = mmap.equal_range(1);
1335   auto it = range.first;
1336   ASSERT_NE(it, range.second);
1337   EXPECT_EQ(it->second, 5);
1338   ASSERT_NE(++it, range.second);
1339   EXPECT_EQ(it->second, 10);
1340   EXPECT_EQ(++it, range.second);
1341 }
1342 
TEST(Btree,InitializerListInsert)1343 TEST(Btree, InitializerListInsert) {
1344   absl::btree_set<std::string> set;
1345   set.insert({"a", "b"});
1346   EXPECT_EQ(set.count("a"), 1);
1347   EXPECT_EQ(set.count("b"), 1);
1348 
1349   absl::btree_multiset<int> mset;
1350   mset.insert({1, 1, 4});
1351   EXPECT_EQ(mset.count(1), 2);
1352   EXPECT_EQ(mset.count(4), 1);
1353 
1354   absl::btree_map<int, int> map;
1355   map.insert({{1, 5}, {2, 10}});
1356   // Test that inserting one element using an initializer list also works.
1357   map.insert({3, 15});
1358   EXPECT_EQ(map[1], 5);
1359   EXPECT_EQ(map[2], 10);
1360   EXPECT_EQ(map[3], 15);
1361 
1362   absl::btree_multimap<int, int> mmap;
1363   mmap.insert({{1, 5}, {1, 10}});
1364   auto range = mmap.equal_range(1);
1365   auto it = range.first;
1366   ASSERT_NE(it, range.second);
1367   EXPECT_EQ(it->second, 5);
1368   ASSERT_NE(++it, range.second);
1369   EXPECT_EQ(it->second, 10);
1370   EXPECT_EQ(++it, range.second);
1371 }
1372 
1373 template <typename Compare, typename Key>
AssertKeyCompareStringAdapted()1374 void AssertKeyCompareStringAdapted() {
1375   using Adapted = typename key_compare_adapter<Compare, Key>::type;
1376   static_assert(
1377       std::is_same<Adapted, StringBtreeDefaultLess>::value ||
1378           std::is_same<Adapted, StringBtreeDefaultGreater>::value,
1379       "key_compare_adapter should have string-adapted this comparator.");
1380 }
1381 template <typename Compare, typename Key>
AssertKeyCompareNotStringAdapted()1382 void AssertKeyCompareNotStringAdapted() {
1383   using Adapted = typename key_compare_adapter<Compare, Key>::type;
1384   static_assert(
1385       !std::is_same<Adapted, StringBtreeDefaultLess>::value &&
1386           !std::is_same<Adapted, StringBtreeDefaultGreater>::value,
1387       "key_compare_adapter shouldn't have string-adapted this comparator.");
1388 }
1389 
TEST(Btree,KeyCompareAdapter)1390 TEST(Btree, KeyCompareAdapter) {
1391   AssertKeyCompareStringAdapted<std::less<std::string>, std::string>();
1392   AssertKeyCompareStringAdapted<std::greater<std::string>, std::string>();
1393   AssertKeyCompareStringAdapted<std::less<absl::string_view>,
1394                                 absl::string_view>();
1395   AssertKeyCompareStringAdapted<std::greater<absl::string_view>,
1396                                 absl::string_view>();
1397   AssertKeyCompareStringAdapted<std::less<absl::Cord>, absl::Cord>();
1398   AssertKeyCompareStringAdapted<std::greater<absl::Cord>, absl::Cord>();
1399   AssertKeyCompareNotStringAdapted<std::less<int>, int>();
1400   AssertKeyCompareNotStringAdapted<std::greater<int>, int>();
1401 }
1402 
TEST(Btree,RValueInsert)1403 TEST(Btree, RValueInsert) {
1404   InstanceTracker tracker;
1405 
1406   absl::btree_set<MovableOnlyInstance> set;
1407   set.insert(MovableOnlyInstance(1));
1408   set.insert(MovableOnlyInstance(3));
1409   MovableOnlyInstance two(2);
1410   set.insert(set.find(MovableOnlyInstance(3)), std::move(two));
1411   auto it = set.find(MovableOnlyInstance(2));
1412   ASSERT_NE(it, set.end());
1413   ASSERT_NE(++it, set.end());
1414   EXPECT_EQ(it->value(), 3);
1415 
1416   absl::btree_multiset<MovableOnlyInstance> mset;
1417   MovableOnlyInstance zero(0);
1418   MovableOnlyInstance zero2(0);
1419   mset.insert(std::move(zero));
1420   mset.insert(mset.find(MovableOnlyInstance(0)), std::move(zero2));
1421   EXPECT_EQ(mset.count(MovableOnlyInstance(0)), 2);
1422 
1423   absl::btree_map<int, MovableOnlyInstance> map;
1424   std::pair<const int, MovableOnlyInstance> p1 = {1, MovableOnlyInstance(5)};
1425   std::pair<const int, MovableOnlyInstance> p2 = {2, MovableOnlyInstance(10)};
1426   std::pair<const int, MovableOnlyInstance> p3 = {3, MovableOnlyInstance(15)};
1427   map.insert(std::move(p1));
1428   map.insert(std::move(p3));
1429   map.insert(map.find(3), std::move(p2));
1430   ASSERT_NE(map.find(2), map.end());
1431   EXPECT_EQ(map.find(2)->second.value(), 10);
1432 
1433   absl::btree_multimap<int, MovableOnlyInstance> mmap;
1434   std::pair<const int, MovableOnlyInstance> p4 = {1, MovableOnlyInstance(5)};
1435   std::pair<const int, MovableOnlyInstance> p5 = {1, MovableOnlyInstance(10)};
1436   mmap.insert(std::move(p4));
1437   mmap.insert(mmap.find(1), std::move(p5));
1438   auto range = mmap.equal_range(1);
1439   auto it1 = range.first;
1440   ASSERT_NE(it1, range.second);
1441   EXPECT_EQ(it1->second.value(), 10);
1442   ASSERT_NE(++it1, range.second);
1443   EXPECT_EQ(it1->second.value(), 5);
1444   EXPECT_EQ(++it1, range.second);
1445 
1446   EXPECT_EQ(tracker.copies(), 0);
1447   EXPECT_EQ(tracker.swaps(), 0);
1448 }
1449 
1450 template <typename Cmp>
1451 struct CheckedCompareOptedOutCmp : Cmp, BtreeTestOnlyCheckedCompareOptOutBase {
1452   using Cmp::Cmp;
CheckedCompareOptedOutCmpabsl::container_internal::__anona1fef86c0411::CheckedCompareOptedOutCmp1453   CheckedCompareOptedOutCmp() {}
CheckedCompareOptedOutCmpabsl::container_internal::__anona1fef86c0411::CheckedCompareOptedOutCmp1454   CheckedCompareOptedOutCmp(Cmp cmp) : Cmp(std::move(cmp)) {}  // NOLINT
1455 };
1456 
1457 // A btree set with a specific number of values per node. Opt out of
1458 // checked_compare so that we can expect exact numbers of comparisons.
1459 template <typename Key, int TargetValuesPerNode, typename Cmp = std::less<Key>>
1460 class SizedBtreeSet
1461     : public btree_set_container<btree<
1462           set_params<Key, CheckedCompareOptedOutCmp<Cmp>, std::allocator<Key>,
1463                      BtreeNodePeer::GetTargetNodeSize<Key>(TargetValuesPerNode),
1464                      /*Multi=*/false>>> {
1465   using Base = typename SizedBtreeSet::btree_set_container;
1466 
1467  public:
1468   SizedBtreeSet() = default;
1469   using Base::Base;
1470 };
1471 
1472 template <typename Set>
ExpectOperationCounts(const int expected_moves,const int expected_comparisons,const std::vector<int> & values,InstanceTracker * tracker,Set * set)1473 void ExpectOperationCounts(const int expected_moves,
1474                            const int expected_comparisons,
1475                            const std::vector<int> &values,
1476                            InstanceTracker *tracker, Set *set) {
1477   for (const int v : values) set->insert(MovableOnlyInstance(v));
1478   set->clear();
1479   EXPECT_EQ(tracker->moves(), expected_moves);
1480   EXPECT_EQ(tracker->comparisons(), expected_comparisons);
1481   EXPECT_EQ(tracker->copies(), 0);
1482   EXPECT_EQ(tracker->swaps(), 0);
1483   tracker->ResetCopiesMovesSwaps();
1484 }
1485 
1486 #ifdef ABSL_HAVE_ADDRESS_SANITIZER
1487 constexpr bool kAsan = true;
1488 #else
1489 constexpr bool kAsan = false;
1490 #endif
1491 
1492 // Note: when the values in this test change, it is expected to have an impact
1493 // on performance.
TEST(Btree,MovesComparisonsCopiesSwapsTracking)1494 TEST(Btree, MovesComparisonsCopiesSwapsTracking) {
1495   if (kAsan) GTEST_SKIP() << "We do extra operations in ASan mode.";
1496 
1497   InstanceTracker tracker;
1498   // Note: this is minimum number of values per node.
1499   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/4> set4;
1500   // Note: this is the default number of values per node for a set of int32s
1501   // (with 64-bit pointers).
1502   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/61> set61;
1503   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/100> set100;
1504 
1505   // Don't depend on flags for random values because then the expectations will
1506   // fail if the flags change.
1507   std::vector<int> values =
1508       GenerateValuesWithSeed<int>(10000, 1 << 22, /*seed=*/23);
1509 
1510   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set4)>(), 4);
1511   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set61)>(), 61);
1512   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set100)>(), 100);
1513   if (sizeof(void *) == 8) {
1514     EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t>>(),
1515               // When we have generations, there is one fewer slot.
1516               BtreeGenerationsEnabled() ? 60 : 61);
1517   }
1518 
1519   // Test key insertion/deletion in random order.
1520   ExpectOperationCounts(56540, 134212, values, &tracker, &set4);
1521   ExpectOperationCounts(386718, 129807, values, &tracker, &set61);
1522   ExpectOperationCounts(586761, 130310, values, &tracker, &set100);
1523 
1524   // Test key insertion/deletion in sorted order.
1525   std::sort(values.begin(), values.end());
1526   ExpectOperationCounts(24972, 85563, values, &tracker, &set4);
1527   ExpectOperationCounts(20208, 87757, values, &tracker, &set61);
1528   ExpectOperationCounts(20124, 96583, values, &tracker, &set100);
1529 
1530   // Test key insertion/deletion in reverse sorted order.
1531   std::reverse(values.begin(), values.end());
1532   ExpectOperationCounts(54949, 127531, values, &tracker, &set4);
1533   ExpectOperationCounts(338813, 118266, values, &tracker, &set61);
1534   ExpectOperationCounts(534529, 125279, values, &tracker, &set100);
1535 }
1536 
1537 struct MovableOnlyInstanceThreeWayCompare {
operator ()absl::container_internal::__anona1fef86c0411::MovableOnlyInstanceThreeWayCompare1538   absl::weak_ordering operator()(const MovableOnlyInstance &a,
1539                                  const MovableOnlyInstance &b) const {
1540     return a.compare(b);
1541   }
1542 };
1543 
1544 // Note: when the values in this test change, it is expected to have an impact
1545 // on performance.
TEST(Btree,MovesComparisonsCopiesSwapsTrackingThreeWayCompare)1546 TEST(Btree, MovesComparisonsCopiesSwapsTrackingThreeWayCompare) {
1547   if (kAsan) GTEST_SKIP() << "We do extra operations in ASan mode.";
1548 
1549   InstanceTracker tracker;
1550   // Note: this is minimum number of values per node.
1551   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/4,
1552                 MovableOnlyInstanceThreeWayCompare>
1553       set4;
1554   // Note: this is the default number of values per node for a set of int32s
1555   // (with 64-bit pointers).
1556   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/61,
1557                 MovableOnlyInstanceThreeWayCompare>
1558       set61;
1559   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/100,
1560                 MovableOnlyInstanceThreeWayCompare>
1561       set100;
1562 
1563   // Don't depend on flags for random values because then the expectations will
1564   // fail if the flags change.
1565   std::vector<int> values =
1566       GenerateValuesWithSeed<int>(10000, 1 << 22, /*seed=*/23);
1567 
1568   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set4)>(), 4);
1569   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set61)>(), 61);
1570   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set100)>(), 100);
1571   if (sizeof(void *) == 8) {
1572     EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t>>(),
1573               // When we have generations, there is one fewer slot.
1574               BtreeGenerationsEnabled() ? 60 : 61);
1575   }
1576 
1577   // Test key insertion/deletion in random order.
1578   ExpectOperationCounts(56540, 124221, values, &tracker, &set4);
1579   ExpectOperationCounts(386718, 119816, values, &tracker, &set61);
1580   ExpectOperationCounts(586761, 120319, values, &tracker, &set100);
1581 
1582   // Test key insertion/deletion in sorted order.
1583   std::sort(values.begin(), values.end());
1584   ExpectOperationCounts(24972, 85563, values, &tracker, &set4);
1585   ExpectOperationCounts(20208, 87757, values, &tracker, &set61);
1586   ExpectOperationCounts(20124, 96583, values, &tracker, &set100);
1587 
1588   // Test key insertion/deletion in reverse sorted order.
1589   std::reverse(values.begin(), values.end());
1590   ExpectOperationCounts(54949, 117532, values, &tracker, &set4);
1591   ExpectOperationCounts(338813, 108267, values, &tracker, &set61);
1592   ExpectOperationCounts(534529, 115280, values, &tracker, &set100);
1593 }
1594 
1595 struct NoDefaultCtor {
1596   int num;
NoDefaultCtorabsl::container_internal::__anona1fef86c0411::NoDefaultCtor1597   explicit NoDefaultCtor(int i) : num(i) {}
1598 
operator <(const NoDefaultCtor & a,const NoDefaultCtor & b)1599   friend bool operator<(const NoDefaultCtor &a, const NoDefaultCtor &b) {
1600     return a.num < b.num;
1601   }
1602 };
1603 
TEST(Btree,BtreeMapCanHoldNoDefaultCtorTypes)1604 TEST(Btree, BtreeMapCanHoldNoDefaultCtorTypes) {
1605   absl::btree_map<NoDefaultCtor, NoDefaultCtor> m;
1606 
1607   for (int i = 1; i <= 99; ++i) {
1608     SCOPED_TRACE(i);
1609     EXPECT_TRUE(m.emplace(NoDefaultCtor(i), NoDefaultCtor(100 - i)).second);
1610   }
1611   EXPECT_FALSE(m.emplace(NoDefaultCtor(78), NoDefaultCtor(0)).second);
1612 
1613   auto iter99 = m.find(NoDefaultCtor(99));
1614   ASSERT_NE(iter99, m.end());
1615   EXPECT_EQ(iter99->second.num, 1);
1616 
1617   auto iter1 = m.find(NoDefaultCtor(1));
1618   ASSERT_NE(iter1, m.end());
1619   EXPECT_EQ(iter1->second.num, 99);
1620 
1621   auto iter50 = m.find(NoDefaultCtor(50));
1622   ASSERT_NE(iter50, m.end());
1623   EXPECT_EQ(iter50->second.num, 50);
1624 
1625   auto iter25 = m.find(NoDefaultCtor(25));
1626   ASSERT_NE(iter25, m.end());
1627   EXPECT_EQ(iter25->second.num, 75);
1628 }
1629 
TEST(Btree,BtreeMultimapCanHoldNoDefaultCtorTypes)1630 TEST(Btree, BtreeMultimapCanHoldNoDefaultCtorTypes) {
1631   absl::btree_multimap<NoDefaultCtor, NoDefaultCtor> m;
1632 
1633   for (int i = 1; i <= 99; ++i) {
1634     SCOPED_TRACE(i);
1635     m.emplace(NoDefaultCtor(i), NoDefaultCtor(100 - i));
1636   }
1637 
1638   auto iter99 = m.find(NoDefaultCtor(99));
1639   ASSERT_NE(iter99, m.end());
1640   EXPECT_EQ(iter99->second.num, 1);
1641 
1642   auto iter1 = m.find(NoDefaultCtor(1));
1643   ASSERT_NE(iter1, m.end());
1644   EXPECT_EQ(iter1->second.num, 99);
1645 
1646   auto iter50 = m.find(NoDefaultCtor(50));
1647   ASSERT_NE(iter50, m.end());
1648   EXPECT_EQ(iter50->second.num, 50);
1649 
1650   auto iter25 = m.find(NoDefaultCtor(25));
1651   ASSERT_NE(iter25, m.end());
1652   EXPECT_EQ(iter25->second.num, 75);
1653 }
1654 
TEST(Btree,MapAt)1655 TEST(Btree, MapAt) {
1656   absl::btree_map<int, int> map = {{1, 2}, {2, 4}};
1657   EXPECT_EQ(map.at(1), 2);
1658   EXPECT_EQ(map.at(2), 4);
1659   map.at(2) = 8;
1660   const absl::btree_map<int, int> &const_map = map;
1661   EXPECT_EQ(const_map.at(1), 2);
1662   EXPECT_EQ(const_map.at(2), 8);
1663 #ifdef ABSL_HAVE_EXCEPTIONS
1664   EXPECT_THROW(map.at(3), std::out_of_range);
1665 #else
1666   EXPECT_DEATH_IF_SUPPORTED(map.at(3), "absl::btree_map::at");
1667 #endif
1668 }
1669 
TEST(Btree,BtreeMultisetEmplace)1670 TEST(Btree, BtreeMultisetEmplace) {
1671   const int value_to_insert = 123456;
1672   absl::btree_multiset<int> s;
1673   auto iter = s.emplace(value_to_insert);
1674   ASSERT_NE(iter, s.end());
1675   EXPECT_EQ(*iter, value_to_insert);
1676   iter = s.emplace(value_to_insert);
1677   ASSERT_NE(iter, s.end());
1678   EXPECT_EQ(*iter, value_to_insert);
1679   auto result = s.equal_range(value_to_insert);
1680   EXPECT_EQ(std::distance(result.first, result.second), 2);
1681 }
1682 
TEST(Btree,BtreeMultisetEmplaceHint)1683 TEST(Btree, BtreeMultisetEmplaceHint) {
1684   const int value_to_insert = 123456;
1685   absl::btree_multiset<int> s;
1686   auto iter = s.emplace(value_to_insert);
1687   ASSERT_NE(iter, s.end());
1688   EXPECT_EQ(*iter, value_to_insert);
1689   iter = s.emplace_hint(iter, value_to_insert);
1690   // The new element should be before the previously inserted one.
1691   EXPECT_EQ(iter, s.lower_bound(value_to_insert));
1692   ASSERT_NE(iter, s.end());
1693   EXPECT_EQ(*iter, value_to_insert);
1694 }
1695 
TEST(Btree,BtreeMultimapEmplace)1696 TEST(Btree, BtreeMultimapEmplace) {
1697   const int key_to_insert = 123456;
1698   const char value0[] = "a";
1699   absl::btree_multimap<int, std::string> m;
1700   auto iter = m.emplace(key_to_insert, value0);
1701   ASSERT_NE(iter, m.end());
1702   EXPECT_EQ(iter->first, key_to_insert);
1703   EXPECT_EQ(iter->second, value0);
1704   const char value1[] = "b";
1705   iter = m.emplace(key_to_insert, value1);
1706   ASSERT_NE(iter, m.end());
1707   EXPECT_EQ(iter->first, key_to_insert);
1708   EXPECT_EQ(iter->second, value1);
1709   auto result = m.equal_range(key_to_insert);
1710   EXPECT_EQ(std::distance(result.first, result.second), 2);
1711 }
1712 
TEST(Btree,BtreeMultimapEmplaceHint)1713 TEST(Btree, BtreeMultimapEmplaceHint) {
1714   const int key_to_insert = 123456;
1715   const char value0[] = "a";
1716   absl::btree_multimap<int, std::string> m;
1717   auto iter = m.emplace(key_to_insert, value0);
1718   ASSERT_NE(iter, m.end());
1719   EXPECT_EQ(iter->first, key_to_insert);
1720   EXPECT_EQ(iter->second, value0);
1721   const char value1[] = "b";
1722   iter = m.emplace_hint(iter, key_to_insert, value1);
1723   // The new element should be before the previously inserted one.
1724   EXPECT_EQ(iter, m.lower_bound(key_to_insert));
1725   ASSERT_NE(iter, m.end());
1726   EXPECT_EQ(iter->first, key_to_insert);
1727   EXPECT_EQ(iter->second, value1);
1728 }
1729 
TEST(Btree,ConstIteratorAccessors)1730 TEST(Btree, ConstIteratorAccessors) {
1731   absl::btree_set<int> set;
1732   for (int i = 0; i < 100; ++i) {
1733     set.insert(i);
1734   }
1735 
1736   auto it = set.cbegin();
1737   auto r_it = set.crbegin();
1738   for (int i = 0; i < 100; ++i, ++it, ++r_it) {
1739     ASSERT_EQ(*it, i);
1740     ASSERT_EQ(*r_it, 99 - i);
1741   }
1742   EXPECT_EQ(it, set.cend());
1743   EXPECT_EQ(r_it, set.crend());
1744 }
1745 
TEST(Btree,StrSplitCompatible)1746 TEST(Btree, StrSplitCompatible) {
1747   const absl::btree_set<std::string> split_set = absl::StrSplit("a,b,c", ',');
1748   const absl::btree_set<std::string> expected_set = {"a", "b", "c"};
1749 
1750   EXPECT_EQ(split_set, expected_set);
1751 }
1752 
TEST(Btree,KeyComp)1753 TEST(Btree, KeyComp) {
1754   absl::btree_set<int> s;
1755   EXPECT_TRUE(s.key_comp()(1, 2));
1756   EXPECT_FALSE(s.key_comp()(2, 2));
1757   EXPECT_FALSE(s.key_comp()(2, 1));
1758 
1759   absl::btree_map<int, int> m1;
1760   EXPECT_TRUE(m1.key_comp()(1, 2));
1761   EXPECT_FALSE(m1.key_comp()(2, 2));
1762   EXPECT_FALSE(m1.key_comp()(2, 1));
1763 
1764   // Even though we internally adapt the comparator of `m2` to be three-way and
1765   // heterogeneous, the comparator we expose through key_comp() is the original
1766   // unadapted comparator.
1767   absl::btree_map<std::string, int> m2;
1768   EXPECT_TRUE(m2.key_comp()("a", "b"));
1769   EXPECT_FALSE(m2.key_comp()("b", "b"));
1770   EXPECT_FALSE(m2.key_comp()("b", "a"));
1771 }
1772 
TEST(Btree,ValueComp)1773 TEST(Btree, ValueComp) {
1774   absl::btree_set<int> s;
1775   EXPECT_TRUE(s.value_comp()(1, 2));
1776   EXPECT_FALSE(s.value_comp()(2, 2));
1777   EXPECT_FALSE(s.value_comp()(2, 1));
1778 
1779   absl::btree_map<int, int> m1;
1780   EXPECT_TRUE(m1.value_comp()(std::make_pair(1, 0), std::make_pair(2, 0)));
1781   EXPECT_FALSE(m1.value_comp()(std::make_pair(2, 0), std::make_pair(2, 0)));
1782   EXPECT_FALSE(m1.value_comp()(std::make_pair(2, 0), std::make_pair(1, 0)));
1783 
1784   // Even though we internally adapt the comparator of `m2` to be three-way and
1785   // heterogeneous, the comparator we expose through value_comp() is based on
1786   // the original unadapted comparator.
1787   absl::btree_map<std::string, int> m2;
1788   EXPECT_TRUE(m2.value_comp()(std::make_pair("a", 0), std::make_pair("b", 0)));
1789   EXPECT_FALSE(m2.value_comp()(std::make_pair("b", 0), std::make_pair("b", 0)));
1790   EXPECT_FALSE(m2.value_comp()(std::make_pair("b", 0), std::make_pair("a", 0)));
1791 }
1792 
1793 // Test that we have the protected members from the std::map::value_compare API.
1794 // See https://en.cppreference.com/w/cpp/container/map/value_compare.
TEST(Btree,MapValueCompProtected)1795 TEST(Btree, MapValueCompProtected) {
1796   struct key_compare {
1797     bool operator()(int l, int r) const { return l < r; }
1798     int id;
1799   };
1800   using value_compare = absl::btree_map<int, int, key_compare>::value_compare;
1801   struct value_comp_child : public value_compare {
1802     explicit value_comp_child(key_compare kc) : value_compare(kc) {}
1803     int GetId() const { return comp.id; }
1804   };
1805   value_comp_child c(key_compare{10});
1806   EXPECT_EQ(c.GetId(), 10);
1807 }
1808 
TEST(Btree,DefaultConstruction)1809 TEST(Btree, DefaultConstruction) {
1810   absl::btree_set<int> s;
1811   absl::btree_map<int, int> m;
1812   absl::btree_multiset<int> ms;
1813   absl::btree_multimap<int, int> mm;
1814 
1815   EXPECT_TRUE(s.empty());
1816   EXPECT_TRUE(m.empty());
1817   EXPECT_TRUE(ms.empty());
1818   EXPECT_TRUE(mm.empty());
1819 }
1820 
TEST(Btree,SwissTableHashable)1821 TEST(Btree, SwissTableHashable) {
1822   static constexpr int kValues = 10000;
1823   std::vector<int> values(kValues);
1824   std::iota(values.begin(), values.end(), 0);
1825   std::vector<std::pair<int, int>> map_values;
1826   for (int v : values) map_values.emplace_back(v, -v);
1827 
1828   using set = absl::btree_set<int>;
1829   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1830       set{},
1831       set{1},
1832       set{2},
1833       set{1, 2},
1834       set{2, 1},
1835       set(values.begin(), values.end()),
1836       set(values.rbegin(), values.rend()),
1837   }));
1838 
1839   using mset = absl::btree_multiset<int>;
1840   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1841       mset{},
1842       mset{1},
1843       mset{1, 1},
1844       mset{2},
1845       mset{2, 2},
1846       mset{1, 2},
1847       mset{1, 1, 2},
1848       mset{1, 2, 2},
1849       mset{1, 1, 2, 2},
1850       mset(values.begin(), values.end()),
1851       mset(values.rbegin(), values.rend()),
1852   }));
1853 
1854   using map = absl::btree_map<int, int>;
1855   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1856       map{},
1857       map{{1, 0}},
1858       map{{1, 1}},
1859       map{{2, 0}},
1860       map{{2, 2}},
1861       map{{1, 0}, {2, 1}},
1862       map(map_values.begin(), map_values.end()),
1863       map(map_values.rbegin(), map_values.rend()),
1864   }));
1865 
1866   using mmap = absl::btree_multimap<int, int>;
1867   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1868       mmap{},
1869       mmap{{1, 0}},
1870       mmap{{1, 1}},
1871       mmap{{1, 0}, {1, 1}},
1872       mmap{{1, 1}, {1, 0}},
1873       mmap{{2, 0}},
1874       mmap{{2, 2}},
1875       mmap{{1, 0}, {2, 1}},
1876       mmap(map_values.begin(), map_values.end()),
1877       mmap(map_values.rbegin(), map_values.rend()),
1878   }));
1879 }
1880 
TEST(Btree,ComparableSet)1881 TEST(Btree, ComparableSet) {
1882   absl::btree_set<int> s1 = {1, 2};
1883   absl::btree_set<int> s2 = {2, 3};
1884   EXPECT_LT(s1, s2);
1885   EXPECT_LE(s1, s2);
1886   EXPECT_LE(s1, s1);
1887   EXPECT_GT(s2, s1);
1888   EXPECT_GE(s2, s1);
1889   EXPECT_GE(s1, s1);
1890 }
1891 
TEST(Btree,ComparableSetsDifferentLength)1892 TEST(Btree, ComparableSetsDifferentLength) {
1893   absl::btree_set<int> s1 = {1, 2};
1894   absl::btree_set<int> s2 = {1, 2, 3};
1895   EXPECT_LT(s1, s2);
1896   EXPECT_LE(s1, s2);
1897   EXPECT_GT(s2, s1);
1898   EXPECT_GE(s2, s1);
1899 }
1900 
TEST(Btree,ComparableMultiset)1901 TEST(Btree, ComparableMultiset) {
1902   absl::btree_multiset<int> s1 = {1, 2};
1903   absl::btree_multiset<int> s2 = {2, 3};
1904   EXPECT_LT(s1, s2);
1905   EXPECT_LE(s1, s2);
1906   EXPECT_LE(s1, s1);
1907   EXPECT_GT(s2, s1);
1908   EXPECT_GE(s2, s1);
1909   EXPECT_GE(s1, s1);
1910 }
1911 
TEST(Btree,ComparableMap)1912 TEST(Btree, ComparableMap) {
1913   absl::btree_map<int, int> s1 = {{1, 2}};
1914   absl::btree_map<int, int> s2 = {{2, 3}};
1915   EXPECT_LT(s1, s2);
1916   EXPECT_LE(s1, s2);
1917   EXPECT_LE(s1, s1);
1918   EXPECT_GT(s2, s1);
1919   EXPECT_GE(s2, s1);
1920   EXPECT_GE(s1, s1);
1921 }
1922 
TEST(Btree,ComparableMultimap)1923 TEST(Btree, ComparableMultimap) {
1924   absl::btree_multimap<int, int> s1 = {{1, 2}};
1925   absl::btree_multimap<int, int> s2 = {{2, 3}};
1926   EXPECT_LT(s1, s2);
1927   EXPECT_LE(s1, s2);
1928   EXPECT_LE(s1, s1);
1929   EXPECT_GT(s2, s1);
1930   EXPECT_GE(s2, s1);
1931   EXPECT_GE(s1, s1);
1932 }
1933 
TEST(Btree,ComparableSetWithCustomComparator)1934 TEST(Btree, ComparableSetWithCustomComparator) {
1935   // As specified by
1936   // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf section
1937   // [container.requirements.general].12, ordering associative containers always
1938   // uses default '<' operator
1939   // - even if otherwise the container uses custom functor.
1940   absl::btree_set<int, std::greater<int>> s1 = {1, 2};
1941   absl::btree_set<int, std::greater<int>> s2 = {2, 3};
1942   EXPECT_LT(s1, s2);
1943   EXPECT_LE(s1, s2);
1944   EXPECT_LE(s1, s1);
1945   EXPECT_GT(s2, s1);
1946   EXPECT_GE(s2, s1);
1947   EXPECT_GE(s1, s1);
1948 }
1949 
TEST(Btree,EraseReturnsIterator)1950 TEST(Btree, EraseReturnsIterator) {
1951   absl::btree_set<int> set = {1, 2, 3, 4, 5};
1952   auto result_it = set.erase(set.begin(), set.find(3));
1953   EXPECT_EQ(result_it, set.find(3));
1954   result_it = set.erase(set.find(5));
1955   EXPECT_EQ(result_it, set.end());
1956 }
1957 
TEST(Btree,ExtractAndInsertNodeHandleSet)1958 TEST(Btree, ExtractAndInsertNodeHandleSet) {
1959   absl::btree_set<int> src1 = {1, 2, 3, 4, 5};
1960   auto nh = src1.extract(src1.find(3));
1961   EXPECT_THAT(src1, ElementsAre(1, 2, 4, 5));
1962   absl::btree_set<int> other;
1963   absl::btree_set<int>::insert_return_type res = other.insert(std::move(nh));
1964   EXPECT_THAT(other, ElementsAre(3));
1965   EXPECT_EQ(res.position, other.find(3));
1966   EXPECT_TRUE(res.inserted);
1967   EXPECT_TRUE(res.node.empty());
1968 
1969   absl::btree_set<int> src2 = {3, 4};
1970   nh = src2.extract(src2.find(3));
1971   EXPECT_THAT(src2, ElementsAre(4));
1972   res = other.insert(std::move(nh));
1973   EXPECT_THAT(other, ElementsAre(3));
1974   EXPECT_EQ(res.position, other.find(3));
1975   EXPECT_FALSE(res.inserted);
1976   ASSERT_FALSE(res.node.empty());
1977   EXPECT_EQ(res.node.value(), 3);
1978 }
1979 
1980 template <typename Set>
TestExtractWithTrackingForSet()1981 void TestExtractWithTrackingForSet() {
1982   InstanceTracker tracker;
1983   {
1984     Set s;
1985     // Add enough elements to make sure we test internal nodes too.
1986     const size_t kSize = 1000;
1987     while (s.size() < kSize) {
1988       s.insert(MovableOnlyInstance(s.size()));
1989     }
1990     for (int i = 0; i < kSize; ++i) {
1991       // Extract with key
1992       auto nh = s.extract(MovableOnlyInstance(i));
1993       EXPECT_EQ(s.size(), kSize - 1);
1994       EXPECT_EQ(nh.value().value(), i);
1995       // Insert with node
1996       s.insert(std::move(nh));
1997       EXPECT_EQ(s.size(), kSize);
1998 
1999       // Extract with iterator
2000       auto it = s.find(MovableOnlyInstance(i));
2001       nh = s.extract(it);
2002       EXPECT_EQ(s.size(), kSize - 1);
2003       EXPECT_EQ(nh.value().value(), i);
2004       // Insert with node and hint
2005       s.insert(s.begin(), std::move(nh));
2006       EXPECT_EQ(s.size(), kSize);
2007     }
2008   }
2009   EXPECT_EQ(0, tracker.instances());
2010 }
2011 
2012 template <typename Map>
TestExtractWithTrackingForMap()2013 void TestExtractWithTrackingForMap() {
2014   InstanceTracker tracker;
2015   {
2016     Map m;
2017     // Add enough elements to make sure we test internal nodes too.
2018     const size_t kSize = 1000;
2019     while (m.size() < kSize) {
2020       m.insert(
2021           {CopyableMovableInstance(m.size()), MovableOnlyInstance(m.size())});
2022     }
2023     for (int i = 0; i < kSize; ++i) {
2024       // Extract with key
2025       auto nh = m.extract(CopyableMovableInstance(i));
2026       EXPECT_EQ(m.size(), kSize - 1);
2027       EXPECT_EQ(nh.key().value(), i);
2028       EXPECT_EQ(nh.mapped().value(), i);
2029       // Insert with node
2030       m.insert(std::move(nh));
2031       EXPECT_EQ(m.size(), kSize);
2032 
2033       // Extract with iterator
2034       auto it = m.find(CopyableMovableInstance(i));
2035       nh = m.extract(it);
2036       EXPECT_EQ(m.size(), kSize - 1);
2037       EXPECT_EQ(nh.key().value(), i);
2038       EXPECT_EQ(nh.mapped().value(), i);
2039       // Insert with node and hint
2040       m.insert(m.begin(), std::move(nh));
2041       EXPECT_EQ(m.size(), kSize);
2042     }
2043   }
2044   EXPECT_EQ(0, tracker.instances());
2045 }
2046 
TEST(Btree,ExtractTracking)2047 TEST(Btree, ExtractTracking) {
2048   TestExtractWithTrackingForSet<absl::btree_set<MovableOnlyInstance>>();
2049   TestExtractWithTrackingForSet<absl::btree_multiset<MovableOnlyInstance>>();
2050   TestExtractWithTrackingForMap<
2051       absl::btree_map<CopyableMovableInstance, MovableOnlyInstance>>();
2052   TestExtractWithTrackingForMap<
2053       absl::btree_multimap<CopyableMovableInstance, MovableOnlyInstance>>();
2054 }
2055 
TEST(Btree,ExtractAndInsertNodeHandleMultiSet)2056 TEST(Btree, ExtractAndInsertNodeHandleMultiSet) {
2057   absl::btree_multiset<int> src1 = {1, 2, 3, 3, 4, 5};
2058   auto nh = src1.extract(src1.find(3));
2059   EXPECT_THAT(src1, ElementsAre(1, 2, 3, 4, 5));
2060   absl::btree_multiset<int> other;
2061   auto res = other.insert(std::move(nh));
2062   EXPECT_THAT(other, ElementsAre(3));
2063   EXPECT_EQ(res, other.find(3));
2064 
2065   absl::btree_multiset<int> src2 = {3, 4};
2066   nh = src2.extract(src2.find(3));
2067   EXPECT_THAT(src2, ElementsAre(4));
2068   res = other.insert(std::move(nh));
2069   EXPECT_THAT(other, ElementsAre(3, 3));
2070   EXPECT_EQ(res, ++other.find(3));
2071 }
2072 
TEST(Btree,ExtractAndInsertNodeHandleMap)2073 TEST(Btree, ExtractAndInsertNodeHandleMap) {
2074   absl::btree_map<int, int> src1 = {{1, 2}, {3, 4}, {5, 6}};
2075   auto nh = src1.extract(src1.find(3));
2076   EXPECT_THAT(src1, ElementsAre(Pair(1, 2), Pair(5, 6)));
2077   absl::btree_map<int, int> other;
2078   absl::btree_map<int, int>::insert_return_type res =
2079       other.insert(std::move(nh));
2080   EXPECT_THAT(other, ElementsAre(Pair(3, 4)));
2081   EXPECT_EQ(res.position, other.find(3));
2082   EXPECT_TRUE(res.inserted);
2083   EXPECT_TRUE(res.node.empty());
2084 
2085   absl::btree_map<int, int> src2 = {{3, 6}};
2086   nh = src2.extract(src2.find(3));
2087   EXPECT_TRUE(src2.empty());
2088   res = other.insert(std::move(nh));
2089   EXPECT_THAT(other, ElementsAre(Pair(3, 4)));
2090   EXPECT_EQ(res.position, other.find(3));
2091   EXPECT_FALSE(res.inserted);
2092   ASSERT_FALSE(res.node.empty());
2093   EXPECT_EQ(res.node.key(), 3);
2094   EXPECT_EQ(res.node.mapped(), 6);
2095 }
2096 
TEST(Btree,ExtractAndInsertNodeHandleMultiMap)2097 TEST(Btree, ExtractAndInsertNodeHandleMultiMap) {
2098   absl::btree_multimap<int, int> src1 = {{1, 2}, {3, 4}, {5, 6}};
2099   auto nh = src1.extract(src1.find(3));
2100   EXPECT_THAT(src1, ElementsAre(Pair(1, 2), Pair(5, 6)));
2101   absl::btree_multimap<int, int> other;
2102   auto res = other.insert(std::move(nh));
2103   EXPECT_THAT(other, ElementsAre(Pair(3, 4)));
2104   EXPECT_EQ(res, other.find(3));
2105 
2106   absl::btree_multimap<int, int> src2 = {{3, 6}};
2107   nh = src2.extract(src2.find(3));
2108   EXPECT_TRUE(src2.empty());
2109   res = other.insert(std::move(nh));
2110   EXPECT_THAT(other, ElementsAre(Pair(3, 4), Pair(3, 6)));
2111   EXPECT_EQ(res, ++other.begin());
2112 }
2113 
TEST(Btree,ExtractMultiMapEquivalentKeys)2114 TEST(Btree, ExtractMultiMapEquivalentKeys) {
2115   // Note: using string keys means a three-way comparator.
2116   absl::btree_multimap<std::string, int> map;
2117   for (int i = 0; i < 100; ++i) {
2118     for (int j = 0; j < 100; ++j) {
2119       map.insert({absl::StrCat(i), j});
2120     }
2121   }
2122 
2123   for (int i = 0; i < 100; ++i) {
2124     const std::string key = absl::StrCat(i);
2125     auto node_handle = map.extract(key);
2126     EXPECT_EQ(node_handle.key(), key);
2127     EXPECT_EQ(node_handle.mapped(), 0) << i;
2128   }
2129 
2130   for (int i = 0; i < 100; ++i) {
2131     const std::string key = absl::StrCat(i);
2132     auto node_handle = map.extract(key);
2133     EXPECT_EQ(node_handle.key(), key);
2134     EXPECT_EQ(node_handle.mapped(), 1) << i;
2135   }
2136 }
2137 
TEST(Btree,ExtractAndGetNextSet)2138 TEST(Btree, ExtractAndGetNextSet) {
2139   absl::btree_set<int> src = {1, 2, 3, 4, 5};
2140   auto it = src.find(3);
2141   auto extracted_and_next = src.extract_and_get_next(it);
2142   EXPECT_THAT(src, ElementsAre(1, 2, 4, 5));
2143   EXPECT_EQ(extracted_and_next.node.value(), 3);
2144   EXPECT_EQ(*extracted_and_next.next, 4);
2145 }
2146 
TEST(Btree,ExtractAndGetNextMultiSet)2147 TEST(Btree, ExtractAndGetNextMultiSet) {
2148   absl::btree_multiset<int> src = {1, 2, 3, 4, 5};
2149   auto it = src.find(3);
2150   auto extracted_and_next = src.extract_and_get_next(it);
2151   EXPECT_THAT(src, ElementsAre(1, 2, 4, 5));
2152   EXPECT_EQ(extracted_and_next.node.value(), 3);
2153   EXPECT_EQ(*extracted_and_next.next, 4);
2154 }
2155 
TEST(Btree,ExtractAndGetNextMap)2156 TEST(Btree, ExtractAndGetNextMap) {
2157   absl::btree_map<int, int> src = {{1, 2}, {3, 4}, {5, 6}};
2158   auto it = src.find(3);
2159   auto extracted_and_next = src.extract_and_get_next(it);
2160   EXPECT_THAT(src, ElementsAre(Pair(1, 2), Pair(5, 6)));
2161   EXPECT_EQ(extracted_and_next.node.key(), 3);
2162   EXPECT_EQ(extracted_and_next.node.mapped(), 4);
2163   EXPECT_THAT(*extracted_and_next.next, Pair(5, 6));
2164 }
2165 
TEST(Btree,ExtractAndGetNextMultiMap)2166 TEST(Btree, ExtractAndGetNextMultiMap) {
2167   absl::btree_multimap<int, int> src = {{1, 2}, {3, 4}, {5, 6}};
2168   auto it = src.find(3);
2169   auto extracted_and_next = src.extract_and_get_next(it);
2170   EXPECT_THAT(src, ElementsAre(Pair(1, 2), Pair(5, 6)));
2171   EXPECT_EQ(extracted_and_next.node.key(), 3);
2172   EXPECT_EQ(extracted_and_next.node.mapped(), 4);
2173   EXPECT_THAT(*extracted_and_next.next, Pair(5, 6));
2174 }
2175 
TEST(Btree,ExtractAndGetNextEndIter)2176 TEST(Btree, ExtractAndGetNextEndIter) {
2177   absl::btree_set<int> src = {1, 2, 3, 4, 5};
2178   auto it = src.find(5);
2179   auto extracted_and_next = src.extract_and_get_next(it);
2180   EXPECT_THAT(src, ElementsAre(1, 2, 3, 4));
2181   EXPECT_EQ(extracted_and_next.node.value(), 5);
2182   EXPECT_EQ(extracted_and_next.next, src.end());
2183 }
2184 
TEST(Btree,ExtractDoesntCauseExtraMoves)2185 TEST(Btree, ExtractDoesntCauseExtraMoves) {
2186 #ifdef _MSC_VER
2187   GTEST_SKIP() << "This test fails on MSVC.";
2188 #endif
2189 
2190   using Set = absl::btree_set<MovableOnlyInstance>;
2191   std::array<std::function<void(Set &)>, 3> extracters = {
2192       [](Set &s) { auto node = s.extract(s.begin()); },
2193       [](Set &s) { auto ret = s.extract_and_get_next(s.begin()); },
2194       [](Set &s) { auto node = s.extract(MovableOnlyInstance(0)); }};
2195 
2196   InstanceTracker tracker;
2197   for (int i = 0; i < 3; ++i) {
2198     Set s;
2199     s.insert(MovableOnlyInstance(0));
2200     tracker.ResetCopiesMovesSwaps();
2201 
2202     extracters[i](s);
2203     // We expect to see exactly 1 move: from the original slot into the
2204     // extracted node.
2205     EXPECT_EQ(tracker.copies(), 0) << i;
2206     EXPECT_EQ(tracker.moves(), 1) << i;
2207     EXPECT_EQ(tracker.swaps(), 0) << i;
2208   }
2209 }
2210 
2211 // For multisets, insert with hint also affects correctness because we need to
2212 // insert immediately before the hint if possible.
2213 struct InsertMultiHintData {
2214   int key;
2215   int not_key;
operator ==absl::container_internal::__anona1fef86c0411::InsertMultiHintData2216   bool operator==(const InsertMultiHintData other) const {
2217     return key == other.key && not_key == other.not_key;
2218   }
2219 };
2220 
2221 struct InsertMultiHintDataKeyCompare {
2222   using is_transparent = void;
operator ()absl::container_internal::__anona1fef86c0411::InsertMultiHintDataKeyCompare2223   bool operator()(const InsertMultiHintData a,
2224                   const InsertMultiHintData b) const {
2225     return a.key < b.key;
2226   }
operator ()absl::container_internal::__anona1fef86c0411::InsertMultiHintDataKeyCompare2227   bool operator()(const int a, const InsertMultiHintData b) const {
2228     return a < b.key;
2229   }
operator ()absl::container_internal::__anona1fef86c0411::InsertMultiHintDataKeyCompare2230   bool operator()(const InsertMultiHintData a, const int b) const {
2231     return a.key < b;
2232   }
2233 };
2234 
TEST(Btree,InsertHintNodeHandle)2235 TEST(Btree, InsertHintNodeHandle) {
2236   // For unique sets, insert with hint is just a performance optimization.
2237   // Test that insert works correctly when the hint is right or wrong.
2238   {
2239     absl::btree_set<int> src = {1, 2, 3, 4, 5};
2240     auto nh = src.extract(src.find(3));
2241     EXPECT_THAT(src, ElementsAre(1, 2, 4, 5));
2242     absl::btree_set<int> other = {0, 100};
2243     // Test a correct hint.
2244     auto it = other.insert(other.lower_bound(3), std::move(nh));
2245     EXPECT_THAT(other, ElementsAre(0, 3, 100));
2246     EXPECT_EQ(it, other.find(3));
2247 
2248     nh = src.extract(src.find(5));
2249     // Test an incorrect hint.
2250     it = other.insert(other.end(), std::move(nh));
2251     EXPECT_THAT(other, ElementsAre(0, 3, 5, 100));
2252     EXPECT_EQ(it, other.find(5));
2253   }
2254 
2255   absl::btree_multiset<InsertMultiHintData, InsertMultiHintDataKeyCompare> src =
2256       {{1, 2}, {3, 4}, {3, 5}};
2257   auto nh = src.extract(src.lower_bound(3));
2258   EXPECT_EQ(nh.value(), (InsertMultiHintData{3, 4}));
2259   absl::btree_multiset<InsertMultiHintData, InsertMultiHintDataKeyCompare>
2260       other = {{3, 1}, {3, 2}, {3, 3}};
2261   auto it = other.insert(--other.end(), std::move(nh));
2262   EXPECT_THAT(
2263       other, ElementsAre(InsertMultiHintData{3, 1}, InsertMultiHintData{3, 2},
2264                          InsertMultiHintData{3, 4}, InsertMultiHintData{3, 3}));
2265   EXPECT_EQ(it, --(--other.end()));
2266 
2267   nh = src.extract(src.find(3));
2268   EXPECT_EQ(nh.value(), (InsertMultiHintData{3, 5}));
2269   it = other.insert(other.begin(), std::move(nh));
2270   EXPECT_THAT(other,
2271               ElementsAre(InsertMultiHintData{3, 5}, InsertMultiHintData{3, 1},
2272                           InsertMultiHintData{3, 2}, InsertMultiHintData{3, 4},
2273                           InsertMultiHintData{3, 3}));
2274   EXPECT_EQ(it, other.begin());
2275 }
2276 
2277 struct IntCompareToCmp {
operator ()absl::container_internal::__anona1fef86c0411::IntCompareToCmp2278   absl::weak_ordering operator()(int a, int b) const {
2279     if (a < b) return absl::weak_ordering::less;
2280     if (a > b) return absl::weak_ordering::greater;
2281     return absl::weak_ordering::equivalent;
2282   }
2283 };
2284 
TEST(Btree,MergeIntoUniqueContainers)2285 TEST(Btree, MergeIntoUniqueContainers) {
2286   absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2287   absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2288   absl::btree_set<int> dst;
2289 
2290   dst.merge(src1);
2291   EXPECT_TRUE(src1.empty());
2292   EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2293   dst.merge(src2);
2294   EXPECT_THAT(src2, ElementsAre(3, 4));
2295   EXPECT_THAT(dst, ElementsAre(1, 2, 3, 4, 5));
2296 }
2297 
TEST(Btree,MergeIntoUniqueContainersWithCompareTo)2298 TEST(Btree, MergeIntoUniqueContainersWithCompareTo) {
2299   absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2300   absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2301   absl::btree_set<int, IntCompareToCmp> dst;
2302 
2303   dst.merge(src1);
2304   EXPECT_TRUE(src1.empty());
2305   EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2306   dst.merge(src2);
2307   EXPECT_THAT(src2, ElementsAre(3, 4));
2308   EXPECT_THAT(dst, ElementsAre(1, 2, 3, 4, 5));
2309 }
2310 
TEST(Btree,MergeIntoMultiContainers)2311 TEST(Btree, MergeIntoMultiContainers) {
2312   absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2313   absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2314   absl::btree_multiset<int> dst;
2315 
2316   dst.merge(src1);
2317   EXPECT_TRUE(src1.empty());
2318   EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2319   dst.merge(src2);
2320   EXPECT_TRUE(src2.empty());
2321   EXPECT_THAT(dst, ElementsAre(1, 2, 3, 3, 4, 4, 5));
2322 }
2323 
TEST(Btree,MergeIntoMultiContainersWithCompareTo)2324 TEST(Btree, MergeIntoMultiContainersWithCompareTo) {
2325   absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2326   absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2327   absl::btree_multiset<int, IntCompareToCmp> dst;
2328 
2329   dst.merge(src1);
2330   EXPECT_TRUE(src1.empty());
2331   EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2332   dst.merge(src2);
2333   EXPECT_TRUE(src2.empty());
2334   EXPECT_THAT(dst, ElementsAre(1, 2, 3, 3, 4, 4, 5));
2335 }
2336 
TEST(Btree,MergeIntoMultiMapsWithDifferentComparators)2337 TEST(Btree, MergeIntoMultiMapsWithDifferentComparators) {
2338   absl::btree_map<int, int, IntCompareToCmp> src1 = {{1, 1}, {2, 2}, {3, 3}};
2339   absl::btree_multimap<int, int, std::greater<int>> src2 = {
2340       {5, 5}, {4, 1}, {4, 4}, {3, 2}};
2341   absl::btree_multimap<int, int> dst;
2342 
2343   dst.merge(src1);
2344   EXPECT_TRUE(src1.empty());
2345   EXPECT_THAT(dst, ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3)));
2346   dst.merge(src2);
2347   EXPECT_TRUE(src2.empty());
2348   EXPECT_THAT(dst, ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3), Pair(3, 2),
2349                                Pair(4, 1), Pair(4, 4), Pair(5, 5)));
2350 }
2351 
TEST(Btree,MergeIntoSetMovableOnly)2352 TEST(Btree, MergeIntoSetMovableOnly) {
2353   absl::btree_set<MovableOnlyInstance> src;
2354   src.insert(MovableOnlyInstance(1));
2355   absl::btree_multiset<MovableOnlyInstance> dst1;
2356   dst1.insert(MovableOnlyInstance(2));
2357   absl::btree_set<MovableOnlyInstance> dst2;
2358 
2359   // Test merge into multiset.
2360   dst1.merge(src);
2361 
2362   EXPECT_TRUE(src.empty());
2363   // ElementsAre/ElementsAreArray don't work with move-only types.
2364   ASSERT_THAT(dst1, SizeIs(2));
2365   EXPECT_EQ(*dst1.begin(), MovableOnlyInstance(1));
2366   EXPECT_EQ(*std::next(dst1.begin()), MovableOnlyInstance(2));
2367 
2368   // Test merge into set.
2369   dst2.merge(dst1);
2370 
2371   EXPECT_TRUE(dst1.empty());
2372   ASSERT_THAT(dst2, SizeIs(2));
2373   EXPECT_EQ(*dst2.begin(), MovableOnlyInstance(1));
2374   EXPECT_EQ(*std::next(dst2.begin()), MovableOnlyInstance(2));
2375 }
2376 
2377 struct KeyCompareToWeakOrdering {
2378   template <typename T>
operator ()absl::container_internal::__anona1fef86c0411::KeyCompareToWeakOrdering2379   absl::weak_ordering operator()(const T &a, const T &b) const {
2380     return a < b ? absl::weak_ordering::less
2381                  : a == b ? absl::weak_ordering::equivalent
2382                           : absl::weak_ordering::greater;
2383   }
2384 };
2385 
2386 struct KeyCompareToStrongOrdering {
2387   template <typename T>
operator ()absl::container_internal::__anona1fef86c0411::KeyCompareToStrongOrdering2388   absl::strong_ordering operator()(const T &a, const T &b) const {
2389     return a < b ? absl::strong_ordering::less
2390                  : a == b ? absl::strong_ordering::equal
2391                           : absl::strong_ordering::greater;
2392   }
2393 };
2394 
TEST(Btree,UserProvidedKeyCompareToComparators)2395 TEST(Btree, UserProvidedKeyCompareToComparators) {
2396   absl::btree_set<int, KeyCompareToWeakOrdering> weak_set = {1, 2, 3};
2397   EXPECT_TRUE(weak_set.contains(2));
2398   EXPECT_FALSE(weak_set.contains(4));
2399 
2400   absl::btree_set<int, KeyCompareToStrongOrdering> strong_set = {1, 2, 3};
2401   EXPECT_TRUE(strong_set.contains(2));
2402   EXPECT_FALSE(strong_set.contains(4));
2403 }
2404 
TEST(Btree,TryEmplaceBasicTest)2405 TEST(Btree, TryEmplaceBasicTest) {
2406   absl::btree_map<int, std::string> m;
2407 
2408   // Should construct a string from the literal.
2409   m.try_emplace(1, "one");
2410   EXPECT_EQ(1, m.size());
2411 
2412   // Try other string constructors and const lvalue key.
2413   const int key(42);
2414   m.try_emplace(key, 3, 'a');
2415   m.try_emplace(2, std::string("two"));
2416 
2417   EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2418   EXPECT_THAT(m, ElementsAreArray(std::vector<std::pair<int, std::string>>{
2419                      {1, "one"}, {2, "two"}, {42, "aaa"}}));
2420 }
2421 
TEST(Btree,TryEmplaceWithHintWorks)2422 TEST(Btree, TryEmplaceWithHintWorks) {
2423   // Use a counting comparator here to verify that hint is used.
2424   int calls = 0;
2425   auto cmp = [&calls](int x, int y) {
2426     ++calls;
2427     return x < y;
2428   };
2429   using Cmp = decltype(cmp);
2430 
2431   // Use a map that is opted out of key_compare being adapted so we can expect
2432   // strict comparison call limits.
2433   absl::btree_map<int, int, CheckedCompareOptedOutCmp<Cmp>> m(cmp);
2434   for (int i = 0; i < 128; ++i) {
2435     m.emplace(i, i);
2436   }
2437 
2438   // Sanity check for the comparator
2439   calls = 0;
2440   m.emplace(127, 127);
2441   EXPECT_GE(calls, 4);
2442 
2443   // Try with begin hint:
2444   calls = 0;
2445   auto it = m.try_emplace(m.begin(), -1, -1);
2446   EXPECT_EQ(129, m.size());
2447   EXPECT_EQ(it, m.begin());
2448   EXPECT_LE(calls, 2);
2449 
2450   // Try with end hint:
2451   calls = 0;
2452   std::pair<int, int> pair1024 = {1024, 1024};
2453   it = m.try_emplace(m.end(), pair1024.first, pair1024.second);
2454   EXPECT_EQ(130, m.size());
2455   EXPECT_EQ(it, --m.end());
2456   EXPECT_LE(calls, 2);
2457 
2458   // Try value already present, bad hint; ensure no duplicate added:
2459   calls = 0;
2460   it = m.try_emplace(m.end(), 16, 17);
2461   EXPECT_EQ(130, m.size());
2462   EXPECT_GE(calls, 4);
2463   EXPECT_EQ(it, m.find(16));
2464 
2465   // Try value already present, hint points directly to it:
2466   calls = 0;
2467   it = m.try_emplace(it, 16, 17);
2468   EXPECT_EQ(130, m.size());
2469   EXPECT_LE(calls, 2);
2470   EXPECT_EQ(it, m.find(16));
2471 
2472   m.erase(2);
2473   EXPECT_EQ(129, m.size());
2474   auto hint = m.find(3);
2475   // Try emplace in the middle of two other elements.
2476   calls = 0;
2477   m.try_emplace(hint, 2, 2);
2478   EXPECT_EQ(130, m.size());
2479   EXPECT_LE(calls, 2);
2480 
2481   EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2482 }
2483 
TEST(Btree,TryEmplaceWithBadHint)2484 TEST(Btree, TryEmplaceWithBadHint) {
2485   absl::btree_map<int, int> m = {{1, 1}, {9, 9}};
2486 
2487   // Bad hint (too small), should still emplace:
2488   auto it = m.try_emplace(m.begin(), 2, 2);
2489   EXPECT_EQ(it, ++m.begin());
2490   EXPECT_THAT(m, ElementsAreArray(
2491                      std::vector<std::pair<int, int>>{{1, 1}, {2, 2}, {9, 9}}));
2492 
2493   // Bad hint, too large this time:
2494   it = m.try_emplace(++(++m.begin()), 0, 0);
2495   EXPECT_EQ(it, m.begin());
2496   EXPECT_THAT(m, ElementsAreArray(std::vector<std::pair<int, int>>{
2497                      {0, 0}, {1, 1}, {2, 2}, {9, 9}}));
2498 }
2499 
TEST(Btree,TryEmplaceMaintainsSortedOrder)2500 TEST(Btree, TryEmplaceMaintainsSortedOrder) {
2501   absl::btree_map<int, std::string> m;
2502   std::pair<int, std::string> pair5 = {5, "five"};
2503 
2504   // Test both lvalue & rvalue emplace.
2505   m.try_emplace(10, "ten");
2506   m.try_emplace(pair5.first, pair5.second);
2507   EXPECT_EQ(2, m.size());
2508   EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2509 
2510   int int100{100};
2511   m.try_emplace(int100, "hundred");
2512   m.try_emplace(1, "one");
2513   EXPECT_EQ(4, m.size());
2514   EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2515 }
2516 
TEST(Btree,TryEmplaceWithHintAndNoValueArgsWorks)2517 TEST(Btree, TryEmplaceWithHintAndNoValueArgsWorks) {
2518   absl::btree_map<int, int> m;
2519   m.try_emplace(m.end(), 1);
2520   EXPECT_EQ(0, m[1]);
2521 }
2522 
TEST(Btree,TryEmplaceWithHintAndMultipleValueArgsWorks)2523 TEST(Btree, TryEmplaceWithHintAndMultipleValueArgsWorks) {
2524   absl::btree_map<int, std::string> m;
2525   m.try_emplace(m.end(), 1, 10, 'a');
2526   EXPECT_EQ(std::string(10, 'a'), m[1]);
2527 }
2528 
TEST(Btree,MoveAssignmentAllocatorPropagation)2529 TEST(Btree, MoveAssignmentAllocatorPropagation) {
2530   InstanceTracker tracker;
2531 
2532   int64_t bytes1 = 0, bytes2 = 0;
2533   PropagatingCountingAlloc<MovableOnlyInstance> allocator1(&bytes1);
2534   PropagatingCountingAlloc<MovableOnlyInstance> allocator2(&bytes2);
2535   std::less<MovableOnlyInstance> cmp;
2536 
2537   // Test propagating allocator_type.
2538   {
2539     absl::btree_set<MovableOnlyInstance, std::less<MovableOnlyInstance>,
2540                     PropagatingCountingAlloc<MovableOnlyInstance>>
2541         set1(cmp, allocator1), set2(cmp, allocator2);
2542 
2543     for (int i = 0; i < 100; ++i) set1.insert(MovableOnlyInstance(i));
2544 
2545     tracker.ResetCopiesMovesSwaps();
2546     set2 = std::move(set1);
2547     EXPECT_EQ(tracker.moves(), 0);
2548   }
2549   // Test non-propagating allocator_type with equal allocators.
2550   {
2551     absl::btree_set<MovableOnlyInstance, std::less<MovableOnlyInstance>,
2552                     CountingAllocator<MovableOnlyInstance>>
2553         set1(cmp, allocator1), set2(cmp, allocator1);
2554 
2555     for (int i = 0; i < 100; ++i) set1.insert(MovableOnlyInstance(i));
2556 
2557     tracker.ResetCopiesMovesSwaps();
2558     set2 = std::move(set1);
2559     EXPECT_EQ(tracker.moves(), 0);
2560   }
2561   // Test non-propagating allocator_type with different allocators.
2562   {
2563     absl::btree_set<MovableOnlyInstance, std::less<MovableOnlyInstance>,
2564                     CountingAllocator<MovableOnlyInstance>>
2565         set1(cmp, allocator1), set2(cmp, allocator2);
2566 
2567     for (int i = 0; i < 100; ++i) set1.insert(MovableOnlyInstance(i));
2568 
2569     tracker.ResetCopiesMovesSwaps();
2570     set2 = std::move(set1);
2571     EXPECT_GE(tracker.moves(), 100);
2572   }
2573 }
2574 
TEST(Btree,EmptyTree)2575 TEST(Btree, EmptyTree) {
2576   absl::btree_set<int> s;
2577   EXPECT_TRUE(s.empty());
2578   EXPECT_EQ(s.size(), 0);
2579   EXPECT_GT(s.max_size(), 0);
2580 }
2581 
IsEven(int k)2582 bool IsEven(int k) { return k % 2 == 0; }
2583 
TEST(Btree,EraseIf)2584 TEST(Btree, EraseIf) {
2585   // Test that erase_if works with all the container types and supports lambdas.
2586   {
2587     absl::btree_set<int> s = {1, 3, 5, 6, 100};
2588     EXPECT_EQ(erase_if(s, [](int k) { return k > 3; }), 3);
2589     EXPECT_THAT(s, ElementsAre(1, 3));
2590   }
2591   {
2592     absl::btree_multiset<int> s = {1, 3, 3, 5, 6, 6, 100};
2593     EXPECT_EQ(erase_if(s, [](int k) { return k <= 3; }), 3);
2594     EXPECT_THAT(s, ElementsAre(5, 6, 6, 100));
2595   }
2596   {
2597     absl::btree_map<int, int> m = {{1, 1}, {3, 3}, {6, 6}, {100, 100}};
2598     EXPECT_EQ(
2599         erase_if(m, [](std::pair<const int, int> kv) { return kv.first > 3; }),
2600         2);
2601     EXPECT_THAT(m, ElementsAre(Pair(1, 1), Pair(3, 3)));
2602   }
2603   {
2604     absl::btree_multimap<int, int> m = {{1, 1}, {3, 3}, {3, 6},
2605                                         {6, 6}, {6, 7}, {100, 6}};
2606     EXPECT_EQ(
2607         erase_if(m,
2608                  [](std::pair<const int, int> kv) { return kv.second == 6; }),
2609         3);
2610     EXPECT_THAT(m, ElementsAre(Pair(1, 1), Pair(3, 3), Pair(6, 7)));
2611   }
2612   // Test that erasing all elements from a large set works and test support for
2613   // function pointers.
2614   {
2615     absl::btree_set<int> s;
2616     for (int i = 0; i < 1000; ++i) s.insert(2 * i);
2617     EXPECT_EQ(erase_if(s, IsEven), 1000);
2618     EXPECT_THAT(s, IsEmpty());
2619   }
2620   // Test that erase_if supports other format of function pointers.
2621   {
2622     absl::btree_set<int> s = {1, 3, 5, 6, 100};
2623     EXPECT_EQ(erase_if(s, &IsEven), 2);
2624     EXPECT_THAT(s, ElementsAre(1, 3, 5));
2625   }
2626   // Test that erase_if invokes the predicate once per element.
2627   {
2628     absl::btree_set<int> s;
2629     for (int i = 0; i < 1000; ++i) s.insert(i);
2630     int pred_calls = 0;
2631     EXPECT_EQ(erase_if(s,
2632                        [&pred_calls](int k) {
2633                          ++pred_calls;
2634                          return k % 2;
2635                        }),
2636               500);
2637     EXPECT_THAT(s, SizeIs(500));
2638     EXPECT_EQ(pred_calls, 1000);
2639   }
2640 }
2641 
TEST(Btree,InsertOrAssign)2642 TEST(Btree, InsertOrAssign) {
2643   absl::btree_map<int, int> m = {{1, 1}, {3, 3}};
2644   using value_type = typename decltype(m)::value_type;
2645 
2646   auto ret = m.insert_or_assign(4, 4);
2647   EXPECT_EQ(*ret.first, value_type(4, 4));
2648   EXPECT_TRUE(ret.second);
2649   ret = m.insert_or_assign(3, 100);
2650   EXPECT_EQ(*ret.first, value_type(3, 100));
2651   EXPECT_FALSE(ret.second);
2652 
2653   auto hint_ret = m.insert_or_assign(ret.first, 3, 200);
2654   EXPECT_EQ(*hint_ret, value_type(3, 200));
2655   hint_ret = m.insert_or_assign(m.find(1), 0, 1);
2656   EXPECT_EQ(*hint_ret, value_type(0, 1));
2657   // Test with bad hint.
2658   hint_ret = m.insert_or_assign(m.end(), -1, 1);
2659   EXPECT_EQ(*hint_ret, value_type(-1, 1));
2660 
2661   EXPECT_THAT(m, ElementsAre(Pair(-1, 1), Pair(0, 1), Pair(1, 1), Pair(3, 200),
2662                              Pair(4, 4)));
2663 }
2664 
TEST(Btree,InsertOrAssignMovableOnly)2665 TEST(Btree, InsertOrAssignMovableOnly) {
2666   absl::btree_map<int, MovableOnlyInstance> m;
2667   using value_type = typename decltype(m)::value_type;
2668 
2669   auto ret = m.insert_or_assign(4, MovableOnlyInstance(4));
2670   EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(4)));
2671   EXPECT_TRUE(ret.second);
2672   ret = m.insert_or_assign(4, MovableOnlyInstance(100));
2673   EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(100)));
2674   EXPECT_FALSE(ret.second);
2675 
2676   auto hint_ret = m.insert_or_assign(ret.first, 3, MovableOnlyInstance(200));
2677   EXPECT_EQ(*hint_ret, value_type(3, MovableOnlyInstance(200)));
2678 
2679   EXPECT_EQ(m.size(), 2);
2680 }
2681 
TEST(Btree,BitfieldArgument)2682 TEST(Btree, BitfieldArgument) {
2683   union {
2684     int n : 1;
2685   };
2686   n = 0;
2687   absl::btree_map<int, int> m;
2688   m.erase(n);
2689   m.count(n);
2690   m.find(n);
2691   m.contains(n);
2692   m.equal_range(n);
2693   m.insert_or_assign(n, n);
2694   m.insert_or_assign(m.end(), n, n);
2695   m.try_emplace(n);
2696   m.try_emplace(m.end(), n);
2697   m.at(n);
2698   m[n];
2699 }
2700 
TEST(Btree,SetRangeConstructorAndInsertSupportExplicitConversionComparable)2701 TEST(Btree, SetRangeConstructorAndInsertSupportExplicitConversionComparable) {
2702   const absl::string_view names[] = {"n1", "n2"};
2703 
2704   absl::btree_set<std::string> name_set1{std::begin(names), std::end(names)};
2705   EXPECT_THAT(name_set1, ElementsAreArray(names));
2706 
2707   absl::btree_set<std::string> name_set2;
2708   name_set2.insert(std::begin(names), std::end(names));
2709   EXPECT_THAT(name_set2, ElementsAreArray(names));
2710 }
2711 
2712 // A type that is explicitly convertible from int and counts constructor calls.
2713 struct ConstructorCounted {
ConstructorCountedabsl::container_internal::__anona1fef86c0411::ConstructorCounted2714   explicit ConstructorCounted(int i) : i(i) { ++constructor_calls; }
operator ==absl::container_internal::__anona1fef86c0411::ConstructorCounted2715   bool operator==(int other) const { return i == other; }
2716 
2717   int i;
2718   static int constructor_calls;
2719 };
2720 int ConstructorCounted::constructor_calls = 0;
2721 
2722 struct ConstructorCountedCompare {
operator ()absl::container_internal::__anona1fef86c0411::ConstructorCountedCompare2723   bool operator()(int a, const ConstructorCounted &b) const { return a < b.i; }
operator ()absl::container_internal::__anona1fef86c0411::ConstructorCountedCompare2724   bool operator()(const ConstructorCounted &a, int b) const { return a.i < b; }
operator ()absl::container_internal::__anona1fef86c0411::ConstructorCountedCompare2725   bool operator()(const ConstructorCounted &a,
2726                   const ConstructorCounted &b) const {
2727     return a.i < b.i;
2728   }
2729   using is_transparent = void;
2730 };
2731 
TEST(Btree,SetRangeConstructorAndInsertExplicitConvComparableLimitConstruction)2732 TEST(Btree,
2733      SetRangeConstructorAndInsertExplicitConvComparableLimitConstruction) {
2734   const int i[] = {0, 1, 1};
2735   ConstructorCounted::constructor_calls = 0;
2736 
2737   absl::btree_set<ConstructorCounted, ConstructorCountedCompare> set{
2738       std::begin(i), std::end(i)};
2739   EXPECT_THAT(set, ElementsAre(0, 1));
2740   EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2741 
2742   set.insert(std::begin(i), std::end(i));
2743   EXPECT_THAT(set, ElementsAre(0, 1));
2744   EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2745 }
2746 
TEST(Btree,SetRangeConstructorAndInsertSupportExplicitConversionNonComparable)2747 TEST(Btree,
2748      SetRangeConstructorAndInsertSupportExplicitConversionNonComparable) {
2749   const int i[] = {0, 1};
2750 
2751   absl::btree_set<std::vector<void *>> s1{std::begin(i), std::end(i)};
2752   EXPECT_THAT(s1, ElementsAre(IsEmpty(), ElementsAre(IsNull())));
2753 
2754   absl::btree_set<std::vector<void *>> s2;
2755   s2.insert(std::begin(i), std::end(i));
2756   EXPECT_THAT(s2, ElementsAre(IsEmpty(), ElementsAre(IsNull())));
2757 }
2758 
2759 // libstdc++ included with GCC 4.9 has a bug in the std::pair constructors that
2760 // prevents explicit conversions between pair types.
2761 // We only run this test for the libstdc++ from GCC 7 or newer because we can't
2762 // reliably check the libstdc++ version prior to that release.
2763 #if !defined(__GLIBCXX__) || \
2764     (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 7)
TEST(Btree,MapRangeConstructorAndInsertSupportExplicitConversionComparable)2765 TEST(Btree, MapRangeConstructorAndInsertSupportExplicitConversionComparable) {
2766   const std::pair<absl::string_view, int> names[] = {{"n1", 1}, {"n2", 2}};
2767 
2768   absl::btree_map<std::string, int> name_map1{std::begin(names),
2769                                               std::end(names)};
2770   EXPECT_THAT(name_map1, ElementsAre(Pair("n1", 1), Pair("n2", 2)));
2771 
2772   absl::btree_map<std::string, int> name_map2;
2773   name_map2.insert(std::begin(names), std::end(names));
2774   EXPECT_THAT(name_map2, ElementsAre(Pair("n1", 1), Pair("n2", 2)));
2775 }
2776 
TEST(Btree,MapRangeConstructorAndInsertExplicitConvComparableLimitConstruction)2777 TEST(Btree,
2778      MapRangeConstructorAndInsertExplicitConvComparableLimitConstruction) {
2779   const std::pair<int, int> i[] = {{0, 1}, {1, 2}, {1, 3}};
2780   ConstructorCounted::constructor_calls = 0;
2781 
2782   absl::btree_map<ConstructorCounted, int, ConstructorCountedCompare> map{
2783       std::begin(i), std::end(i)};
2784   EXPECT_THAT(map, ElementsAre(Pair(0, 1), Pair(1, 2)));
2785   EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2786 
2787   map.insert(std::begin(i), std::end(i));
2788   EXPECT_THAT(map, ElementsAre(Pair(0, 1), Pair(1, 2)));
2789   EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2790 }
2791 
TEST(Btree,MapRangeConstructorAndInsertSupportExplicitConversionNonComparable)2792 TEST(Btree,
2793      MapRangeConstructorAndInsertSupportExplicitConversionNonComparable) {
2794   const std::pair<int, int> i[] = {{0, 1}, {1, 2}};
2795 
2796   absl::btree_map<std::vector<void *>, int> m1{std::begin(i), std::end(i)};
2797   EXPECT_THAT(m1,
2798               ElementsAre(Pair(IsEmpty(), 1), Pair(ElementsAre(IsNull()), 2)));
2799 
2800   absl::btree_map<std::vector<void *>, int> m2;
2801   m2.insert(std::begin(i), std::end(i));
2802   EXPECT_THAT(m2,
2803               ElementsAre(Pair(IsEmpty(), 1), Pair(ElementsAre(IsNull()), 2)));
2804 }
2805 
TEST(Btree,HeterogeneousTryEmplace)2806 TEST(Btree, HeterogeneousTryEmplace) {
2807   absl::btree_map<std::string, int> m;
2808   std::string s = "key";
2809   absl::string_view sv = s;
2810   m.try_emplace(sv, 1);
2811   EXPECT_EQ(m[s], 1);
2812 
2813   m.try_emplace(m.end(), sv, 2);
2814   EXPECT_EQ(m[s], 1);
2815 }
2816 
TEST(Btree,HeterogeneousOperatorMapped)2817 TEST(Btree, HeterogeneousOperatorMapped) {
2818   absl::btree_map<std::string, int> m;
2819   std::string s = "key";
2820   absl::string_view sv = s;
2821   m[sv] = 1;
2822   EXPECT_EQ(m[s], 1);
2823 
2824   m[sv] = 2;
2825   EXPECT_EQ(m[s], 2);
2826 }
2827 
TEST(Btree,HeterogeneousInsertOrAssign)2828 TEST(Btree, HeterogeneousInsertOrAssign) {
2829   absl::btree_map<std::string, int> m;
2830   std::string s = "key";
2831   absl::string_view sv = s;
2832   m.insert_or_assign(sv, 1);
2833   EXPECT_EQ(m[s], 1);
2834 
2835   m.insert_or_assign(m.end(), sv, 2);
2836   EXPECT_EQ(m[s], 2);
2837 }
2838 #endif
2839 
2840 // This test requires std::launder for mutable key access in node handles.
2841 #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
TEST(Btree,NodeHandleMutableKeyAccess)2842 TEST(Btree, NodeHandleMutableKeyAccess) {
2843   {
2844     absl::btree_map<std::string, std::string> map;
2845 
2846     map["key1"] = "mapped";
2847 
2848     auto nh = map.extract(map.begin());
2849     nh.key().resize(3);
2850     map.insert(std::move(nh));
2851 
2852     EXPECT_THAT(map, ElementsAre(Pair("key", "mapped")));
2853   }
2854   // Also for multimap.
2855   {
2856     absl::btree_multimap<std::string, std::string> map;
2857 
2858     map.emplace("key1", "mapped");
2859 
2860     auto nh = map.extract(map.begin());
2861     nh.key().resize(3);
2862     map.insert(std::move(nh));
2863 
2864     EXPECT_THAT(map, ElementsAre(Pair("key", "mapped")));
2865   }
2866 }
2867 #endif
2868 
2869 struct MultiKey {
2870   int i1;
2871   int i2;
2872 };
2873 
operator ==(const MultiKey a,const MultiKey b)2874 bool operator==(const MultiKey a, const MultiKey b) {
2875   return a.i1 == b.i1 && a.i2 == b.i2;
2876 }
2877 
2878 // A heterogeneous comparator that has different equivalence classes for
2879 // different lookup types.
2880 struct MultiKeyComp {
2881   using is_transparent = void;
operator ()absl::container_internal::__anona1fef86c0411::MultiKeyComp2882   bool operator()(const MultiKey a, const MultiKey b) const {
2883     if (a.i1 != b.i1) return a.i1 < b.i1;
2884     return a.i2 < b.i2;
2885   }
operator ()absl::container_internal::__anona1fef86c0411::MultiKeyComp2886   bool operator()(const int a, const MultiKey b) const { return a < b.i1; }
operator ()absl::container_internal::__anona1fef86c0411::MultiKeyComp2887   bool operator()(const MultiKey a, const int b) const { return a.i1 < b; }
2888 };
2889 
2890 // A heterogeneous, three-way comparator that has different equivalence classes
2891 // for different lookup types.
2892 struct MultiKeyThreeWayComp {
2893   using is_transparent = void;
operator ()absl::container_internal::__anona1fef86c0411::MultiKeyThreeWayComp2894   absl::weak_ordering operator()(const MultiKey a, const MultiKey b) const {
2895     if (a.i1 < b.i1) return absl::weak_ordering::less;
2896     if (a.i1 > b.i1) return absl::weak_ordering::greater;
2897     if (a.i2 < b.i2) return absl::weak_ordering::less;
2898     if (a.i2 > b.i2) return absl::weak_ordering::greater;
2899     return absl::weak_ordering::equivalent;
2900   }
operator ()absl::container_internal::__anona1fef86c0411::MultiKeyThreeWayComp2901   absl::weak_ordering operator()(const int a, const MultiKey b) const {
2902     if (a < b.i1) return absl::weak_ordering::less;
2903     if (a > b.i1) return absl::weak_ordering::greater;
2904     return absl::weak_ordering::equivalent;
2905   }
operator ()absl::container_internal::__anona1fef86c0411::MultiKeyThreeWayComp2906   absl::weak_ordering operator()(const MultiKey a, const int b) const {
2907     if (a.i1 < b) return absl::weak_ordering::less;
2908     if (a.i1 > b) return absl::weak_ordering::greater;
2909     return absl::weak_ordering::equivalent;
2910   }
2911 };
2912 
2913 template <typename Compare>
2914 class BtreeMultiKeyTest : public ::testing::Test {};
2915 using MultiKeyComps = ::testing::Types<MultiKeyComp, MultiKeyThreeWayComp>;
2916 TYPED_TEST_SUITE(BtreeMultiKeyTest, MultiKeyComps);
2917 
TYPED_TEST(BtreeMultiKeyTest,EqualRange)2918 TYPED_TEST(BtreeMultiKeyTest, EqualRange) {
2919   absl::btree_set<MultiKey, TypeParam> set;
2920   for (int i = 0; i < 100; ++i) {
2921     for (int j = 0; j < 100; ++j) {
2922       set.insert({i, j});
2923     }
2924   }
2925 
2926   for (int i = 0; i < 100; ++i) {
2927     auto equal_range = set.equal_range(i);
2928     EXPECT_EQ(equal_range.first->i1, i);
2929     EXPECT_EQ(equal_range.first->i2, 0) << i;
2930     EXPECT_EQ(std::distance(equal_range.first, equal_range.second), 100) << i;
2931   }
2932 }
2933 
TYPED_TEST(BtreeMultiKeyTest,Extract)2934 TYPED_TEST(BtreeMultiKeyTest, Extract) {
2935   absl::btree_set<MultiKey, TypeParam> set;
2936   for (int i = 0; i < 100; ++i) {
2937     for (int j = 0; j < 100; ++j) {
2938       set.insert({i, j});
2939     }
2940   }
2941 
2942   for (int i = 0; i < 100; ++i) {
2943     auto node_handle = set.extract(i);
2944     EXPECT_EQ(node_handle.value().i1, i);
2945     EXPECT_EQ(node_handle.value().i2, 0) << i;
2946   }
2947 
2948   for (int i = 0; i < 100; ++i) {
2949     auto node_handle = set.extract(i);
2950     EXPECT_EQ(node_handle.value().i1, i);
2951     EXPECT_EQ(node_handle.value().i2, 1) << i;
2952   }
2953 }
2954 
TYPED_TEST(BtreeMultiKeyTest,Erase)2955 TYPED_TEST(BtreeMultiKeyTest, Erase) {
2956   absl::btree_set<MultiKey, TypeParam> set = {
2957       {1, 1}, {2, 1}, {2, 2}, {3, 1}};
2958   EXPECT_EQ(set.erase(2), 2);
2959   EXPECT_THAT(set, ElementsAre(MultiKey{1, 1}, MultiKey{3, 1}));
2960 }
2961 
TYPED_TEST(BtreeMultiKeyTest,Count)2962 TYPED_TEST(BtreeMultiKeyTest, Count) {
2963   const absl::btree_set<MultiKey, TypeParam> set = {
2964       {1, 1}, {2, 1}, {2, 2}, {3, 1}};
2965   EXPECT_EQ(set.count(2), 2);
2966 }
2967 
TEST(Btree,AllocConstructor)2968 TEST(Btree, AllocConstructor) {
2969   using Alloc = CountingAllocator<int>;
2970   using Set = absl::btree_set<int, std::less<int>, Alloc>;
2971   int64_t bytes_used = 0;
2972   Alloc alloc(&bytes_used);
2973   Set set(alloc);
2974 
2975   set.insert({1, 2, 3});
2976 
2977   EXPECT_THAT(set, ElementsAre(1, 2, 3));
2978   EXPECT_GT(bytes_used, set.size() * sizeof(int));
2979 }
2980 
TEST(Btree,AllocInitializerListConstructor)2981 TEST(Btree, AllocInitializerListConstructor) {
2982   using Alloc = CountingAllocator<int>;
2983   using Set = absl::btree_set<int, std::less<int>, Alloc>;
2984   int64_t bytes_used = 0;
2985   Alloc alloc(&bytes_used);
2986   Set set({1, 2, 3}, alloc);
2987 
2988   EXPECT_THAT(set, ElementsAre(1, 2, 3));
2989   EXPECT_GT(bytes_used, set.size() * sizeof(int));
2990 }
2991 
TEST(Btree,AllocRangeConstructor)2992 TEST(Btree, AllocRangeConstructor) {
2993   using Alloc = CountingAllocator<int>;
2994   using Set = absl::btree_set<int, std::less<int>, Alloc>;
2995   int64_t bytes_used = 0;
2996   Alloc alloc(&bytes_used);
2997   std::vector<int> v = {1, 2, 3};
2998   Set set(v.begin(), v.end(), alloc);
2999 
3000   EXPECT_THAT(set, ElementsAre(1, 2, 3));
3001   EXPECT_GT(bytes_used, set.size() * sizeof(int));
3002 }
3003 
TEST(Btree,AllocCopyConstructor)3004 TEST(Btree, AllocCopyConstructor) {
3005   using Alloc = CountingAllocator<int>;
3006   using Set = absl::btree_set<int, std::less<int>, Alloc>;
3007   int64_t bytes_used1 = 0;
3008   Alloc alloc1(&bytes_used1);
3009   Set set1(alloc1);
3010 
3011   set1.insert({1, 2, 3});
3012 
3013   int64_t bytes_used2 = 0;
3014   Alloc alloc2(&bytes_used2);
3015   Set set2(set1, alloc2);
3016 
3017   EXPECT_THAT(set1, ElementsAre(1, 2, 3));
3018   EXPECT_THAT(set2, ElementsAre(1, 2, 3));
3019   EXPECT_GT(bytes_used1, set1.size() * sizeof(int));
3020   EXPECT_EQ(bytes_used1, bytes_used2);
3021 }
3022 
TEST(Btree,AllocMoveConstructor_SameAlloc)3023 TEST(Btree, AllocMoveConstructor_SameAlloc) {
3024   using Alloc = CountingAllocator<int>;
3025   using Set = absl::btree_set<int, std::less<int>, Alloc>;
3026   int64_t bytes_used = 0;
3027   Alloc alloc(&bytes_used);
3028   Set set1(alloc);
3029 
3030   set1.insert({1, 2, 3});
3031 
3032   const int64_t original_bytes_used = bytes_used;
3033   EXPECT_GT(original_bytes_used, set1.size() * sizeof(int));
3034 
3035   Set set2(std::move(set1), alloc);
3036 
3037   EXPECT_THAT(set2, ElementsAre(1, 2, 3));
3038   EXPECT_EQ(bytes_used, original_bytes_used);
3039 }
3040 
TEST(Btree,AllocMoveConstructor_DifferentAlloc)3041 TEST(Btree, AllocMoveConstructor_DifferentAlloc) {
3042   using Alloc = CountingAllocator<int>;
3043   using Set = absl::btree_set<int, std::less<int>, Alloc>;
3044   int64_t bytes_used1 = 0;
3045   Alloc alloc1(&bytes_used1);
3046   Set set1(alloc1);
3047 
3048   set1.insert({1, 2, 3});
3049 
3050   const int64_t original_bytes_used = bytes_used1;
3051   EXPECT_GT(original_bytes_used, set1.size() * sizeof(int));
3052 
3053   int64_t bytes_used2 = 0;
3054   Alloc alloc2(&bytes_used2);
3055   Set set2(std::move(set1), alloc2);
3056 
3057   EXPECT_THAT(set2, ElementsAre(1, 2, 3));
3058   // We didn't free these bytes allocated by `set1` yet.
3059   EXPECT_EQ(bytes_used1, original_bytes_used);
3060   EXPECT_EQ(bytes_used2, original_bytes_used);
3061 }
3062 
IntCmp(const int a,const int b)3063 bool IntCmp(const int a, const int b) { return a < b; }
3064 
TEST(Btree,SupportsFunctionPtrComparator)3065 TEST(Btree, SupportsFunctionPtrComparator) {
3066   absl::btree_set<int, decltype(IntCmp) *> set(IntCmp);
3067   set.insert({1, 2, 3});
3068   EXPECT_THAT(set, ElementsAre(1, 2, 3));
3069   EXPECT_TRUE(set.key_comp()(1, 2));
3070   EXPECT_TRUE(set.value_comp()(1, 2));
3071 
3072   absl::btree_map<int, int, decltype(IntCmp) *> map(&IntCmp);
3073   map[1] = 1;
3074   EXPECT_THAT(map, ElementsAre(Pair(1, 1)));
3075   EXPECT_TRUE(map.key_comp()(1, 2));
3076   EXPECT_TRUE(map.value_comp()(std::make_pair(1, 1), std::make_pair(2, 2)));
3077 }
3078 
3079 template <typename Compare>
3080 struct TransparentPassThroughComp {
3081   using is_transparent = void;
3082 
3083   // This will fail compilation if we attempt a comparison that Compare does not
3084   // support, and the failure will happen inside the function implementation so
3085   // it can't be avoided by using SFINAE on this comparator.
3086   template <typename T, typename U>
operator ()absl::container_internal::__anona1fef86c0411::TransparentPassThroughComp3087   bool operator()(const T &lhs, const U &rhs) const {
3088     return Compare()(lhs, rhs);
3089   }
3090 };
3091 
TEST(Btree,SupportsTransparentComparatorThatDoesNotImplementAllVisibleOperators)3092 TEST(Btree,
3093      SupportsTransparentComparatorThatDoesNotImplementAllVisibleOperators) {
3094   absl::btree_set<MultiKey, TransparentPassThroughComp<MultiKeyComp>> set;
3095   set.insert(MultiKey{1, 2});
3096   EXPECT_TRUE(set.contains(1));
3097 }
3098 
TEST(Btree,ConstructImplicitlyWithUnadaptedComparator)3099 TEST(Btree, ConstructImplicitlyWithUnadaptedComparator) {
3100   absl::btree_set<MultiKey, MultiKeyComp> set = {{}, MultiKeyComp{}};
3101 }
3102 
TEST(Btree,InvalidComparatorsCaught)3103 TEST(Btree, InvalidComparatorsCaught) {
3104   if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
3105 
3106   {
3107     struct ZeroAlwaysLessCmp {
3108       bool operator()(int lhs, int rhs) const {
3109         if (lhs == 0) return true;
3110         return lhs < rhs;
3111       }
3112     };
3113     absl::btree_set<int, ZeroAlwaysLessCmp> set;
3114     EXPECT_DEATH(set.insert({0, 1, 2}), "is_self_equivalent");
3115   }
3116   {
3117     struct ThreeWayAlwaysLessCmp {
3118       absl::weak_ordering operator()(int, int) const {
3119         return absl::weak_ordering::less;
3120       }
3121     };
3122     absl::btree_set<int, ThreeWayAlwaysLessCmp> set;
3123     EXPECT_DEATH(set.insert({0, 1, 2}), "is_self_equivalent");
3124   }
3125   {
3126     struct SumGreaterZeroCmp {
3127       bool operator()(int lhs, int rhs) const {
3128         // First, do equivalence correctly - so we can test later condition.
3129         if (lhs == rhs) return false;
3130         return lhs + rhs > 0;
3131       }
3132     };
3133     absl::btree_set<int, SumGreaterZeroCmp> set;
3134     // Note: '!' only needs to be escaped when it's the first character.
3135     EXPECT_DEATH(set.insert({0, 1, 2}),
3136                  R"regex(\!lhs_comp_rhs \|\| !comp\(\)\(rhs, lhs\))regex");
3137   }
3138   {
3139     struct ThreeWaySumGreaterZeroCmp {
3140       absl::weak_ordering operator()(int lhs, int rhs) const {
3141         // First, do equivalence correctly - so we can test later condition.
3142         if (lhs == rhs) return absl::weak_ordering::equivalent;
3143 
3144         if (lhs + rhs > 0) return absl::weak_ordering::less;
3145         if (lhs + rhs == 0) return absl::weak_ordering::equivalent;
3146         return absl::weak_ordering::greater;
3147       }
3148     };
3149     absl::btree_set<int, ThreeWaySumGreaterZeroCmp> set;
3150     EXPECT_DEATH(set.insert({0, 1, 2}), "lhs_comp_rhs < 0 -> rhs_comp_lhs > 0");
3151   }
3152   // Verify that we detect cases of comparators that violate transitivity.
3153   // When the comparators below check for the presence of an optional field,
3154   // they violate transitivity because instances that have the optional field
3155   // compare differently with each other from how they compare with instances
3156   // that don't have the optional field.
3157   struct ClockTime {
3158     absl::optional<int> hour;
3159     int minute;
3160   };
3161   // `comp(a,b) && comp(b,c) && !comp(a,c)` violates transitivity.
3162   ClockTime a = {absl::nullopt, 1};
3163   ClockTime b = {2, 5};
3164   ClockTime c = {6, 0};
3165   {
3166     struct NonTransitiveTimeCmp {
3167       bool operator()(ClockTime lhs, ClockTime rhs) const {
3168         if (lhs.hour.has_value() && rhs.hour.has_value() &&
3169             *lhs.hour != *rhs.hour) {
3170           return *lhs.hour < *rhs.hour;
3171         }
3172         return lhs.minute < rhs.minute;
3173       }
3174     };
3175     NonTransitiveTimeCmp cmp;
3176     ASSERT_TRUE(cmp(a, b) && cmp(b, c) && !cmp(a, c));
3177     absl::btree_set<ClockTime, NonTransitiveTimeCmp> set;
3178     EXPECT_DEATH(set.insert({a, b, c}), "is_ordered_correctly");
3179     absl::btree_multiset<ClockTime, NonTransitiveTimeCmp> mset;
3180     EXPECT_DEATH(mset.insert({a, a, b, b, c, c}), "is_ordered_correctly");
3181   }
3182   {
3183     struct ThreeWayNonTransitiveTimeCmp {
3184       absl::weak_ordering operator()(ClockTime lhs, ClockTime rhs) const {
3185         if (lhs.hour.has_value() && rhs.hour.has_value() &&
3186             *lhs.hour != *rhs.hour) {
3187           return *lhs.hour < *rhs.hour ? absl::weak_ordering::less
3188                                        : absl::weak_ordering::greater;
3189         }
3190         return lhs.minute < rhs.minute    ? absl::weak_ordering::less
3191                : lhs.minute == rhs.minute ? absl::weak_ordering::equivalent
3192                                           : absl::weak_ordering::greater;
3193       }
3194     };
3195     ThreeWayNonTransitiveTimeCmp cmp;
3196     ASSERT_TRUE(cmp(a, b) < 0 && cmp(b, c) < 0 && cmp(a, c) > 0);
3197     absl::btree_set<ClockTime, ThreeWayNonTransitiveTimeCmp> set;
3198     EXPECT_DEATH(set.insert({a, b, c}), "is_ordered_correctly");
3199     absl::btree_multiset<ClockTime, ThreeWayNonTransitiveTimeCmp> mset;
3200     EXPECT_DEATH(mset.insert({a, a, b, b, c, c}), "is_ordered_correctly");
3201   }
3202 }
3203 
TEST(Btree,MutatedKeysCaught)3204 TEST(Btree, MutatedKeysCaught) {
3205   if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
3206 
3207   struct IntPtrCmp {
3208     bool operator()(int *lhs, int *rhs) const { return *lhs < *rhs; }
3209   };
3210   {
3211     absl::btree_set<int *, IntPtrCmp> set;
3212     int arr[] = {0, 1, 2};
3213     set.insert({&arr[0], &arr[1], &arr[2]});
3214     arr[0] = 100;
3215     EXPECT_DEATH(set.insert(&arr[0]), "is_ordered_correctly");
3216   }
3217   {
3218     absl::btree_multiset<int *, IntPtrCmp> set;
3219     int arr[] = {0, 1, 2};
3220     set.insert({&arr[0], &arr[0], &arr[1], &arr[1], &arr[2], &arr[2]});
3221     arr[0] = 100;
3222     EXPECT_DEATH(set.insert(&arr[0]), "is_ordered_correctly");
3223   }
3224 }
3225 
3226 #ifndef _MSC_VER
3227 // This test crashes on MSVC.
TEST(Btree,InvalidIteratorUse)3228 TEST(Btree, InvalidIteratorUse) {
3229   if (!BtreeGenerationsEnabled())
3230     GTEST_SKIP() << "Generation validation for iterators is disabled.";
3231 
3232   // Invalid memory use can trigger heap-use-after-free in ASan or invalidated
3233   // iterator assertions.
3234   constexpr const char *kInvalidMemoryDeathMessage =
3235       "heap-use-after-free|invalidated iterator";
3236 
3237   {
3238     absl::btree_set<int> set;
3239     for (int i = 0; i < 10; ++i) set.insert(i);
3240     auto it = set.begin();
3241     set.erase(it++);
3242     EXPECT_DEATH(set.erase(it++), kInvalidMemoryDeathMessage);
3243   }
3244   {
3245     absl::btree_set<int> set;
3246     for (int i = 0; i < 10; ++i) set.insert(i);
3247     auto it = set.insert(20).first;
3248     set.insert(30);
3249     EXPECT_DEATH(*it, kInvalidMemoryDeathMessage);
3250   }
3251   {
3252     absl::btree_set<int> set;
3253     for (int i = 0; i < 10000; ++i) set.insert(i);
3254     auto it = set.find(5000);
3255     ASSERT_NE(it, set.end());
3256     set.erase(1);
3257     EXPECT_DEATH(*it, kInvalidMemoryDeathMessage);
3258   }
3259   {
3260     absl::btree_set<int> set;
3261     for (int i = 0; i < 10; ++i) set.insert(i);
3262     auto it = set.insert(20).first;
3263     set.insert(30);
3264     EXPECT_DEATH(void(it == set.begin()), kInvalidMemoryDeathMessage);
3265     EXPECT_DEATH(void(set.begin() == it), kInvalidMemoryDeathMessage);
3266   }
3267 }
3268 #endif
3269 
3270 class OnlyConstructibleByAllocator {
OnlyConstructibleByAllocator(int i)3271   explicit OnlyConstructibleByAllocator(int i) : i_(i) {}
3272 
3273  public:
OnlyConstructibleByAllocator(const OnlyConstructibleByAllocator & other)3274   OnlyConstructibleByAllocator(const OnlyConstructibleByAllocator &other)
3275       : i_(other.i_) {}
operator =(const OnlyConstructibleByAllocator & other)3276   OnlyConstructibleByAllocator &operator=(
3277       const OnlyConstructibleByAllocator &other) {
3278     i_ = other.i_;
3279     return *this;
3280   }
Get() const3281   int Get() const { return i_; }
operator ==(int i) const3282   bool operator==(int i) const { return i_ == i; }
3283 
3284  private:
3285   template <typename T>
3286   friend class OnlyConstructibleAllocator;
3287 
3288   int i_;
3289 };
3290 
3291 template <typename T = OnlyConstructibleByAllocator>
3292 class OnlyConstructibleAllocator : public std::allocator<T> {
3293  public:
3294   OnlyConstructibleAllocator() = default;
3295   template <class U>
OnlyConstructibleAllocator(const OnlyConstructibleAllocator<U> &)3296   explicit OnlyConstructibleAllocator(const OnlyConstructibleAllocator<U> &) {}
3297 
construct(OnlyConstructibleByAllocator * p,int i)3298   void construct(OnlyConstructibleByAllocator *p, int i) {
3299     new (p) OnlyConstructibleByAllocator(i);
3300   }
3301   template <typename Pair>
construct(Pair * p,const int i)3302   void construct(Pair *p, const int i) {
3303     OnlyConstructibleByAllocator only(i);
3304     new (p) Pair(std::move(only), i);
3305   }
3306 
3307   template <class U>
3308   struct rebind {
3309     using other = OnlyConstructibleAllocator<U>;
3310   };
3311 };
3312 
3313 struct OnlyConstructibleByAllocatorComp {
3314   using is_transparent = void;
operator ()absl::container_internal::__anona1fef86c0411::OnlyConstructibleByAllocatorComp3315   bool operator()(OnlyConstructibleByAllocator a,
3316                   OnlyConstructibleByAllocator b) const {
3317     return a.Get() < b.Get();
3318   }
operator ()absl::container_internal::__anona1fef86c0411::OnlyConstructibleByAllocatorComp3319   bool operator()(int a, OnlyConstructibleByAllocator b) const {
3320     return a < b.Get();
3321   }
operator ()absl::container_internal::__anona1fef86c0411::OnlyConstructibleByAllocatorComp3322   bool operator()(OnlyConstructibleByAllocator a, int b) const {
3323     return a.Get() < b;
3324   }
3325 };
3326 
TEST(Btree,OnlyConstructibleByAllocatorType)3327 TEST(Btree, OnlyConstructibleByAllocatorType) {
3328   const std::array<int, 2> arr = {3, 4};
3329   {
3330     absl::btree_set<OnlyConstructibleByAllocator,
3331                     OnlyConstructibleByAllocatorComp,
3332                     OnlyConstructibleAllocator<>>
3333         set;
3334     set.emplace(1);
3335     set.emplace_hint(set.end(), 2);
3336     set.insert(arr.begin(), arr.end());
3337     EXPECT_THAT(set, ElementsAre(1, 2, 3, 4));
3338   }
3339   {
3340     absl::btree_multiset<OnlyConstructibleByAllocator,
3341                          OnlyConstructibleByAllocatorComp,
3342                          OnlyConstructibleAllocator<>>
3343         set;
3344     set.emplace(1);
3345     set.emplace_hint(set.end(), 2);
3346     // TODO(ezb): fix insert_multi to allow this to compile.
3347     // set.insert(arr.begin(), arr.end());
3348     EXPECT_THAT(set, ElementsAre(1, 2));
3349   }
3350   {
3351     absl::btree_map<OnlyConstructibleByAllocator, int,
3352                     OnlyConstructibleByAllocatorComp,
3353                     OnlyConstructibleAllocator<>>
3354         map;
3355     map.emplace(1);
3356     map.emplace_hint(map.end(), 2);
3357     map.insert(arr.begin(), arr.end());
3358     EXPECT_THAT(map,
3359                 ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3), Pair(4, 4)));
3360   }
3361   {
3362     absl::btree_multimap<OnlyConstructibleByAllocator, int,
3363                          OnlyConstructibleByAllocatorComp,
3364                          OnlyConstructibleAllocator<>>
3365         map;
3366     map.emplace(1);
3367     map.emplace_hint(map.end(), 2);
3368     // TODO(ezb): fix insert_multi to allow this to compile.
3369     // map.insert(arr.begin(), arr.end());
3370     EXPECT_THAT(map, ElementsAre(Pair(1, 1), Pair(2, 2)));
3371   }
3372 }
3373 
3374 class NotAssignable {
3375  public:
NotAssignable(int i)3376   explicit NotAssignable(int i) : i_(i) {}
NotAssignable(const NotAssignable & other)3377   NotAssignable(const NotAssignable &other) : i_(other.i_) {}
3378   NotAssignable &operator=(NotAssignable &&other) = delete;
Get() const3379   int Get() const { return i_; }
operator ==(int i) const3380   bool operator==(int i) const { return i_ == i; }
operator <(NotAssignable a,NotAssignable b)3381   friend bool operator<(NotAssignable a, NotAssignable b) {
3382     return a.i_ < b.i_;
3383   }
3384 
3385  private:
3386   int i_;
3387 };
3388 
TEST(Btree,NotAssignableType)3389 TEST(Btree, NotAssignableType) {
3390   {
3391     absl::btree_set<NotAssignable> set;
3392     set.emplace(1);
3393     set.emplace_hint(set.end(), 2);
3394     set.insert(NotAssignable(3));
3395     set.insert(set.end(), NotAssignable(4));
3396     EXPECT_THAT(set, ElementsAre(1, 2, 3, 4));
3397     set.erase(set.begin());
3398     EXPECT_THAT(set, ElementsAre(2, 3, 4));
3399   }
3400   {
3401     absl::btree_multiset<NotAssignable> set;
3402     set.emplace(1);
3403     set.emplace_hint(set.end(), 2);
3404     set.insert(NotAssignable(2));
3405     set.insert(set.end(), NotAssignable(3));
3406     EXPECT_THAT(set, ElementsAre(1, 2, 2, 3));
3407     set.erase(set.begin());
3408     EXPECT_THAT(set, ElementsAre(2, 2, 3));
3409   }
3410   {
3411     absl::btree_map<NotAssignable, int> map;
3412     map.emplace(NotAssignable(1), 1);
3413     map.emplace_hint(map.end(), NotAssignable(2), 2);
3414     map.insert({NotAssignable(3), 3});
3415     map.insert(map.end(), {NotAssignable(4), 4});
3416     EXPECT_THAT(map,
3417                 ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3), Pair(4, 4)));
3418     map.erase(map.begin());
3419     EXPECT_THAT(map, ElementsAre(Pair(2, 2), Pair(3, 3), Pair(4, 4)));
3420   }
3421   {
3422     absl::btree_multimap<NotAssignable, int> map;
3423     map.emplace(NotAssignable(1), 1);
3424     map.emplace_hint(map.end(), NotAssignable(2), 2);
3425     map.insert({NotAssignable(2), 3});
3426     map.insert(map.end(), {NotAssignable(3), 3});
3427     EXPECT_THAT(map,
3428                 ElementsAre(Pair(1, 1), Pair(2, 2), Pair(2, 3), Pair(3, 3)));
3429     map.erase(map.begin());
3430     EXPECT_THAT(map, ElementsAre(Pair(2, 2), Pair(2, 3), Pair(3, 3)));
3431   }
3432 }
3433 
3434 struct ArenaLike {
3435   void* recycled = nullptr;
3436   size_t recycled_size = 0;
3437 };
3438 
3439 // A very simple implementation of arena allocation.
3440 template <typename T>
3441 class ArenaLikeAllocator : public std::allocator<T> {
3442  public:
3443   // Standard library containers require the ability to allocate objects of
3444   // different types which they can do so via rebind.other.
3445   template <typename U>
3446   struct rebind {
3447     using other = ArenaLikeAllocator<U>;
3448   };
3449 
ArenaLikeAllocator(ArenaLike * arena)3450   explicit ArenaLikeAllocator(ArenaLike* arena) noexcept : arena_(arena) {}
3451 
~ArenaLikeAllocator()3452   ~ArenaLikeAllocator() {
3453     if (arena_->recycled != nullptr) {
3454       delete [] static_cast<T*>(arena_->recycled);
3455       arena_->recycled = nullptr;
3456     }
3457   }
3458 
3459   template<typename U>
ArenaLikeAllocator(const ArenaLikeAllocator<U> & other)3460   explicit ArenaLikeAllocator(const ArenaLikeAllocator<U>& other) noexcept
3461       : arena_(other.arena_) {}
3462 
allocate(size_t num_objects,const void * =nullptr)3463   T* allocate(size_t num_objects, const void* = nullptr) {
3464     size_t size = num_objects * sizeof(T);
3465     if (arena_->recycled != nullptr && arena_->recycled_size == size) {
3466       T* result = static_cast<T*>(arena_->recycled);
3467       arena_->recycled = nullptr;
3468       return result;
3469     }
3470     return new T[num_objects];
3471   }
3472 
deallocate(T * p,size_t num_objects)3473   void deallocate(T* p, size_t num_objects) {
3474     size_t size = num_objects * sizeof(T);
3475 
3476     // Simulate writing to the freed memory as an actual arena allocator might
3477     // do. This triggers an error report if the memory is poisoned.
3478     memset(p, 0xde, size);
3479 
3480     if (arena_->recycled == nullptr) {
3481       arena_->recycled = p;
3482       arena_->recycled_size = size;
3483     } else {
3484       delete [] p;
3485     }
3486   }
3487 
3488   ArenaLike* arena_;
3489 };
3490 
3491 // This test verifies that an arena allocator that reuses memory will not be
3492 // asked to free poisoned BTree memory.
TEST(Btree,ReusePoisonMemory)3493 TEST(Btree, ReusePoisonMemory) {
3494   using Alloc = ArenaLikeAllocator<int64_t>;
3495   using Set = absl::btree_set<int64_t, std::less<int64_t>, Alloc>;
3496   ArenaLike arena;
3497   Alloc alloc(&arena);
3498   Set set(alloc);
3499 
3500   set.insert(0);
3501   set.erase(0);
3502   set.insert(0);
3503 }
3504 
TEST(Btree,IteratorSubtraction)3505 TEST(Btree, IteratorSubtraction) {
3506   absl::BitGen bitgen;
3507   std::vector<int> vec;
3508   // Randomize the set's insertion order so the nodes aren't all full.
3509   for (int i = 0; i < 1000000; ++i) vec.push_back(i);
3510   absl::c_shuffle(vec, bitgen);
3511 
3512   absl::btree_set<int> set;
3513   for (int i : vec) set.insert(i);
3514 
3515   for (int i = 0; i < 1000; ++i) {
3516     size_t begin = absl::Uniform(bitgen, 0u, set.size());
3517     size_t end = absl::Uniform(bitgen, begin, set.size());
3518     ASSERT_EQ(end - begin, set.find(end) - set.find(begin))
3519         << begin << " " << end;
3520   }
3521 }
3522 
TEST(Btree,DereferencingEndIterator)3523 TEST(Btree, DereferencingEndIterator) {
3524   if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
3525 
3526   absl::btree_set<int> set;
3527   for (int i = 0; i < 1000; ++i) set.insert(i);
3528   EXPECT_DEATH(*set.end(), R"regex(Dereferencing end\(\) iterator)regex");
3529 }
3530 
TEST(Btree,InvalidIteratorComparison)3531 TEST(Btree, InvalidIteratorComparison) {
3532   if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
3533 
3534   absl::btree_set<int> set1, set2;
3535   for (int i = 0; i < 1000; ++i) {
3536     set1.insert(i);
3537     set2.insert(i);
3538   }
3539 
3540   constexpr const char *kValueInitDeathMessage =
3541       "Comparing default-constructed iterator with .*non-default-constructed "
3542       "iterator";
3543   typename absl::btree_set<int>::iterator iter1, iter2;
3544   EXPECT_EQ(iter1, iter2);
3545   EXPECT_DEATH(void(set1.begin() == iter1), kValueInitDeathMessage);
3546   EXPECT_DEATH(void(iter1 == set1.begin()), kValueInitDeathMessage);
3547 
3548   constexpr const char *kDifferentContainerDeathMessage =
3549       "Comparing iterators from different containers";
3550   iter1 = set1.begin();
3551   iter2 = set2.begin();
3552   EXPECT_DEATH(void(iter1 == iter2), kDifferentContainerDeathMessage);
3553   EXPECT_DEATH(void(iter2 == iter1), kDifferentContainerDeathMessage);
3554 }
3555 
TEST(Btree,InvalidPointerUse)3556 TEST(Btree, InvalidPointerUse) {
3557   if (!kAsan)
3558     GTEST_SKIP() << "We only detect invalid pointer use in ASan mode.";
3559 
3560   absl::btree_set<int> set;
3561   set.insert(0);
3562   const int *ptr = &*set.begin();
3563   set.insert(1);
3564   EXPECT_DEATH(std::cout << *ptr, "heap-use-after-free");
3565   size_t slots_per_node = BtreeNodePeer::GetNumSlotsPerNode<decltype(set)>();
3566   for (int i = 2; i < slots_per_node - 1; ++i) set.insert(i);
3567   ptr = &*set.begin();
3568   set.insert(static_cast<int>(slots_per_node));
3569   EXPECT_DEATH(std::cout << *ptr, "heap-use-after-free");
3570 }
3571 
3572 template<typename Set>
TestBasicFunctionality(Set set)3573 void TestBasicFunctionality(Set set) {
3574   using value_type = typename Set::value_type;
3575   for (int i = 0; i < 100; ++i) { set.insert(value_type(i)); }
3576   for (int i = 50; i < 100; ++i) { set.erase(value_type(i)); }
3577   auto it = set.begin();
3578   for (int i = 0; i < 50; ++i, ++it) {
3579     ASSERT_EQ(set.find(value_type(i)), it) << i;
3580   }
3581 }
3582 
3583 template<size_t align>
3584 struct alignas(align) OveralignedKey {
OveralignedKeyabsl::container_internal::__anona1fef86c0411::OveralignedKey3585   explicit OveralignedKey(int i) : key(i) {}
operator <absl::container_internal::__anona1fef86c0411::OveralignedKey3586   bool operator<(const OveralignedKey &other) const { return key < other.key; }
3587   int key = 0;
3588 };
3589 
TEST(Btree,OveralignedKey)3590 TEST(Btree, OveralignedKey) {
3591   // Test basic functionality with both even and odd numbers of slots per node.
3592   // The goal here is to detect cases where alignment may be incorrect.
3593   TestBasicFunctionality(
3594       SizedBtreeSet<OveralignedKey<16>, /*TargetValuesPerNode=*/8>());
3595   TestBasicFunctionality(
3596       SizedBtreeSet<OveralignedKey<16>, /*TargetValuesPerNode=*/9>());
3597 }
3598 
TEST(Btree,FieldTypeEqualsSlotType)3599 TEST(Btree, FieldTypeEqualsSlotType) {
3600   // This breaks if we try to do layout_type::Pointer<slot_type> because
3601   // slot_type is the same as field_type.
3602   using set_type = absl::btree_set<uint8_t>;
3603   static_assert(BtreeNodePeer::FieldTypeEqualsSlotType<set_type>(), "");
3604   TestBasicFunctionality(set_type());
3605 }
3606 
3607 }  // namespace
3608 }  // namespace container_internal
3609 ABSL_NAMESPACE_END
3610 }  // namespace absl
3611