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