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