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