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


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:50