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