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