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