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::__anon7e8713fe0211::CompareIntToString746 bool operator()(const std::string &a, const std::string &b) const {
747 return a < b;
748 }
operator ()absl::container_internal::__anon7e8713fe0211::CompareIntToString749 bool operator()(const std::string &a, int b) const {
750 return a < absl::StrCat(b);
751 }
operator ()absl::container_internal::__anon7e8713fe0211::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::__anon7e8713fe0211::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::__anon7e8713fe0211::SubstringLess953 explicit SubstringLess(int length) : n(length) {}
operator ()absl::container_internal::__anon7e8713fe0211::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::__anon7e8713fe0311::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::__anon7e8713fe0311::CheckedCompareOptedOutCmp1316 CheckedCompareOptedOutCmp() {}
CheckedCompareOptedOutCmpabsl::container_internal::__anon7e8713fe0311::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 #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
1350 defined(ABSL_HAVE_HWADDRESS_SANITIZER)
1351 constexpr bool kAsan = true;
1352 #else
1353 constexpr bool kAsan = false;
1354 #endif
1355
1356 // Note: when the values in this test change, it is expected to have an impact
1357 // on performance.
TEST(Btree,MovesComparisonsCopiesSwapsTracking)1358 TEST(Btree, MovesComparisonsCopiesSwapsTracking) {
1359 if (kAsan) GTEST_SKIP() << "We do extra operations in ASan mode.";
1360
1361 InstanceTracker tracker;
1362 // Note: this is minimum number of values per node.
1363 SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/4> set4;
1364 // Note: this is the default number of values per node for a set of int32s
1365 // (with 64-bit pointers).
1366 SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/61> set61;
1367 SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/100> set100;
1368
1369 // Don't depend on flags for random values because then the expectations will
1370 // fail if the flags change.
1371 std::vector<int> values =
1372 GenerateValuesWithSeed<int>(10000, 1 << 22, /*seed=*/23);
1373
1374 EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set4)>(), 4);
1375 EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set61)>(), 61);
1376 EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set100)>(), 100);
1377 if (sizeof(void *) == 8) {
1378 EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t>>(),
1379 // When we have generations, there is one fewer slot.
1380 BtreeGenerationsEnabled() ? 60 : 61);
1381 }
1382
1383 // Test key insertion/deletion in random order.
1384 ExpectOperationCounts(56540, 134212, values, &tracker, &set4);
1385 ExpectOperationCounts(386718, 129807, values, &tracker, &set61);
1386 ExpectOperationCounts(586761, 130310, values, &tracker, &set100);
1387
1388 // Test key insertion/deletion in sorted order.
1389 std::sort(values.begin(), values.end());
1390 ExpectOperationCounts(24972, 85563, values, &tracker, &set4);
1391 ExpectOperationCounts(20208, 87757, values, &tracker, &set61);
1392 ExpectOperationCounts(20124, 96583, values, &tracker, &set100);
1393
1394 // Test key insertion/deletion in reverse sorted order.
1395 std::reverse(values.begin(), values.end());
1396 ExpectOperationCounts(54949, 127531, values, &tracker, &set4);
1397 ExpectOperationCounts(338813, 118266, values, &tracker, &set61);
1398 ExpectOperationCounts(534529, 125279, values, &tracker, &set100);
1399 }
1400
1401 struct MovableOnlyInstanceThreeWayCompare {
operator ()absl::container_internal::__anon7e8713fe0311::MovableOnlyInstanceThreeWayCompare1402 absl::weak_ordering operator()(const MovableOnlyInstance &a,
1403 const MovableOnlyInstance &b) const {
1404 return a.compare(b);
1405 }
1406 };
1407
1408 // Note: when the values in this test change, it is expected to have an impact
1409 // on performance.
TEST(Btree,MovesComparisonsCopiesSwapsTrackingThreeWayCompare)1410 TEST(Btree, MovesComparisonsCopiesSwapsTrackingThreeWayCompare) {
1411 if (kAsan) GTEST_SKIP() << "We do extra operations in ASan mode.";
1412
1413 InstanceTracker tracker;
1414 // Note: this is minimum number of values per node.
1415 SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/4,
1416 MovableOnlyInstanceThreeWayCompare>
1417 set4;
1418 // Note: this is the default number of values per node for a set of int32s
1419 // (with 64-bit pointers).
1420 SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/61,
1421 MovableOnlyInstanceThreeWayCompare>
1422 set61;
1423 SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/100,
1424 MovableOnlyInstanceThreeWayCompare>
1425 set100;
1426
1427 // Don't depend on flags for random values because then the expectations will
1428 // fail if the flags change.
1429 std::vector<int> values =
1430 GenerateValuesWithSeed<int>(10000, 1 << 22, /*seed=*/23);
1431
1432 EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set4)>(), 4);
1433 EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set61)>(), 61);
1434 EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set100)>(), 100);
1435 if (sizeof(void *) == 8) {
1436 EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t>>(),
1437 // When we have generations, there is one fewer slot.
1438 BtreeGenerationsEnabled() ? 60 : 61);
1439 }
1440
1441 // Test key insertion/deletion in random order.
1442 ExpectOperationCounts(56540, 124221, values, &tracker, &set4);
1443 ExpectOperationCounts(386718, 119816, values, &tracker, &set61);
1444 ExpectOperationCounts(586761, 120319, values, &tracker, &set100);
1445
1446 // Test key insertion/deletion in sorted order.
1447 std::sort(values.begin(), values.end());
1448 ExpectOperationCounts(24972, 85563, values, &tracker, &set4);
1449 ExpectOperationCounts(20208, 87757, values, &tracker, &set61);
1450 ExpectOperationCounts(20124, 96583, values, &tracker, &set100);
1451
1452 // Test key insertion/deletion in reverse sorted order.
1453 std::reverse(values.begin(), values.end());
1454 ExpectOperationCounts(54949, 117532, values, &tracker, &set4);
1455 ExpectOperationCounts(338813, 108267, values, &tracker, &set61);
1456 ExpectOperationCounts(534529, 115280, values, &tracker, &set100);
1457 }
1458
1459 struct NoDefaultCtor {
1460 int num;
NoDefaultCtorabsl::container_internal::__anon7e8713fe0311::NoDefaultCtor1461 explicit NoDefaultCtor(int i) : num(i) {}
1462
operator <(const NoDefaultCtor & a,const NoDefaultCtor & b)1463 friend bool operator<(const NoDefaultCtor &a, const NoDefaultCtor &b) {
1464 return a.num < b.num;
1465 }
1466 };
1467
TEST(Btree,BtreeMapCanHoldNoDefaultCtorTypes)1468 TEST(Btree, BtreeMapCanHoldNoDefaultCtorTypes) {
1469 absl::btree_map<NoDefaultCtor, NoDefaultCtor> m;
1470
1471 for (int i = 1; i <= 99; ++i) {
1472 SCOPED_TRACE(i);
1473 EXPECT_TRUE(m.emplace(NoDefaultCtor(i), NoDefaultCtor(100 - i)).second);
1474 }
1475 EXPECT_FALSE(m.emplace(NoDefaultCtor(78), NoDefaultCtor(0)).second);
1476
1477 auto iter99 = m.find(NoDefaultCtor(99));
1478 ASSERT_NE(iter99, m.end());
1479 EXPECT_EQ(iter99->second.num, 1);
1480
1481 auto iter1 = m.find(NoDefaultCtor(1));
1482 ASSERT_NE(iter1, m.end());
1483 EXPECT_EQ(iter1->second.num, 99);
1484
1485 auto iter50 = m.find(NoDefaultCtor(50));
1486 ASSERT_NE(iter50, m.end());
1487 EXPECT_EQ(iter50->second.num, 50);
1488
1489 auto iter25 = m.find(NoDefaultCtor(25));
1490 ASSERT_NE(iter25, m.end());
1491 EXPECT_EQ(iter25->second.num, 75);
1492 }
1493
TEST(Btree,BtreeMultimapCanHoldNoDefaultCtorTypes)1494 TEST(Btree, BtreeMultimapCanHoldNoDefaultCtorTypes) {
1495 absl::btree_multimap<NoDefaultCtor, NoDefaultCtor> m;
1496
1497 for (int i = 1; i <= 99; ++i) {
1498 SCOPED_TRACE(i);
1499 m.emplace(NoDefaultCtor(i), NoDefaultCtor(100 - i));
1500 }
1501
1502 auto iter99 = m.find(NoDefaultCtor(99));
1503 ASSERT_NE(iter99, m.end());
1504 EXPECT_EQ(iter99->second.num, 1);
1505
1506 auto iter1 = m.find(NoDefaultCtor(1));
1507 ASSERT_NE(iter1, m.end());
1508 EXPECT_EQ(iter1->second.num, 99);
1509
1510 auto iter50 = m.find(NoDefaultCtor(50));
1511 ASSERT_NE(iter50, m.end());
1512 EXPECT_EQ(iter50->second.num, 50);
1513
1514 auto iter25 = m.find(NoDefaultCtor(25));
1515 ASSERT_NE(iter25, m.end());
1516 EXPECT_EQ(iter25->second.num, 75);
1517 }
1518
TEST(Btree,MapAt)1519 TEST(Btree, MapAt) {
1520 absl::btree_map<int, int> map = {{1, 2}, {2, 4}};
1521 EXPECT_EQ(map.at(1), 2);
1522 EXPECT_EQ(map.at(2), 4);
1523 map.at(2) = 8;
1524 const absl::btree_map<int, int> &const_map = map;
1525 EXPECT_EQ(const_map.at(1), 2);
1526 EXPECT_EQ(const_map.at(2), 8);
1527 #ifdef ABSL_HAVE_EXCEPTIONS
1528 EXPECT_THROW(map.at(3), std::out_of_range);
1529 #else
1530 EXPECT_DEATH_IF_SUPPORTED(map.at(3), "absl::btree_map::at");
1531 #endif
1532 }
1533
TEST(Btree,BtreeMultisetEmplace)1534 TEST(Btree, BtreeMultisetEmplace) {
1535 const int value_to_insert = 123456;
1536 absl::btree_multiset<int> s;
1537 auto iter = s.emplace(value_to_insert);
1538 ASSERT_NE(iter, s.end());
1539 EXPECT_EQ(*iter, value_to_insert);
1540 iter = s.emplace(value_to_insert);
1541 ASSERT_NE(iter, s.end());
1542 EXPECT_EQ(*iter, value_to_insert);
1543 auto result = s.equal_range(value_to_insert);
1544 EXPECT_EQ(std::distance(result.first, result.second), 2);
1545 }
1546
TEST(Btree,BtreeMultisetEmplaceHint)1547 TEST(Btree, BtreeMultisetEmplaceHint) {
1548 const int value_to_insert = 123456;
1549 absl::btree_multiset<int> s;
1550 auto iter = s.emplace(value_to_insert);
1551 ASSERT_NE(iter, s.end());
1552 EXPECT_EQ(*iter, value_to_insert);
1553 iter = s.emplace_hint(iter, value_to_insert);
1554 // The new element should be before the previously inserted one.
1555 EXPECT_EQ(iter, s.lower_bound(value_to_insert));
1556 ASSERT_NE(iter, s.end());
1557 EXPECT_EQ(*iter, value_to_insert);
1558 }
1559
TEST(Btree,BtreeMultimapEmplace)1560 TEST(Btree, BtreeMultimapEmplace) {
1561 const int key_to_insert = 123456;
1562 const char value0[] = "a";
1563 absl::btree_multimap<int, std::string> m;
1564 auto iter = m.emplace(key_to_insert, value0);
1565 ASSERT_NE(iter, m.end());
1566 EXPECT_EQ(iter->first, key_to_insert);
1567 EXPECT_EQ(iter->second, value0);
1568 const char value1[] = "b";
1569 iter = m.emplace(key_to_insert, value1);
1570 ASSERT_NE(iter, m.end());
1571 EXPECT_EQ(iter->first, key_to_insert);
1572 EXPECT_EQ(iter->second, value1);
1573 auto result = m.equal_range(key_to_insert);
1574 EXPECT_EQ(std::distance(result.first, result.second), 2);
1575 }
1576
TEST(Btree,BtreeMultimapEmplaceHint)1577 TEST(Btree, BtreeMultimapEmplaceHint) {
1578 const int key_to_insert = 123456;
1579 const char value0[] = "a";
1580 absl::btree_multimap<int, std::string> m;
1581 auto iter = m.emplace(key_to_insert, value0);
1582 ASSERT_NE(iter, m.end());
1583 EXPECT_EQ(iter->first, key_to_insert);
1584 EXPECT_EQ(iter->second, value0);
1585 const char value1[] = "b";
1586 iter = m.emplace_hint(iter, key_to_insert, value1);
1587 // The new element should be before the previously inserted one.
1588 EXPECT_EQ(iter, m.lower_bound(key_to_insert));
1589 ASSERT_NE(iter, m.end());
1590 EXPECT_EQ(iter->first, key_to_insert);
1591 EXPECT_EQ(iter->second, value1);
1592 }
1593
TEST(Btree,ConstIteratorAccessors)1594 TEST(Btree, ConstIteratorAccessors) {
1595 absl::btree_set<int> set;
1596 for (int i = 0; i < 100; ++i) {
1597 set.insert(i);
1598 }
1599
1600 auto it = set.cbegin();
1601 auto r_it = set.crbegin();
1602 for (int i = 0; i < 100; ++i, ++it, ++r_it) {
1603 ASSERT_EQ(*it, i);
1604 ASSERT_EQ(*r_it, 99 - i);
1605 }
1606 EXPECT_EQ(it, set.cend());
1607 EXPECT_EQ(r_it, set.crend());
1608 }
1609
TEST(Btree,StrSplitCompatible)1610 TEST(Btree, StrSplitCompatible) {
1611 const absl::btree_set<std::string> split_set = absl::StrSplit("a,b,c", ',');
1612 const absl::btree_set<std::string> expected_set = {"a", "b", "c"};
1613
1614 EXPECT_EQ(split_set, expected_set);
1615 }
1616
TEST(Btree,KeyComp)1617 TEST(Btree, KeyComp) {
1618 absl::btree_set<int> s;
1619 EXPECT_TRUE(s.key_comp()(1, 2));
1620 EXPECT_FALSE(s.key_comp()(2, 2));
1621 EXPECT_FALSE(s.key_comp()(2, 1));
1622
1623 absl::btree_map<int, int> m1;
1624 EXPECT_TRUE(m1.key_comp()(1, 2));
1625 EXPECT_FALSE(m1.key_comp()(2, 2));
1626 EXPECT_FALSE(m1.key_comp()(2, 1));
1627
1628 // Even though we internally adapt the comparator of `m2` to be three-way and
1629 // heterogeneous, the comparator we expose through key_comp() is the original
1630 // unadapted comparator.
1631 absl::btree_map<std::string, int> m2;
1632 EXPECT_TRUE(m2.key_comp()("a", "b"));
1633 EXPECT_FALSE(m2.key_comp()("b", "b"));
1634 EXPECT_FALSE(m2.key_comp()("b", "a"));
1635 }
1636
TEST(Btree,ValueComp)1637 TEST(Btree, ValueComp) {
1638 absl::btree_set<int> s;
1639 EXPECT_TRUE(s.value_comp()(1, 2));
1640 EXPECT_FALSE(s.value_comp()(2, 2));
1641 EXPECT_FALSE(s.value_comp()(2, 1));
1642
1643 absl::btree_map<int, int> m1;
1644 EXPECT_TRUE(m1.value_comp()(std::make_pair(1, 0), std::make_pair(2, 0)));
1645 EXPECT_FALSE(m1.value_comp()(std::make_pair(2, 0), std::make_pair(2, 0)));
1646 EXPECT_FALSE(m1.value_comp()(std::make_pair(2, 0), std::make_pair(1, 0)));
1647
1648 // Even though we internally adapt the comparator of `m2` to be three-way and
1649 // heterogeneous, the comparator we expose through value_comp() is based on
1650 // the original unadapted comparator.
1651 absl::btree_map<std::string, int> m2;
1652 EXPECT_TRUE(m2.value_comp()(std::make_pair("a", 0), std::make_pair("b", 0)));
1653 EXPECT_FALSE(m2.value_comp()(std::make_pair("b", 0), std::make_pair("b", 0)));
1654 EXPECT_FALSE(m2.value_comp()(std::make_pair("b", 0), std::make_pair("a", 0)));
1655 }
1656
1657 // Test that we have the protected members from the std::map::value_compare API.
1658 // See https://en.cppreference.com/w/cpp/container/map/value_compare.
TEST(Btree,MapValueCompProtected)1659 TEST(Btree, MapValueCompProtected) {
1660 struct key_compare {
1661 bool operator()(int l, int r) const { return l < r; }
1662 int id;
1663 };
1664 using value_compare = absl::btree_map<int, int, key_compare>::value_compare;
1665 struct value_comp_child : public value_compare {
1666 explicit value_comp_child(key_compare kc) : value_compare(kc) {}
1667 int GetId() const { return comp.id; }
1668 };
1669 value_comp_child c(key_compare{10});
1670 EXPECT_EQ(c.GetId(), 10);
1671 }
1672
TEST(Btree,DefaultConstruction)1673 TEST(Btree, DefaultConstruction) {
1674 absl::btree_set<int> s;
1675 absl::btree_map<int, int> m;
1676 absl::btree_multiset<int> ms;
1677 absl::btree_multimap<int, int> mm;
1678
1679 EXPECT_TRUE(s.empty());
1680 EXPECT_TRUE(m.empty());
1681 EXPECT_TRUE(ms.empty());
1682 EXPECT_TRUE(mm.empty());
1683 }
1684
TEST(Btree,SwissTableHashable)1685 TEST(Btree, SwissTableHashable) {
1686 static constexpr int kValues = 10000;
1687 std::vector<int> values(kValues);
1688 std::iota(values.begin(), values.end(), 0);
1689 std::vector<std::pair<int, int>> map_values;
1690 for (int v : values) map_values.emplace_back(v, -v);
1691
1692 using set = absl::btree_set<int>;
1693 EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1694 set{},
1695 set{1},
1696 set{2},
1697 set{1, 2},
1698 set{2, 1},
1699 set(values.begin(), values.end()),
1700 set(values.rbegin(), values.rend()),
1701 }));
1702
1703 using mset = absl::btree_multiset<int>;
1704 EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1705 mset{},
1706 mset{1},
1707 mset{1, 1},
1708 mset{2},
1709 mset{2, 2},
1710 mset{1, 2},
1711 mset{1, 1, 2},
1712 mset{1, 2, 2},
1713 mset{1, 1, 2, 2},
1714 mset(values.begin(), values.end()),
1715 mset(values.rbegin(), values.rend()),
1716 }));
1717
1718 using map = absl::btree_map<int, int>;
1719 EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1720 map{},
1721 map{{1, 0}},
1722 map{{1, 1}},
1723 map{{2, 0}},
1724 map{{2, 2}},
1725 map{{1, 0}, {2, 1}},
1726 map(map_values.begin(), map_values.end()),
1727 map(map_values.rbegin(), map_values.rend()),
1728 }));
1729
1730 using mmap = absl::btree_multimap<int, int>;
1731 EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1732 mmap{},
1733 mmap{{1, 0}},
1734 mmap{{1, 1}},
1735 mmap{{1, 0}, {1, 1}},
1736 mmap{{1, 1}, {1, 0}},
1737 mmap{{2, 0}},
1738 mmap{{2, 2}},
1739 mmap{{1, 0}, {2, 1}},
1740 mmap(map_values.begin(), map_values.end()),
1741 mmap(map_values.rbegin(), map_values.rend()),
1742 }));
1743 }
1744
TEST(Btree,ComparableSet)1745 TEST(Btree, ComparableSet) {
1746 absl::btree_set<int> s1 = {1, 2};
1747 absl::btree_set<int> s2 = {2, 3};
1748 EXPECT_LT(s1, s2);
1749 EXPECT_LE(s1, s2);
1750 EXPECT_LE(s1, s1);
1751 EXPECT_GT(s2, s1);
1752 EXPECT_GE(s2, s1);
1753 EXPECT_GE(s1, s1);
1754 }
1755
TEST(Btree,ComparableSetsDifferentLength)1756 TEST(Btree, ComparableSetsDifferentLength) {
1757 absl::btree_set<int> s1 = {1, 2};
1758 absl::btree_set<int> s2 = {1, 2, 3};
1759 EXPECT_LT(s1, s2);
1760 EXPECT_LE(s1, s2);
1761 EXPECT_GT(s2, s1);
1762 EXPECT_GE(s2, s1);
1763 }
1764
TEST(Btree,ComparableMultiset)1765 TEST(Btree, ComparableMultiset) {
1766 absl::btree_multiset<int> s1 = {1, 2};
1767 absl::btree_multiset<int> s2 = {2, 3};
1768 EXPECT_LT(s1, s2);
1769 EXPECT_LE(s1, s2);
1770 EXPECT_LE(s1, s1);
1771 EXPECT_GT(s2, s1);
1772 EXPECT_GE(s2, s1);
1773 EXPECT_GE(s1, s1);
1774 }
1775
TEST(Btree,ComparableMap)1776 TEST(Btree, ComparableMap) {
1777 absl::btree_map<int, int> s1 = {{1, 2}};
1778 absl::btree_map<int, int> s2 = {{2, 3}};
1779 EXPECT_LT(s1, s2);
1780 EXPECT_LE(s1, s2);
1781 EXPECT_LE(s1, s1);
1782 EXPECT_GT(s2, s1);
1783 EXPECT_GE(s2, s1);
1784 EXPECT_GE(s1, s1);
1785 }
1786
TEST(Btree,ComparableMultimap)1787 TEST(Btree, ComparableMultimap) {
1788 absl::btree_multimap<int, int> s1 = {{1, 2}};
1789 absl::btree_multimap<int, int> s2 = {{2, 3}};
1790 EXPECT_LT(s1, s2);
1791 EXPECT_LE(s1, s2);
1792 EXPECT_LE(s1, s1);
1793 EXPECT_GT(s2, s1);
1794 EXPECT_GE(s2, s1);
1795 EXPECT_GE(s1, s1);
1796 }
1797
TEST(Btree,ComparableSetWithCustomComparator)1798 TEST(Btree, ComparableSetWithCustomComparator) {
1799 // As specified by
1800 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf section
1801 // [container.requirements.general].12, ordering associative containers always
1802 // uses default '<' operator
1803 // - even if otherwise the container uses custom functor.
1804 absl::btree_set<int, std::greater<int>> s1 = {1, 2};
1805 absl::btree_set<int, std::greater<int>> s2 = {2, 3};
1806 EXPECT_LT(s1, s2);
1807 EXPECT_LE(s1, s2);
1808 EXPECT_LE(s1, s1);
1809 EXPECT_GT(s2, s1);
1810 EXPECT_GE(s2, s1);
1811 EXPECT_GE(s1, s1);
1812 }
1813
TEST(Btree,EraseReturnsIterator)1814 TEST(Btree, EraseReturnsIterator) {
1815 absl::btree_set<int> set = {1, 2, 3, 4, 5};
1816 auto result_it = set.erase(set.begin(), set.find(3));
1817 EXPECT_EQ(result_it, set.find(3));
1818 result_it = set.erase(set.find(5));
1819 EXPECT_EQ(result_it, set.end());
1820 }
1821
TEST(Btree,ExtractAndInsertNodeHandleSet)1822 TEST(Btree, ExtractAndInsertNodeHandleSet) {
1823 absl::btree_set<int> src1 = {1, 2, 3, 4, 5};
1824 auto nh = src1.extract(src1.find(3));
1825 EXPECT_THAT(src1, ElementsAre(1, 2, 4, 5));
1826 absl::btree_set<int> other;
1827 absl::btree_set<int>::insert_return_type res = other.insert(std::move(nh));
1828 EXPECT_THAT(other, ElementsAre(3));
1829 EXPECT_EQ(res.position, other.find(3));
1830 EXPECT_TRUE(res.inserted);
1831 EXPECT_TRUE(res.node.empty());
1832
1833 absl::btree_set<int> src2 = {3, 4};
1834 nh = src2.extract(src2.find(3));
1835 EXPECT_THAT(src2, ElementsAre(4));
1836 res = other.insert(std::move(nh));
1837 EXPECT_THAT(other, ElementsAre(3));
1838 EXPECT_EQ(res.position, other.find(3));
1839 EXPECT_FALSE(res.inserted);
1840 ASSERT_FALSE(res.node.empty());
1841 EXPECT_EQ(res.node.value(), 3);
1842 }
1843
1844 template <typename Set>
TestExtractWithTrackingForSet()1845 void TestExtractWithTrackingForSet() {
1846 InstanceTracker tracker;
1847 {
1848 Set s;
1849 // Add enough elements to make sure we test internal nodes too.
1850 const size_t kSize = 1000;
1851 while (s.size() < kSize) {
1852 s.insert(MovableOnlyInstance(s.size()));
1853 }
1854 for (int i = 0; i < kSize; ++i) {
1855 // Extract with key
1856 auto nh = s.extract(MovableOnlyInstance(i));
1857 EXPECT_EQ(s.size(), kSize - 1);
1858 EXPECT_EQ(nh.value().value(), i);
1859 // Insert with node
1860 s.insert(std::move(nh));
1861 EXPECT_EQ(s.size(), kSize);
1862
1863 // Extract with iterator
1864 auto it = s.find(MovableOnlyInstance(i));
1865 nh = s.extract(it);
1866 EXPECT_EQ(s.size(), kSize - 1);
1867 EXPECT_EQ(nh.value().value(), i);
1868 // Insert with node and hint
1869 s.insert(s.begin(), std::move(nh));
1870 EXPECT_EQ(s.size(), kSize);
1871 }
1872 }
1873 EXPECT_EQ(0, tracker.instances());
1874 }
1875
1876 template <typename Map>
TestExtractWithTrackingForMap()1877 void TestExtractWithTrackingForMap() {
1878 InstanceTracker tracker;
1879 {
1880 Map m;
1881 // Add enough elements to make sure we test internal nodes too.
1882 const size_t kSize = 1000;
1883 while (m.size() < kSize) {
1884 m.insert(
1885 {CopyableMovableInstance(m.size()), MovableOnlyInstance(m.size())});
1886 }
1887 for (int i = 0; i < kSize; ++i) {
1888 // Extract with key
1889 auto nh = m.extract(CopyableMovableInstance(i));
1890 EXPECT_EQ(m.size(), kSize - 1);
1891 EXPECT_EQ(nh.key().value(), i);
1892 EXPECT_EQ(nh.mapped().value(), i);
1893 // Insert with node
1894 m.insert(std::move(nh));
1895 EXPECT_EQ(m.size(), kSize);
1896
1897 // Extract with iterator
1898 auto it = m.find(CopyableMovableInstance(i));
1899 nh = m.extract(it);
1900 EXPECT_EQ(m.size(), kSize - 1);
1901 EXPECT_EQ(nh.key().value(), i);
1902 EXPECT_EQ(nh.mapped().value(), i);
1903 // Insert with node and hint
1904 m.insert(m.begin(), std::move(nh));
1905 EXPECT_EQ(m.size(), kSize);
1906 }
1907 }
1908 EXPECT_EQ(0, tracker.instances());
1909 }
1910
TEST(Btree,ExtractTracking)1911 TEST(Btree, ExtractTracking) {
1912 TestExtractWithTrackingForSet<absl::btree_set<MovableOnlyInstance>>();
1913 TestExtractWithTrackingForSet<absl::btree_multiset<MovableOnlyInstance>>();
1914 TestExtractWithTrackingForMap<
1915 absl::btree_map<CopyableMovableInstance, MovableOnlyInstance>>();
1916 TestExtractWithTrackingForMap<
1917 absl::btree_multimap<CopyableMovableInstance, MovableOnlyInstance>>();
1918 }
1919
TEST(Btree,ExtractAndInsertNodeHandleMultiSet)1920 TEST(Btree, ExtractAndInsertNodeHandleMultiSet) {
1921 absl::btree_multiset<int> src1 = {1, 2, 3, 3, 4, 5};
1922 auto nh = src1.extract(src1.find(3));
1923 EXPECT_THAT(src1, ElementsAre(1, 2, 3, 4, 5));
1924 absl::btree_multiset<int> other;
1925 auto res = other.insert(std::move(nh));
1926 EXPECT_THAT(other, ElementsAre(3));
1927 EXPECT_EQ(res, other.find(3));
1928
1929 absl::btree_multiset<int> src2 = {3, 4};
1930 nh = src2.extract(src2.find(3));
1931 EXPECT_THAT(src2, ElementsAre(4));
1932 res = other.insert(std::move(nh));
1933 EXPECT_THAT(other, ElementsAre(3, 3));
1934 EXPECT_EQ(res, ++other.find(3));
1935 }
1936
TEST(Btree,ExtractAndInsertNodeHandleMap)1937 TEST(Btree, ExtractAndInsertNodeHandleMap) {
1938 absl::btree_map<int, int> src1 = {{1, 2}, {3, 4}, {5, 6}};
1939 auto nh = src1.extract(src1.find(3));
1940 EXPECT_THAT(src1, ElementsAre(Pair(1, 2), Pair(5, 6)));
1941 absl::btree_map<int, int> other;
1942 absl::btree_map<int, int>::insert_return_type res =
1943 other.insert(std::move(nh));
1944 EXPECT_THAT(other, ElementsAre(Pair(3, 4)));
1945 EXPECT_EQ(res.position, other.find(3));
1946 EXPECT_TRUE(res.inserted);
1947 EXPECT_TRUE(res.node.empty());
1948
1949 absl::btree_map<int, int> src2 = {{3, 6}};
1950 nh = src2.extract(src2.find(3));
1951 EXPECT_TRUE(src2.empty());
1952 res = other.insert(std::move(nh));
1953 EXPECT_THAT(other, ElementsAre(Pair(3, 4)));
1954 EXPECT_EQ(res.position, other.find(3));
1955 EXPECT_FALSE(res.inserted);
1956 ASSERT_FALSE(res.node.empty());
1957 EXPECT_EQ(res.node.key(), 3);
1958 EXPECT_EQ(res.node.mapped(), 6);
1959 }
1960
TEST(Btree,ExtractAndInsertNodeHandleMultiMap)1961 TEST(Btree, ExtractAndInsertNodeHandleMultiMap) {
1962 absl::btree_multimap<int, int> src1 = {{1, 2}, {3, 4}, {5, 6}};
1963 auto nh = src1.extract(src1.find(3));
1964 EXPECT_THAT(src1, ElementsAre(Pair(1, 2), Pair(5, 6)));
1965 absl::btree_multimap<int, int> other;
1966 auto res = other.insert(std::move(nh));
1967 EXPECT_THAT(other, ElementsAre(Pair(3, 4)));
1968 EXPECT_EQ(res, other.find(3));
1969
1970 absl::btree_multimap<int, int> src2 = {{3, 6}};
1971 nh = src2.extract(src2.find(3));
1972 EXPECT_TRUE(src2.empty());
1973 res = other.insert(std::move(nh));
1974 EXPECT_THAT(other, ElementsAre(Pair(3, 4), Pair(3, 6)));
1975 EXPECT_EQ(res, ++other.begin());
1976 }
1977
TEST(Btree,ExtractMultiMapEquivalentKeys)1978 TEST(Btree, ExtractMultiMapEquivalentKeys) {
1979 // Note: using string keys means a three-way comparator.
1980 absl::btree_multimap<std::string, int> map;
1981 for (int i = 0; i < 100; ++i) {
1982 for (int j = 0; j < 100; ++j) {
1983 map.insert({absl::StrCat(i), j});
1984 }
1985 }
1986
1987 for (int i = 0; i < 100; ++i) {
1988 const std::string key = absl::StrCat(i);
1989 auto node_handle = map.extract(key);
1990 EXPECT_EQ(node_handle.key(), key);
1991 EXPECT_EQ(node_handle.mapped(), 0) << i;
1992 }
1993
1994 for (int i = 0; i < 100; ++i) {
1995 const std::string key = absl::StrCat(i);
1996 auto node_handle = map.extract(key);
1997 EXPECT_EQ(node_handle.key(), key);
1998 EXPECT_EQ(node_handle.mapped(), 1) << i;
1999 }
2000 }
2001
TEST(Btree,ExtractAndGetNextSet)2002 TEST(Btree, ExtractAndGetNextSet) {
2003 absl::btree_set<int> src = {1, 2, 3, 4, 5};
2004 auto it = src.find(3);
2005 auto extracted_and_next = src.extract_and_get_next(it);
2006 EXPECT_THAT(src, ElementsAre(1, 2, 4, 5));
2007 EXPECT_EQ(extracted_and_next.node.value(), 3);
2008 EXPECT_EQ(*extracted_and_next.next, 4);
2009 }
2010
TEST(Btree,ExtractAndGetNextMultiSet)2011 TEST(Btree, ExtractAndGetNextMultiSet) {
2012 absl::btree_multiset<int> src = {1, 2, 3, 4, 5};
2013 auto it = src.find(3);
2014 auto extracted_and_next = src.extract_and_get_next(it);
2015 EXPECT_THAT(src, ElementsAre(1, 2, 4, 5));
2016 EXPECT_EQ(extracted_and_next.node.value(), 3);
2017 EXPECT_EQ(*extracted_and_next.next, 4);
2018 }
2019
TEST(Btree,ExtractAndGetNextMap)2020 TEST(Btree, ExtractAndGetNextMap) {
2021 absl::btree_map<int, int> src = {{1, 2}, {3, 4}, {5, 6}};
2022 auto it = src.find(3);
2023 auto extracted_and_next = src.extract_and_get_next(it);
2024 EXPECT_THAT(src, ElementsAre(Pair(1, 2), Pair(5, 6)));
2025 EXPECT_EQ(extracted_and_next.node.key(), 3);
2026 EXPECT_EQ(extracted_and_next.node.mapped(), 4);
2027 EXPECT_THAT(*extracted_and_next.next, Pair(5, 6));
2028 }
2029
TEST(Btree,ExtractAndGetNextMultiMap)2030 TEST(Btree, ExtractAndGetNextMultiMap) {
2031 absl::btree_multimap<int, int> src = {{1, 2}, {3, 4}, {5, 6}};
2032 auto it = src.find(3);
2033 auto extracted_and_next = src.extract_and_get_next(it);
2034 EXPECT_THAT(src, ElementsAre(Pair(1, 2), Pair(5, 6)));
2035 EXPECT_EQ(extracted_and_next.node.key(), 3);
2036 EXPECT_EQ(extracted_and_next.node.mapped(), 4);
2037 EXPECT_THAT(*extracted_and_next.next, Pair(5, 6));
2038 }
2039
TEST(Btree,ExtractAndGetNextEndIter)2040 TEST(Btree, ExtractAndGetNextEndIter) {
2041 absl::btree_set<int> src = {1, 2, 3, 4, 5};
2042 auto it = src.find(5);
2043 auto extracted_and_next = src.extract_and_get_next(it);
2044 EXPECT_THAT(src, ElementsAre(1, 2, 3, 4));
2045 EXPECT_EQ(extracted_and_next.node.value(), 5);
2046 EXPECT_EQ(extracted_and_next.next, src.end());
2047 }
2048
TEST(Btree,ExtractDoesntCauseExtraMoves)2049 TEST(Btree, ExtractDoesntCauseExtraMoves) {
2050 #ifdef _MSC_VER
2051 GTEST_SKIP() << "This test fails on MSVC.";
2052 #endif
2053
2054 using Set = absl::btree_set<MovableOnlyInstance>;
2055 std::array<std::function<void(Set &)>, 3> extracters = {
2056 [](Set &s) { auto node = s.extract(s.begin()); },
2057 [](Set &s) { auto ret = s.extract_and_get_next(s.begin()); },
2058 [](Set &s) { auto node = s.extract(MovableOnlyInstance(0)); }};
2059
2060 InstanceTracker tracker;
2061 for (int i = 0; i < 3; ++i) {
2062 Set s;
2063 s.insert(MovableOnlyInstance(0));
2064 tracker.ResetCopiesMovesSwaps();
2065
2066 extracters[i](s);
2067 // We expect to see exactly 1 move: from the original slot into the
2068 // extracted node.
2069 EXPECT_EQ(tracker.copies(), 0) << i;
2070 EXPECT_EQ(tracker.moves(), 1) << i;
2071 EXPECT_EQ(tracker.swaps(), 0) << i;
2072 }
2073 }
2074
2075 // For multisets, insert with hint also affects correctness because we need to
2076 // insert immediately before the hint if possible.
2077 struct InsertMultiHintData {
2078 int key;
2079 int not_key;
operator ==absl::container_internal::__anon7e8713fe0311::InsertMultiHintData2080 bool operator==(const InsertMultiHintData other) const {
2081 return key == other.key && not_key == other.not_key;
2082 }
2083 };
2084
2085 struct InsertMultiHintDataKeyCompare {
2086 using is_transparent = void;
operator ()absl::container_internal::__anon7e8713fe0311::InsertMultiHintDataKeyCompare2087 bool operator()(const InsertMultiHintData a,
2088 const InsertMultiHintData b) const {
2089 return a.key < b.key;
2090 }
operator ()absl::container_internal::__anon7e8713fe0311::InsertMultiHintDataKeyCompare2091 bool operator()(const int a, const InsertMultiHintData b) const {
2092 return a < b.key;
2093 }
operator ()absl::container_internal::__anon7e8713fe0311::InsertMultiHintDataKeyCompare2094 bool operator()(const InsertMultiHintData a, const int b) const {
2095 return a.key < b;
2096 }
2097 };
2098
TEST(Btree,InsertHintNodeHandle)2099 TEST(Btree, InsertHintNodeHandle) {
2100 // For unique sets, insert with hint is just a performance optimization.
2101 // Test that insert works correctly when the hint is right or wrong.
2102 {
2103 absl::btree_set<int> src = {1, 2, 3, 4, 5};
2104 auto nh = src.extract(src.find(3));
2105 EXPECT_THAT(src, ElementsAre(1, 2, 4, 5));
2106 absl::btree_set<int> other = {0, 100};
2107 // Test a correct hint.
2108 auto it = other.insert(other.lower_bound(3), std::move(nh));
2109 EXPECT_THAT(other, ElementsAre(0, 3, 100));
2110 EXPECT_EQ(it, other.find(3));
2111
2112 nh = src.extract(src.find(5));
2113 // Test an incorrect hint.
2114 it = other.insert(other.end(), std::move(nh));
2115 EXPECT_THAT(other, ElementsAre(0, 3, 5, 100));
2116 EXPECT_EQ(it, other.find(5));
2117 }
2118
2119 absl::btree_multiset<InsertMultiHintData, InsertMultiHintDataKeyCompare> src =
2120 {{1, 2}, {3, 4}, {3, 5}};
2121 auto nh = src.extract(src.lower_bound(3));
2122 EXPECT_EQ(nh.value(), (InsertMultiHintData{3, 4}));
2123 absl::btree_multiset<InsertMultiHintData, InsertMultiHintDataKeyCompare>
2124 other = {{3, 1}, {3, 2}, {3, 3}};
2125 auto it = other.insert(--other.end(), std::move(nh));
2126 EXPECT_THAT(
2127 other, ElementsAre(InsertMultiHintData{3, 1}, InsertMultiHintData{3, 2},
2128 InsertMultiHintData{3, 4}, InsertMultiHintData{3, 3}));
2129 EXPECT_EQ(it, --(--other.end()));
2130
2131 nh = src.extract(src.find(3));
2132 EXPECT_EQ(nh.value(), (InsertMultiHintData{3, 5}));
2133 it = other.insert(other.begin(), std::move(nh));
2134 EXPECT_THAT(other,
2135 ElementsAre(InsertMultiHintData{3, 5}, InsertMultiHintData{3, 1},
2136 InsertMultiHintData{3, 2}, InsertMultiHintData{3, 4},
2137 InsertMultiHintData{3, 3}));
2138 EXPECT_EQ(it, other.begin());
2139 }
2140
2141 struct IntCompareToCmp {
operator ()absl::container_internal::__anon7e8713fe0311::IntCompareToCmp2142 absl::weak_ordering operator()(int a, int b) const {
2143 if (a < b) return absl::weak_ordering::less;
2144 if (a > b) return absl::weak_ordering::greater;
2145 return absl::weak_ordering::equivalent;
2146 }
2147 };
2148
TEST(Btree,MergeIntoUniqueContainers)2149 TEST(Btree, MergeIntoUniqueContainers) {
2150 absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2151 absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2152 absl::btree_set<int> dst;
2153
2154 dst.merge(src1);
2155 EXPECT_TRUE(src1.empty());
2156 EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2157 dst.merge(src2);
2158 EXPECT_THAT(src2, ElementsAre(3, 4));
2159 EXPECT_THAT(dst, ElementsAre(1, 2, 3, 4, 5));
2160 }
2161
TEST(Btree,MergeIntoUniqueContainersWithCompareTo)2162 TEST(Btree, MergeIntoUniqueContainersWithCompareTo) {
2163 absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2164 absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2165 absl::btree_set<int, IntCompareToCmp> dst;
2166
2167 dst.merge(src1);
2168 EXPECT_TRUE(src1.empty());
2169 EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2170 dst.merge(src2);
2171 EXPECT_THAT(src2, ElementsAre(3, 4));
2172 EXPECT_THAT(dst, ElementsAre(1, 2, 3, 4, 5));
2173 }
2174
TEST(Btree,MergeIntoMultiContainers)2175 TEST(Btree, MergeIntoMultiContainers) {
2176 absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2177 absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2178 absl::btree_multiset<int> dst;
2179
2180 dst.merge(src1);
2181 EXPECT_TRUE(src1.empty());
2182 EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2183 dst.merge(src2);
2184 EXPECT_TRUE(src2.empty());
2185 EXPECT_THAT(dst, ElementsAre(1, 2, 3, 3, 4, 4, 5));
2186 }
2187
TEST(Btree,MergeIntoMultiContainersWithCompareTo)2188 TEST(Btree, MergeIntoMultiContainersWithCompareTo) {
2189 absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2190 absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2191 absl::btree_multiset<int, IntCompareToCmp> dst;
2192
2193 dst.merge(src1);
2194 EXPECT_TRUE(src1.empty());
2195 EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2196 dst.merge(src2);
2197 EXPECT_TRUE(src2.empty());
2198 EXPECT_THAT(dst, ElementsAre(1, 2, 3, 3, 4, 4, 5));
2199 }
2200
TEST(Btree,MergeIntoMultiMapsWithDifferentComparators)2201 TEST(Btree, MergeIntoMultiMapsWithDifferentComparators) {
2202 absl::btree_map<int, int, IntCompareToCmp> src1 = {{1, 1}, {2, 2}, {3, 3}};
2203 absl::btree_multimap<int, int, std::greater<int>> src2 = {
2204 {5, 5}, {4, 1}, {4, 4}, {3, 2}};
2205 absl::btree_multimap<int, int> dst;
2206
2207 dst.merge(src1);
2208 EXPECT_TRUE(src1.empty());
2209 EXPECT_THAT(dst, ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3)));
2210 dst.merge(src2);
2211 EXPECT_TRUE(src2.empty());
2212 EXPECT_THAT(dst, ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3), Pair(3, 2),
2213 Pair(4, 1), Pair(4, 4), Pair(5, 5)));
2214 }
2215
TEST(Btree,MergeIntoSetMovableOnly)2216 TEST(Btree, MergeIntoSetMovableOnly) {
2217 absl::btree_set<MovableOnlyInstance> src;
2218 src.insert(MovableOnlyInstance(1));
2219 absl::btree_multiset<MovableOnlyInstance> dst1;
2220 dst1.insert(MovableOnlyInstance(2));
2221 absl::btree_set<MovableOnlyInstance> dst2;
2222
2223 // Test merge into multiset.
2224 dst1.merge(src);
2225
2226 EXPECT_TRUE(src.empty());
2227 // ElementsAre/ElementsAreArray don't work with move-only types.
2228 ASSERT_THAT(dst1, SizeIs(2));
2229 EXPECT_EQ(*dst1.begin(), MovableOnlyInstance(1));
2230 EXPECT_EQ(*std::next(dst1.begin()), MovableOnlyInstance(2));
2231
2232 // Test merge into set.
2233 dst2.merge(dst1);
2234
2235 EXPECT_TRUE(dst1.empty());
2236 ASSERT_THAT(dst2, SizeIs(2));
2237 EXPECT_EQ(*dst2.begin(), MovableOnlyInstance(1));
2238 EXPECT_EQ(*std::next(dst2.begin()), MovableOnlyInstance(2));
2239 }
2240
2241 struct KeyCompareToWeakOrdering {
2242 template <typename T>
operator ()absl::container_internal::__anon7e8713fe0311::KeyCompareToWeakOrdering2243 absl::weak_ordering operator()(const T &a, const T &b) const {
2244 return a < b ? absl::weak_ordering::less
2245 : a == b ? absl::weak_ordering::equivalent
2246 : absl::weak_ordering::greater;
2247 }
2248 };
2249
2250 struct KeyCompareToStrongOrdering {
2251 template <typename T>
operator ()absl::container_internal::__anon7e8713fe0311::KeyCompareToStrongOrdering2252 absl::strong_ordering operator()(const T &a, const T &b) const {
2253 return a < b ? absl::strong_ordering::less
2254 : a == b ? absl::strong_ordering::equal
2255 : absl::strong_ordering::greater;
2256 }
2257 };
2258
TEST(Btree,UserProvidedKeyCompareToComparators)2259 TEST(Btree, UserProvidedKeyCompareToComparators) {
2260 absl::btree_set<int, KeyCompareToWeakOrdering> weak_set = {1, 2, 3};
2261 EXPECT_TRUE(weak_set.contains(2));
2262 EXPECT_FALSE(weak_set.contains(4));
2263
2264 absl::btree_set<int, KeyCompareToStrongOrdering> strong_set = {1, 2, 3};
2265 EXPECT_TRUE(strong_set.contains(2));
2266 EXPECT_FALSE(strong_set.contains(4));
2267 }
2268
TEST(Btree,TryEmplaceBasicTest)2269 TEST(Btree, TryEmplaceBasicTest) {
2270 absl::btree_map<int, std::string> m;
2271
2272 // Should construct a string from the literal.
2273 m.try_emplace(1, "one");
2274 EXPECT_EQ(1, m.size());
2275
2276 // Try other string constructors and const lvalue key.
2277 const int key(42);
2278 m.try_emplace(key, 3, 'a');
2279 m.try_emplace(2, std::string("two"));
2280
2281 EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2282 EXPECT_THAT(m, ElementsAreArray(std::vector<std::pair<int, std::string>>{
2283 {1, "one"}, {2, "two"}, {42, "aaa"}}));
2284 }
2285
TEST(Btree,TryEmplaceWithHintWorks)2286 TEST(Btree, TryEmplaceWithHintWorks) {
2287 // Use a counting comparator here to verify that hint is used.
2288 int calls = 0;
2289 auto cmp = [&calls](int x, int y) {
2290 ++calls;
2291 return x < y;
2292 };
2293 using Cmp = decltype(cmp);
2294
2295 // Use a map that is opted out of key_compare being adapted so we can expect
2296 // strict comparison call limits.
2297 absl::btree_map<int, int, CheckedCompareOptedOutCmp<Cmp>> m(cmp);
2298 for (int i = 0; i < 128; ++i) {
2299 m.emplace(i, i);
2300 }
2301
2302 // Sanity check for the comparator
2303 calls = 0;
2304 m.emplace(127, 127);
2305 EXPECT_GE(calls, 4);
2306
2307 // Try with begin hint:
2308 calls = 0;
2309 auto it = m.try_emplace(m.begin(), -1, -1);
2310 EXPECT_EQ(129, m.size());
2311 EXPECT_EQ(it, m.begin());
2312 EXPECT_LE(calls, 2);
2313
2314 // Try with end hint:
2315 calls = 0;
2316 std::pair<int, int> pair1024 = {1024, 1024};
2317 it = m.try_emplace(m.end(), pair1024.first, pair1024.second);
2318 EXPECT_EQ(130, m.size());
2319 EXPECT_EQ(it, --m.end());
2320 EXPECT_LE(calls, 2);
2321
2322 // Try value already present, bad hint; ensure no duplicate added:
2323 calls = 0;
2324 it = m.try_emplace(m.end(), 16, 17);
2325 EXPECT_EQ(130, m.size());
2326 EXPECT_GE(calls, 4);
2327 EXPECT_EQ(it, m.find(16));
2328
2329 // Try value already present, hint points directly to it:
2330 calls = 0;
2331 it = m.try_emplace(it, 16, 17);
2332 EXPECT_EQ(130, m.size());
2333 EXPECT_LE(calls, 2);
2334 EXPECT_EQ(it, m.find(16));
2335
2336 m.erase(2);
2337 EXPECT_EQ(129, m.size());
2338 auto hint = m.find(3);
2339 // Try emplace in the middle of two other elements.
2340 calls = 0;
2341 m.try_emplace(hint, 2, 2);
2342 EXPECT_EQ(130, m.size());
2343 EXPECT_LE(calls, 2);
2344
2345 EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2346 }
2347
TEST(Btree,TryEmplaceWithBadHint)2348 TEST(Btree, TryEmplaceWithBadHint) {
2349 absl::btree_map<int, int> m = {{1, 1}, {9, 9}};
2350
2351 // Bad hint (too small), should still emplace:
2352 auto it = m.try_emplace(m.begin(), 2, 2);
2353 EXPECT_EQ(it, ++m.begin());
2354 EXPECT_THAT(m, ElementsAreArray(
2355 std::vector<std::pair<int, int>>{{1, 1}, {2, 2}, {9, 9}}));
2356
2357 // Bad hint, too large this time:
2358 it = m.try_emplace(++(++m.begin()), 0, 0);
2359 EXPECT_EQ(it, m.begin());
2360 EXPECT_THAT(m, ElementsAreArray(std::vector<std::pair<int, int>>{
2361 {0, 0}, {1, 1}, {2, 2}, {9, 9}}));
2362 }
2363
TEST(Btree,TryEmplaceMaintainsSortedOrder)2364 TEST(Btree, TryEmplaceMaintainsSortedOrder) {
2365 absl::btree_map<int, std::string> m;
2366 std::pair<int, std::string> pair5 = {5, "five"};
2367
2368 // Test both lvalue & rvalue emplace.
2369 m.try_emplace(10, "ten");
2370 m.try_emplace(pair5.first, pair5.second);
2371 EXPECT_EQ(2, m.size());
2372 EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2373
2374 int int100{100};
2375 m.try_emplace(int100, "hundred");
2376 m.try_emplace(1, "one");
2377 EXPECT_EQ(4, m.size());
2378 EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2379 }
2380
TEST(Btree,TryEmplaceWithHintAndNoValueArgsWorks)2381 TEST(Btree, TryEmplaceWithHintAndNoValueArgsWorks) {
2382 absl::btree_map<int, int> m;
2383 m.try_emplace(m.end(), 1);
2384 EXPECT_EQ(0, m[1]);
2385 }
2386
TEST(Btree,TryEmplaceWithHintAndMultipleValueArgsWorks)2387 TEST(Btree, TryEmplaceWithHintAndMultipleValueArgsWorks) {
2388 absl::btree_map<int, std::string> m;
2389 m.try_emplace(m.end(), 1, 10, 'a');
2390 EXPECT_EQ(std::string(10, 'a'), m[1]);
2391 }
2392
2393 template <typename Alloc>
2394 using BtreeSetAlloc = absl::btree_set<int, std::less<int>, Alloc>;
2395
TEST(Btree,AllocatorPropagation)2396 TEST(Btree, AllocatorPropagation) {
2397 TestAllocPropagation<BtreeSetAlloc>();
2398 }
2399
TEST(Btree,MinimumAlignmentAllocator)2400 TEST(Btree, MinimumAlignmentAllocator) {
2401 absl::btree_set<int8_t, std::less<int8_t>, MinimumAlignmentAlloc<int8_t>> set;
2402
2403 // Do some basic operations. Test that everything is fine when allocator uses
2404 // minimal alignment.
2405 for (int8_t i = 0; i < 100; ++i) set.insert(i);
2406 set.erase(set.find(50), set.end());
2407 for (int8_t i = 51; i < 101; ++i) set.insert(i);
2408
2409 EXPECT_EQ(set.size(), 100);
2410 }
2411
TEST(Btree,EmptyTree)2412 TEST(Btree, EmptyTree) {
2413 absl::btree_set<int> s;
2414 EXPECT_TRUE(s.empty());
2415 EXPECT_EQ(s.size(), 0);
2416 EXPECT_GT(s.max_size(), 0);
2417 }
2418
IsEven(int k)2419 bool IsEven(int k) { return k % 2 == 0; }
2420
TEST(Btree,EraseIf)2421 TEST(Btree, EraseIf) {
2422 // Test that erase_if works with all the container types and supports lambdas.
2423 {
2424 absl::btree_set<int> s = {1, 3, 5, 6, 100};
2425 EXPECT_EQ(erase_if(s, [](int k) { return k > 3; }), 3);
2426 EXPECT_THAT(s, ElementsAre(1, 3));
2427 }
2428 {
2429 absl::btree_multiset<int> s = {1, 3, 3, 5, 6, 6, 100};
2430 EXPECT_EQ(erase_if(s, [](int k) { return k <= 3; }), 3);
2431 EXPECT_THAT(s, ElementsAre(5, 6, 6, 100));
2432 }
2433 {
2434 absl::btree_map<int, int> m = {{1, 1}, {3, 3}, {6, 6}, {100, 100}};
2435 EXPECT_EQ(
2436 erase_if(m, [](std::pair<const int, int> kv) { return kv.first > 3; }),
2437 2);
2438 EXPECT_THAT(m, ElementsAre(Pair(1, 1), Pair(3, 3)));
2439 }
2440 {
2441 absl::btree_multimap<int, int> m = {{1, 1}, {3, 3}, {3, 6},
2442 {6, 6}, {6, 7}, {100, 6}};
2443 EXPECT_EQ(
2444 erase_if(m,
2445 [](std::pair<const int, int> kv) { return kv.second == 6; }),
2446 3);
2447 EXPECT_THAT(m, ElementsAre(Pair(1, 1), Pair(3, 3), Pair(6, 7)));
2448 }
2449 // Test that erasing all elements from a large set works and test support for
2450 // function pointers.
2451 {
2452 absl::btree_set<int> s;
2453 for (int i = 0; i < 1000; ++i) s.insert(2 * i);
2454 EXPECT_EQ(erase_if(s, IsEven), 1000);
2455 EXPECT_THAT(s, IsEmpty());
2456 }
2457 // Test that erase_if supports other format of function pointers.
2458 {
2459 absl::btree_set<int> s = {1, 3, 5, 6, 100};
2460 EXPECT_EQ(erase_if(s, &IsEven), 2);
2461 EXPECT_THAT(s, ElementsAre(1, 3, 5));
2462 }
2463 // Test that erase_if invokes the predicate once per element.
2464 {
2465 absl::btree_set<int> s;
2466 for (int i = 0; i < 1000; ++i) s.insert(i);
2467 int pred_calls = 0;
2468 EXPECT_EQ(erase_if(s,
2469 [&pred_calls](int k) {
2470 ++pred_calls;
2471 return k % 2;
2472 }),
2473 500);
2474 EXPECT_THAT(s, SizeIs(500));
2475 EXPECT_EQ(pred_calls, 1000);
2476 }
2477 }
2478
TEST(Btree,InsertOrAssign)2479 TEST(Btree, InsertOrAssign) {
2480 absl::btree_map<int, int> m = {{1, 1}, {3, 3}};
2481 using value_type = typename decltype(m)::value_type;
2482
2483 auto ret = m.insert_or_assign(4, 4);
2484 EXPECT_EQ(*ret.first, value_type(4, 4));
2485 EXPECT_TRUE(ret.second);
2486 ret = m.insert_or_assign(3, 100);
2487 EXPECT_EQ(*ret.first, value_type(3, 100));
2488 EXPECT_FALSE(ret.second);
2489
2490 auto hint_ret = m.insert_or_assign(ret.first, 3, 200);
2491 EXPECT_EQ(*hint_ret, value_type(3, 200));
2492 hint_ret = m.insert_or_assign(m.find(1), 0, 1);
2493 EXPECT_EQ(*hint_ret, value_type(0, 1));
2494 // Test with bad hint.
2495 hint_ret = m.insert_or_assign(m.end(), -1, 1);
2496 EXPECT_EQ(*hint_ret, value_type(-1, 1));
2497
2498 EXPECT_THAT(m, ElementsAre(Pair(-1, 1), Pair(0, 1), Pair(1, 1), Pair(3, 200),
2499 Pair(4, 4)));
2500 }
2501
TEST(Btree,InsertOrAssignMovableOnly)2502 TEST(Btree, InsertOrAssignMovableOnly) {
2503 absl::btree_map<int, MovableOnlyInstance> m;
2504 using value_type = typename decltype(m)::value_type;
2505
2506 auto ret = m.insert_or_assign(4, MovableOnlyInstance(4));
2507 EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(4)));
2508 EXPECT_TRUE(ret.second);
2509 ret = m.insert_or_assign(4, MovableOnlyInstance(100));
2510 EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(100)));
2511 EXPECT_FALSE(ret.second);
2512
2513 auto hint_ret = m.insert_or_assign(ret.first, 3, MovableOnlyInstance(200));
2514 EXPECT_EQ(*hint_ret, value_type(3, MovableOnlyInstance(200)));
2515
2516 EXPECT_EQ(m.size(), 2);
2517 }
2518
TEST(Btree,BitfieldArgument)2519 TEST(Btree, BitfieldArgument) {
2520 union {
2521 int n : 1;
2522 };
2523 n = 0;
2524 absl::btree_map<int, int> m;
2525 m.erase(n);
2526 m.count(n);
2527 m.find(n);
2528 m.contains(n);
2529 m.equal_range(n);
2530 m.insert_or_assign(n, n);
2531 m.insert_or_assign(m.end(), n, n);
2532 m.try_emplace(n);
2533 m.try_emplace(m.end(), n);
2534 m.at(n);
2535 m[n];
2536 }
2537
TEST(Btree,SetRangeConstructorAndInsertSupportExplicitConversionComparable)2538 TEST(Btree, SetRangeConstructorAndInsertSupportExplicitConversionComparable) {
2539 const absl::string_view names[] = {"n1", "n2"};
2540
2541 absl::btree_set<std::string> name_set1{std::begin(names), std::end(names)};
2542 EXPECT_THAT(name_set1, ElementsAreArray(names));
2543
2544 absl::btree_set<std::string> name_set2;
2545 name_set2.insert(std::begin(names), std::end(names));
2546 EXPECT_THAT(name_set2, ElementsAreArray(names));
2547 }
2548
2549 // A type that is explicitly convertible from int and counts constructor calls.
2550 struct ConstructorCounted {
ConstructorCountedabsl::container_internal::__anon7e8713fe0311::ConstructorCounted2551 explicit ConstructorCounted(int i) : i(i) { ++constructor_calls; }
operator ==absl::container_internal::__anon7e8713fe0311::ConstructorCounted2552 bool operator==(int other) const { return i == other; }
2553
2554 int i;
2555 static int constructor_calls;
2556 };
2557 int ConstructorCounted::constructor_calls = 0;
2558
2559 struct ConstructorCountedCompare {
operator ()absl::container_internal::__anon7e8713fe0311::ConstructorCountedCompare2560 bool operator()(int a, const ConstructorCounted &b) const { return a < b.i; }
operator ()absl::container_internal::__anon7e8713fe0311::ConstructorCountedCompare2561 bool operator()(const ConstructorCounted &a, int b) const { return a.i < b; }
operator ()absl::container_internal::__anon7e8713fe0311::ConstructorCountedCompare2562 bool operator()(const ConstructorCounted &a,
2563 const ConstructorCounted &b) const {
2564 return a.i < b.i;
2565 }
2566 using is_transparent = void;
2567 };
2568
TEST(Btree,SetRangeConstructorAndInsertExplicitConvComparableLimitConstruction)2569 TEST(Btree,
2570 SetRangeConstructorAndInsertExplicitConvComparableLimitConstruction) {
2571 const int i[] = {0, 1, 1};
2572 ConstructorCounted::constructor_calls = 0;
2573
2574 absl::btree_set<ConstructorCounted, ConstructorCountedCompare> set{
2575 std::begin(i), std::end(i)};
2576 EXPECT_THAT(set, ElementsAre(0, 1));
2577 EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2578
2579 set.insert(std::begin(i), std::end(i));
2580 EXPECT_THAT(set, ElementsAre(0, 1));
2581 EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2582 }
2583
TEST(Btree,SetRangeConstructorAndInsertSupportExplicitConversionNonComparable)2584 TEST(Btree,
2585 SetRangeConstructorAndInsertSupportExplicitConversionNonComparable) {
2586 const int i[] = {0, 1};
2587
2588 absl::btree_set<std::vector<void *>> s1{std::begin(i), std::end(i)};
2589 EXPECT_THAT(s1, ElementsAre(IsEmpty(), ElementsAre(IsNull())));
2590
2591 absl::btree_set<std::vector<void *>> s2;
2592 s2.insert(std::begin(i), std::end(i));
2593 EXPECT_THAT(s2, ElementsAre(IsEmpty(), ElementsAre(IsNull())));
2594 }
2595
2596 // libstdc++ included with GCC 4.9 has a bug in the std::pair constructors that
2597 // prevents explicit conversions between pair types.
2598 // We only run this test for the libstdc++ from GCC 7 or newer because we can't
2599 // reliably check the libstdc++ version prior to that release.
2600 #if !defined(__GLIBCXX__) || \
2601 (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 7)
TEST(Btree,MapRangeConstructorAndInsertSupportExplicitConversionComparable)2602 TEST(Btree, MapRangeConstructorAndInsertSupportExplicitConversionComparable) {
2603 const std::pair<absl::string_view, int> names[] = {{"n1", 1}, {"n2", 2}};
2604
2605 absl::btree_map<std::string, int> name_map1{std::begin(names),
2606 std::end(names)};
2607 EXPECT_THAT(name_map1, ElementsAre(Pair("n1", 1), Pair("n2", 2)));
2608
2609 absl::btree_map<std::string, int> name_map2;
2610 name_map2.insert(std::begin(names), std::end(names));
2611 EXPECT_THAT(name_map2, ElementsAre(Pair("n1", 1), Pair("n2", 2)));
2612 }
2613
TEST(Btree,MapRangeConstructorAndInsertExplicitConvComparableLimitConstruction)2614 TEST(Btree,
2615 MapRangeConstructorAndInsertExplicitConvComparableLimitConstruction) {
2616 const std::pair<int, int> i[] = {{0, 1}, {1, 2}, {1, 3}};
2617 ConstructorCounted::constructor_calls = 0;
2618
2619 absl::btree_map<ConstructorCounted, int, ConstructorCountedCompare> map{
2620 std::begin(i), std::end(i)};
2621 EXPECT_THAT(map, ElementsAre(Pair(0, 1), Pair(1, 2)));
2622 EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2623
2624 map.insert(std::begin(i), std::end(i));
2625 EXPECT_THAT(map, ElementsAre(Pair(0, 1), Pair(1, 2)));
2626 EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2627 }
2628
TEST(Btree,MapRangeConstructorAndInsertSupportExplicitConversionNonComparable)2629 TEST(Btree,
2630 MapRangeConstructorAndInsertSupportExplicitConversionNonComparable) {
2631 const std::pair<int, int> i[] = {{0, 1}, {1, 2}};
2632
2633 absl::btree_map<std::vector<void *>, int> m1{std::begin(i), std::end(i)};
2634 EXPECT_THAT(m1,
2635 ElementsAre(Pair(IsEmpty(), 1), Pair(ElementsAre(IsNull()), 2)));
2636
2637 absl::btree_map<std::vector<void *>, int> m2;
2638 m2.insert(std::begin(i), std::end(i));
2639 EXPECT_THAT(m2,
2640 ElementsAre(Pair(IsEmpty(), 1), Pair(ElementsAre(IsNull()), 2)));
2641 }
2642
TEST(Btree,HeterogeneousTryEmplace)2643 TEST(Btree, HeterogeneousTryEmplace) {
2644 absl::btree_map<std::string, int> m;
2645 std::string s = "key";
2646 absl::string_view sv = s;
2647 m.try_emplace(sv, 1);
2648 EXPECT_EQ(m[s], 1);
2649
2650 m.try_emplace(m.end(), sv, 2);
2651 EXPECT_EQ(m[s], 1);
2652 }
2653
TEST(Btree,HeterogeneousOperatorMapped)2654 TEST(Btree, HeterogeneousOperatorMapped) {
2655 absl::btree_map<std::string, int> m;
2656 std::string s = "key";
2657 absl::string_view sv = s;
2658 m[sv] = 1;
2659 EXPECT_EQ(m[s], 1);
2660
2661 m[sv] = 2;
2662 EXPECT_EQ(m[s], 2);
2663 }
2664
TEST(Btree,HeterogeneousInsertOrAssign)2665 TEST(Btree, HeterogeneousInsertOrAssign) {
2666 absl::btree_map<std::string, int> m;
2667 std::string s = "key";
2668 absl::string_view sv = s;
2669 m.insert_or_assign(sv, 1);
2670 EXPECT_EQ(m[s], 1);
2671
2672 m.insert_or_assign(m.end(), sv, 2);
2673 EXPECT_EQ(m[s], 2);
2674 }
2675 #endif
2676
2677 // This test requires std::launder for mutable key access in node handles.
2678 #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
TEST(Btree,NodeHandleMutableKeyAccess)2679 TEST(Btree, NodeHandleMutableKeyAccess) {
2680 {
2681 absl::btree_map<std::string, std::string> map;
2682
2683 map["key1"] = "mapped";
2684
2685 auto nh = map.extract(map.begin());
2686 nh.key().resize(3);
2687 map.insert(std::move(nh));
2688
2689 EXPECT_THAT(map, ElementsAre(Pair("key", "mapped")));
2690 }
2691 // Also for multimap.
2692 {
2693 absl::btree_multimap<std::string, std::string> map;
2694
2695 map.emplace("key1", "mapped");
2696
2697 auto nh = map.extract(map.begin());
2698 nh.key().resize(3);
2699 map.insert(std::move(nh));
2700
2701 EXPECT_THAT(map, ElementsAre(Pair("key", "mapped")));
2702 }
2703 }
2704 #endif
2705
2706 struct MultiKey {
2707 int i1;
2708 int i2;
2709 };
2710
operator ==(const MultiKey a,const MultiKey b)2711 bool operator==(const MultiKey a, const MultiKey b) {
2712 return a.i1 == b.i1 && a.i2 == b.i2;
2713 }
2714
2715 // A heterogeneous comparator that has different equivalence classes for
2716 // different lookup types.
2717 struct MultiKeyComp {
2718 using is_transparent = void;
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyComp2719 bool operator()(const MultiKey a, const MultiKey b) const {
2720 if (a.i1 != b.i1) return a.i1 < b.i1;
2721 return a.i2 < b.i2;
2722 }
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyComp2723 bool operator()(const int a, const MultiKey b) const { return a < b.i1; }
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyComp2724 bool operator()(const MultiKey a, const int b) const { return a.i1 < b; }
2725 };
2726
2727 // A heterogeneous, three-way comparator that has different equivalence classes
2728 // for different lookup types.
2729 struct MultiKeyThreeWayComp {
2730 using is_transparent = void;
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyThreeWayComp2731 absl::weak_ordering operator()(const MultiKey a, const MultiKey b) const {
2732 if (a.i1 < b.i1) return absl::weak_ordering::less;
2733 if (a.i1 > b.i1) return absl::weak_ordering::greater;
2734 if (a.i2 < b.i2) return absl::weak_ordering::less;
2735 if (a.i2 > b.i2) return absl::weak_ordering::greater;
2736 return absl::weak_ordering::equivalent;
2737 }
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyThreeWayComp2738 absl::weak_ordering operator()(const int a, const MultiKey b) const {
2739 if (a < b.i1) return absl::weak_ordering::less;
2740 if (a > b.i1) return absl::weak_ordering::greater;
2741 return absl::weak_ordering::equivalent;
2742 }
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyThreeWayComp2743 absl::weak_ordering operator()(const MultiKey a, const int b) const {
2744 if (a.i1 < b) return absl::weak_ordering::less;
2745 if (a.i1 > b) return absl::weak_ordering::greater;
2746 return absl::weak_ordering::equivalent;
2747 }
2748 };
2749
2750 template <typename Compare>
2751 class BtreeMultiKeyTest : public ::testing::Test {};
2752 using MultiKeyComps = ::testing::Types<MultiKeyComp, MultiKeyThreeWayComp>;
2753 TYPED_TEST_SUITE(BtreeMultiKeyTest, MultiKeyComps);
2754
TYPED_TEST(BtreeMultiKeyTest,EqualRange)2755 TYPED_TEST(BtreeMultiKeyTest, EqualRange) {
2756 absl::btree_set<MultiKey, TypeParam> set;
2757 for (int i = 0; i < 100; ++i) {
2758 for (int j = 0; j < 100; ++j) {
2759 set.insert({i, j});
2760 }
2761 }
2762
2763 for (int i = 0; i < 100; ++i) {
2764 auto equal_range = set.equal_range(i);
2765 EXPECT_EQ(equal_range.first->i1, i);
2766 EXPECT_EQ(equal_range.first->i2, 0) << i;
2767 EXPECT_EQ(std::distance(equal_range.first, equal_range.second), 100) << i;
2768 }
2769 }
2770
TYPED_TEST(BtreeMultiKeyTest,Extract)2771 TYPED_TEST(BtreeMultiKeyTest, Extract) {
2772 absl::btree_set<MultiKey, TypeParam> set;
2773 for (int i = 0; i < 100; ++i) {
2774 for (int j = 0; j < 100; ++j) {
2775 set.insert({i, j});
2776 }
2777 }
2778
2779 for (int i = 0; i < 100; ++i) {
2780 auto node_handle = set.extract(i);
2781 EXPECT_EQ(node_handle.value().i1, i);
2782 EXPECT_EQ(node_handle.value().i2, 0) << i;
2783 }
2784
2785 for (int i = 0; i < 100; ++i) {
2786 auto node_handle = set.extract(i);
2787 EXPECT_EQ(node_handle.value().i1, i);
2788 EXPECT_EQ(node_handle.value().i2, 1) << i;
2789 }
2790 }
2791
TYPED_TEST(BtreeMultiKeyTest,Erase)2792 TYPED_TEST(BtreeMultiKeyTest, Erase) {
2793 absl::btree_set<MultiKey, TypeParam> set = {
2794 {1, 1}, {2, 1}, {2, 2}, {3, 1}};
2795 EXPECT_EQ(set.erase(2), 2);
2796 EXPECT_THAT(set, ElementsAre(MultiKey{1, 1}, MultiKey{3, 1}));
2797 }
2798
TYPED_TEST(BtreeMultiKeyTest,Count)2799 TYPED_TEST(BtreeMultiKeyTest, Count) {
2800 const absl::btree_set<MultiKey, TypeParam> set = {
2801 {1, 1}, {2, 1}, {2, 2}, {3, 1}};
2802 EXPECT_EQ(set.count(2), 2);
2803 }
2804
TEST(Btree,SetIteratorsAreConst)2805 TEST(Btree, SetIteratorsAreConst) {
2806 using Set = absl::btree_set<int>;
2807 EXPECT_TRUE(
2808 (std::is_same<typename Set::iterator::reference, const int &>::value));
2809 EXPECT_TRUE(
2810 (std::is_same<typename Set::iterator::pointer, const int *>::value));
2811
2812 using MSet = absl::btree_multiset<int>;
2813 EXPECT_TRUE(
2814 (std::is_same<typename MSet::iterator::reference, const int &>::value));
2815 EXPECT_TRUE(
2816 (std::is_same<typename MSet::iterator::pointer, const int *>::value));
2817 }
2818
TEST(Btree,AllocConstructor)2819 TEST(Btree, AllocConstructor) {
2820 using Alloc = CountingAllocator<int>;
2821 using Set = absl::btree_set<int, std::less<int>, Alloc>;
2822 int64_t bytes_used = 0;
2823 Alloc alloc(&bytes_used);
2824 Set set(alloc);
2825
2826 set.insert({1, 2, 3});
2827
2828 EXPECT_THAT(set, ElementsAre(1, 2, 3));
2829 EXPECT_GT(bytes_used, set.size() * sizeof(int));
2830 }
2831
TEST(Btree,AllocInitializerListConstructor)2832 TEST(Btree, AllocInitializerListConstructor) {
2833 using Alloc = CountingAllocator<int>;
2834 using Set = absl::btree_set<int, std::less<int>, Alloc>;
2835 int64_t bytes_used = 0;
2836 Alloc alloc(&bytes_used);
2837 Set set({1, 2, 3}, alloc);
2838
2839 EXPECT_THAT(set, ElementsAre(1, 2, 3));
2840 EXPECT_GT(bytes_used, set.size() * sizeof(int));
2841 }
2842
TEST(Btree,AllocRangeConstructor)2843 TEST(Btree, AllocRangeConstructor) {
2844 using Alloc = CountingAllocator<int>;
2845 using Set = absl::btree_set<int, std::less<int>, Alloc>;
2846 int64_t bytes_used = 0;
2847 Alloc alloc(&bytes_used);
2848 std::vector<int> v = {1, 2, 3};
2849 Set set(v.begin(), v.end(), alloc);
2850
2851 EXPECT_THAT(set, ElementsAre(1, 2, 3));
2852 EXPECT_GT(bytes_used, set.size() * sizeof(int));
2853 }
2854
TEST(Btree,AllocCopyConstructor)2855 TEST(Btree, AllocCopyConstructor) {
2856 using Alloc = CountingAllocator<int>;
2857 using Set = absl::btree_set<int, std::less<int>, Alloc>;
2858 int64_t bytes_used1 = 0;
2859 Alloc alloc1(&bytes_used1);
2860 Set set1(alloc1);
2861
2862 set1.insert({1, 2, 3});
2863
2864 int64_t bytes_used2 = 0;
2865 Alloc alloc2(&bytes_used2);
2866 Set set2(set1, alloc2);
2867
2868 EXPECT_THAT(set1, ElementsAre(1, 2, 3));
2869 EXPECT_THAT(set2, ElementsAre(1, 2, 3));
2870 EXPECT_GT(bytes_used1, set1.size() * sizeof(int));
2871 EXPECT_EQ(bytes_used1, bytes_used2);
2872 }
2873
TEST(Btree,AllocMoveConstructor_SameAlloc)2874 TEST(Btree, AllocMoveConstructor_SameAlloc) {
2875 using Alloc = CountingAllocator<int>;
2876 using Set = absl::btree_set<int, std::less<int>, Alloc>;
2877 int64_t bytes_used = 0;
2878 Alloc alloc(&bytes_used);
2879 Set set1(alloc);
2880
2881 set1.insert({1, 2, 3});
2882
2883 const int64_t original_bytes_used = bytes_used;
2884 EXPECT_GT(original_bytes_used, set1.size() * sizeof(int));
2885
2886 Set set2(std::move(set1), alloc);
2887
2888 EXPECT_THAT(set2, ElementsAre(1, 2, 3));
2889 EXPECT_EQ(bytes_used, original_bytes_used);
2890 }
2891
TEST(Btree,AllocMoveConstructor_DifferentAlloc)2892 TEST(Btree, AllocMoveConstructor_DifferentAlloc) {
2893 using Alloc = CountingAllocator<int>;
2894 using Set = absl::btree_set<int, std::less<int>, Alloc>;
2895 int64_t bytes_used1 = 0;
2896 Alloc alloc1(&bytes_used1);
2897 Set set1(alloc1);
2898
2899 set1.insert({1, 2, 3});
2900
2901 const int64_t original_bytes_used = bytes_used1;
2902 EXPECT_GT(original_bytes_used, set1.size() * sizeof(int));
2903
2904 int64_t bytes_used2 = 0;
2905 Alloc alloc2(&bytes_used2);
2906 Set set2(std::move(set1), alloc2);
2907
2908 EXPECT_THAT(set2, ElementsAre(1, 2, 3));
2909 // We didn't free these bytes allocated by `set1` yet.
2910 EXPECT_EQ(bytes_used1, original_bytes_used);
2911 EXPECT_EQ(bytes_used2, original_bytes_used);
2912 }
2913
IntCmp(const int a,const int b)2914 bool IntCmp(const int a, const int b) { return a < b; }
2915
TEST(Btree,SupportsFunctionPtrComparator)2916 TEST(Btree, SupportsFunctionPtrComparator) {
2917 absl::btree_set<int, decltype(IntCmp) *> set(IntCmp);
2918 set.insert({1, 2, 3});
2919 EXPECT_THAT(set, ElementsAre(1, 2, 3));
2920 EXPECT_TRUE(set.key_comp()(1, 2));
2921 EXPECT_TRUE(set.value_comp()(1, 2));
2922
2923 absl::btree_map<int, int, decltype(IntCmp) *> map(&IntCmp);
2924 map[1] = 1;
2925 EXPECT_THAT(map, ElementsAre(Pair(1, 1)));
2926 EXPECT_TRUE(map.key_comp()(1, 2));
2927 EXPECT_TRUE(map.value_comp()(std::make_pair(1, 1), std::make_pair(2, 2)));
2928 }
2929
2930 template <typename Compare>
2931 struct TransparentPassThroughComp {
2932 using is_transparent = void;
2933
2934 // This will fail compilation if we attempt a comparison that Compare does not
2935 // support, and the failure will happen inside the function implementation so
2936 // it can't be avoided by using SFINAE on this comparator.
2937 template <typename T, typename U>
operator ()absl::container_internal::__anon7e8713fe0311::TransparentPassThroughComp2938 bool operator()(const T &lhs, const U &rhs) const {
2939 return Compare()(lhs, rhs);
2940 }
2941 };
2942
TEST(Btree,SupportsTransparentComparatorThatDoesNotImplementAllVisibleOperators)2943 TEST(Btree,
2944 SupportsTransparentComparatorThatDoesNotImplementAllVisibleOperators) {
2945 absl::btree_set<MultiKey, TransparentPassThroughComp<MultiKeyComp>> set;
2946 set.insert(MultiKey{1, 2});
2947 EXPECT_TRUE(set.contains(1));
2948 }
2949
TEST(Btree,ConstructImplicitlyWithUnadaptedComparator)2950 TEST(Btree, ConstructImplicitlyWithUnadaptedComparator) {
2951 absl::btree_set<MultiKey, MultiKeyComp> set = {{}, MultiKeyComp{}};
2952 }
2953
TEST(Btree,InvalidComparatorsCaught)2954 TEST(Btree, InvalidComparatorsCaught) {
2955 if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
2956
2957 {
2958 struct ZeroAlwaysLessCmp {
2959 bool operator()(int lhs, int rhs) const {
2960 if (lhs == 0) return true;
2961 return lhs < rhs;
2962 }
2963 };
2964 absl::btree_set<int, ZeroAlwaysLessCmp> set;
2965 EXPECT_DEATH(set.insert({0, 1, 2}), "is_self_equivalent");
2966 }
2967 {
2968 struct ThreeWayAlwaysLessCmp {
2969 absl::weak_ordering operator()(int, int) const {
2970 return absl::weak_ordering::less;
2971 }
2972 };
2973 absl::btree_set<int, ThreeWayAlwaysLessCmp> set;
2974 EXPECT_DEATH(set.insert({0, 1, 2}), "is_self_equivalent");
2975 }
2976 {
2977 struct SumGreaterZeroCmp {
2978 bool operator()(int lhs, int rhs) const {
2979 // First, do equivalence correctly - so we can test later condition.
2980 if (lhs == rhs) return false;
2981 return lhs + rhs > 0;
2982 }
2983 };
2984 absl::btree_set<int, SumGreaterZeroCmp> set;
2985 // Note: '!' only needs to be escaped when it's the first character.
2986 EXPECT_DEATH(set.insert({0, 1, 2}),
2987 R"regex(\!lhs_comp_rhs \|\| !comp\(\)\(rhs, lhs\))regex");
2988 }
2989 {
2990 struct ThreeWaySumGreaterZeroCmp {
2991 absl::weak_ordering operator()(int lhs, int rhs) const {
2992 // First, do equivalence correctly - so we can test later condition.
2993 if (lhs == rhs) return absl::weak_ordering::equivalent;
2994
2995 if (lhs + rhs > 0) return absl::weak_ordering::less;
2996 if (lhs + rhs == 0) return absl::weak_ordering::equivalent;
2997 return absl::weak_ordering::greater;
2998 }
2999 };
3000 absl::btree_set<int, ThreeWaySumGreaterZeroCmp> set;
3001 EXPECT_DEATH(set.insert({0, 1, 2}), "lhs_comp_rhs < 0 -> rhs_comp_lhs > 0");
3002 }
3003 // Verify that we detect cases of comparators that violate transitivity.
3004 // When the comparators below check for the presence of an optional field,
3005 // they violate transitivity because instances that have the optional field
3006 // compare differently with each other from how they compare with instances
3007 // that don't have the optional field.
3008 struct ClockTime {
3009 absl::optional<int> hour;
3010 int minute;
3011 };
3012 // `comp(a,b) && comp(b,c) && !comp(a,c)` violates transitivity.
3013 ClockTime a = {absl::nullopt, 1};
3014 ClockTime b = {2, 5};
3015 ClockTime c = {6, 0};
3016 {
3017 struct NonTransitiveTimeCmp {
3018 bool operator()(ClockTime lhs, ClockTime rhs) const {
3019 if (lhs.hour.has_value() && rhs.hour.has_value() &&
3020 *lhs.hour != *rhs.hour) {
3021 return *lhs.hour < *rhs.hour;
3022 }
3023 return lhs.minute < rhs.minute;
3024 }
3025 };
3026 NonTransitiveTimeCmp cmp;
3027 ASSERT_TRUE(cmp(a, b) && cmp(b, c) && !cmp(a, c));
3028 absl::btree_set<ClockTime, NonTransitiveTimeCmp> set;
3029 EXPECT_DEATH(set.insert({a, b, c}), "is_ordered_correctly");
3030 absl::btree_multiset<ClockTime, NonTransitiveTimeCmp> mset;
3031 EXPECT_DEATH(mset.insert({a, a, b, b, c, c}), "is_ordered_correctly");
3032 }
3033 {
3034 struct ThreeWayNonTransitiveTimeCmp {
3035 absl::weak_ordering operator()(ClockTime lhs, ClockTime rhs) const {
3036 if (lhs.hour.has_value() && rhs.hour.has_value() &&
3037 *lhs.hour != *rhs.hour) {
3038 return *lhs.hour < *rhs.hour ? absl::weak_ordering::less
3039 : absl::weak_ordering::greater;
3040 }
3041 return lhs.minute < rhs.minute ? absl::weak_ordering::less
3042 : lhs.minute == rhs.minute ? absl::weak_ordering::equivalent
3043 : absl::weak_ordering::greater;
3044 }
3045 };
3046 ThreeWayNonTransitiveTimeCmp cmp;
3047 ASSERT_TRUE(cmp(a, b) < 0 && cmp(b, c) < 0 && cmp(a, c) > 0);
3048 absl::btree_set<ClockTime, ThreeWayNonTransitiveTimeCmp> set;
3049 EXPECT_DEATH(set.insert({a, b, c}), "is_ordered_correctly");
3050 absl::btree_multiset<ClockTime, ThreeWayNonTransitiveTimeCmp> mset;
3051 EXPECT_DEATH(mset.insert({a, a, b, b, c, c}), "is_ordered_correctly");
3052 }
3053 }
3054
TEST(Btree,MutatedKeysCaught)3055 TEST(Btree, MutatedKeysCaught) {
3056 if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
3057
3058 struct IntPtrCmp {
3059 bool operator()(int *lhs, int *rhs) const { return *lhs < *rhs; }
3060 };
3061 {
3062 absl::btree_set<int *, IntPtrCmp> set;
3063 int arr[] = {0, 1, 2};
3064 set.insert({&arr[0], &arr[1], &arr[2]});
3065 arr[0] = 100;
3066 EXPECT_DEATH(set.insert(&arr[0]), "is_ordered_correctly");
3067 }
3068 {
3069 absl::btree_multiset<int *, IntPtrCmp> set;
3070 int arr[] = {0, 1, 2};
3071 set.insert({&arr[0], &arr[0], &arr[1], &arr[1], &arr[2], &arr[2]});
3072 arr[0] = 100;
3073 EXPECT_DEATH(set.insert(&arr[0]), "is_ordered_correctly");
3074 }
3075 }
3076
3077 #ifndef _MSC_VER
3078 // This test crashes on MSVC.
TEST(Btree,InvalidIteratorUse)3079 TEST(Btree, InvalidIteratorUse) {
3080 if (!BtreeGenerationsEnabled())
3081 GTEST_SKIP() << "Generation validation for iterators is disabled.";
3082
3083 // Invalid memory use can trigger use-after-free in ASan, HWASAN or
3084 // invalidated iterator assertions.
3085 constexpr const char *kInvalidMemoryDeathMessage =
3086 "use-after-free|invalidated iterator";
3087
3088 {
3089 absl::btree_set<int> set;
3090 for (int i = 0; i < 10; ++i) set.insert(i);
3091 auto it = set.begin();
3092 set.erase(it++);
3093 EXPECT_DEATH(set.erase(it++), kInvalidMemoryDeathMessage);
3094 }
3095 {
3096 absl::btree_set<int> set;
3097 for (int i = 0; i < 10; ++i) set.insert(i);
3098 auto it = set.insert(20).first;
3099 set.insert(30);
3100 EXPECT_DEATH(*it, kInvalidMemoryDeathMessage);
3101 }
3102 {
3103 absl::btree_set<int> set;
3104 for (int i = 0; i < 10000; ++i) set.insert(i);
3105 auto it = set.find(5000);
3106 ASSERT_NE(it, set.end());
3107 set.erase(1);
3108 EXPECT_DEATH(*it, kInvalidMemoryDeathMessage);
3109 }
3110 {
3111 absl::btree_set<int> set;
3112 for (int i = 0; i < 10; ++i) set.insert(i);
3113 auto it = set.insert(20).first;
3114 set.insert(30);
3115 EXPECT_DEATH(void(it == set.begin()), kInvalidMemoryDeathMessage);
3116 EXPECT_DEATH(void(set.begin() == it), kInvalidMemoryDeathMessage);
3117 }
3118 }
3119 #endif
3120
3121 class OnlyConstructibleByAllocator {
OnlyConstructibleByAllocator(int i)3122 explicit OnlyConstructibleByAllocator(int i) : i_(i) {}
3123
3124 public:
OnlyConstructibleByAllocator(const OnlyConstructibleByAllocator & other)3125 OnlyConstructibleByAllocator(const OnlyConstructibleByAllocator &other)
3126 : i_(other.i_) {}
operator =(const OnlyConstructibleByAllocator & other)3127 OnlyConstructibleByAllocator &operator=(
3128 const OnlyConstructibleByAllocator &other) {
3129 i_ = other.i_;
3130 return *this;
3131 }
Get() const3132 int Get() const { return i_; }
operator ==(int i) const3133 bool operator==(int i) const { return i_ == i; }
3134
3135 private:
3136 template <typename T>
3137 friend class OnlyConstructibleAllocator;
3138
3139 int i_;
3140 };
3141
3142 template <typename T = OnlyConstructibleByAllocator>
3143 class OnlyConstructibleAllocator : public std::allocator<T> {
3144 public:
3145 OnlyConstructibleAllocator() = default;
3146 template <class U>
OnlyConstructibleAllocator(const OnlyConstructibleAllocator<U> &)3147 explicit OnlyConstructibleAllocator(const OnlyConstructibleAllocator<U> &) {}
3148
construct(OnlyConstructibleByAllocator * p,int i)3149 void construct(OnlyConstructibleByAllocator *p, int i) {
3150 new (p) OnlyConstructibleByAllocator(i);
3151 }
3152 template <typename Pair>
construct(Pair * p,const int i)3153 void construct(Pair *p, const int i) {
3154 OnlyConstructibleByAllocator only(i);
3155 new (p) Pair(std::move(only), i);
3156 }
3157
3158 template <class U>
3159 struct rebind {
3160 using other = OnlyConstructibleAllocator<U>;
3161 };
3162 };
3163
3164 struct OnlyConstructibleByAllocatorComp {
3165 using is_transparent = void;
operator ()absl::container_internal::__anon7e8713fe0311::OnlyConstructibleByAllocatorComp3166 bool operator()(OnlyConstructibleByAllocator a,
3167 OnlyConstructibleByAllocator b) const {
3168 return a.Get() < b.Get();
3169 }
operator ()absl::container_internal::__anon7e8713fe0311::OnlyConstructibleByAllocatorComp3170 bool operator()(int a, OnlyConstructibleByAllocator b) const {
3171 return a < b.Get();
3172 }
operator ()absl::container_internal::__anon7e8713fe0311::OnlyConstructibleByAllocatorComp3173 bool operator()(OnlyConstructibleByAllocator a, int b) const {
3174 return a.Get() < b;
3175 }
3176 };
3177
TEST(Btree,OnlyConstructibleByAllocatorType)3178 TEST(Btree, OnlyConstructibleByAllocatorType) {
3179 const std::array<int, 2> arr = {3, 4};
3180 {
3181 absl::btree_set<OnlyConstructibleByAllocator,
3182 OnlyConstructibleByAllocatorComp,
3183 OnlyConstructibleAllocator<>>
3184 set;
3185 set.emplace(1);
3186 set.emplace_hint(set.end(), 2);
3187 set.insert(arr.begin(), arr.end());
3188 EXPECT_THAT(set, ElementsAre(1, 2, 3, 4));
3189 }
3190 {
3191 absl::btree_multiset<OnlyConstructibleByAllocator,
3192 OnlyConstructibleByAllocatorComp,
3193 OnlyConstructibleAllocator<>>
3194 set;
3195 set.emplace(1);
3196 set.emplace_hint(set.end(), 2);
3197 // TODO(ezb): fix insert_multi to allow this to compile.
3198 // set.insert(arr.begin(), arr.end());
3199 EXPECT_THAT(set, ElementsAre(1, 2));
3200 }
3201 {
3202 absl::btree_map<OnlyConstructibleByAllocator, int,
3203 OnlyConstructibleByAllocatorComp,
3204 OnlyConstructibleAllocator<>>
3205 map;
3206 map.emplace(1);
3207 map.emplace_hint(map.end(), 2);
3208 map.insert(arr.begin(), arr.end());
3209 EXPECT_THAT(map,
3210 ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3), Pair(4, 4)));
3211 }
3212 {
3213 absl::btree_multimap<OnlyConstructibleByAllocator, int,
3214 OnlyConstructibleByAllocatorComp,
3215 OnlyConstructibleAllocator<>>
3216 map;
3217 map.emplace(1);
3218 map.emplace_hint(map.end(), 2);
3219 // TODO(ezb): fix insert_multi to allow this to compile.
3220 // map.insert(arr.begin(), arr.end());
3221 EXPECT_THAT(map, ElementsAre(Pair(1, 1), Pair(2, 2)));
3222 }
3223 }
3224
3225 class NotAssignable {
3226 public:
NotAssignable(int i)3227 explicit NotAssignable(int i) : i_(i) {}
NotAssignable(const NotAssignable & other)3228 NotAssignable(const NotAssignable &other) : i_(other.i_) {}
3229 NotAssignable &operator=(NotAssignable &&other) = delete;
Get() const3230 int Get() const { return i_; }
operator ==(int i) const3231 bool operator==(int i) const { return i_ == i; }
operator <(NotAssignable a,NotAssignable b)3232 friend bool operator<(NotAssignable a, NotAssignable b) {
3233 return a.i_ < b.i_;
3234 }
3235
3236 private:
3237 int i_;
3238 };
3239
TEST(Btree,NotAssignableType)3240 TEST(Btree, NotAssignableType) {
3241 {
3242 absl::btree_set<NotAssignable> set;
3243 set.emplace(1);
3244 set.emplace_hint(set.end(), 2);
3245 set.insert(NotAssignable(3));
3246 set.insert(set.end(), NotAssignable(4));
3247 EXPECT_THAT(set, ElementsAre(1, 2, 3, 4));
3248 set.erase(set.begin());
3249 EXPECT_THAT(set, ElementsAre(2, 3, 4));
3250 }
3251 {
3252 absl::btree_multiset<NotAssignable> set;
3253 set.emplace(1);
3254 set.emplace_hint(set.end(), 2);
3255 set.insert(NotAssignable(2));
3256 set.insert(set.end(), NotAssignable(3));
3257 EXPECT_THAT(set, ElementsAre(1, 2, 2, 3));
3258 set.erase(set.begin());
3259 EXPECT_THAT(set, ElementsAre(2, 2, 3));
3260 }
3261 {
3262 absl::btree_map<NotAssignable, int> map;
3263 map.emplace(NotAssignable(1), 1);
3264 map.emplace_hint(map.end(), NotAssignable(2), 2);
3265 map.insert({NotAssignable(3), 3});
3266 map.insert(map.end(), {NotAssignable(4), 4});
3267 EXPECT_THAT(map,
3268 ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3), Pair(4, 4)));
3269 map.erase(map.begin());
3270 EXPECT_THAT(map, ElementsAre(Pair(2, 2), Pair(3, 3), Pair(4, 4)));
3271 }
3272 {
3273 absl::btree_multimap<NotAssignable, int> map;
3274 map.emplace(NotAssignable(1), 1);
3275 map.emplace_hint(map.end(), NotAssignable(2), 2);
3276 map.insert({NotAssignable(2), 3});
3277 map.insert(map.end(), {NotAssignable(3), 3});
3278 EXPECT_THAT(map,
3279 ElementsAre(Pair(1, 1), Pair(2, 2), Pair(2, 3), Pair(3, 3)));
3280 map.erase(map.begin());
3281 EXPECT_THAT(map, ElementsAre(Pair(2, 2), Pair(2, 3), Pair(3, 3)));
3282 }
3283 }
3284
3285 struct ArenaLike {
3286 void* recycled = nullptr;
3287 size_t recycled_size = 0;
3288 };
3289
3290 // A very simple implementation of arena allocation.
3291 template <typename T>
3292 class ArenaLikeAllocator : public std::allocator<T> {
3293 public:
3294 // Standard library containers require the ability to allocate objects of
3295 // different types which they can do so via rebind.other.
3296 template <typename U>
3297 struct rebind {
3298 using other = ArenaLikeAllocator<U>;
3299 };
3300
ArenaLikeAllocator(ArenaLike * arena)3301 explicit ArenaLikeAllocator(ArenaLike* arena) noexcept : arena_(arena) {}
3302
~ArenaLikeAllocator()3303 ~ArenaLikeAllocator() {
3304 if (arena_->recycled != nullptr) {
3305 delete [] static_cast<T*>(arena_->recycled);
3306 arena_->recycled = nullptr;
3307 }
3308 }
3309
3310 template<typename U>
ArenaLikeAllocator(const ArenaLikeAllocator<U> & other)3311 explicit ArenaLikeAllocator(const ArenaLikeAllocator<U>& other) noexcept
3312 : arena_(other.arena_) {}
3313
allocate(size_t num_objects,const void * =nullptr)3314 T* allocate(size_t num_objects, const void* = nullptr) {
3315 size_t size = num_objects * sizeof(T);
3316 if (arena_->recycled != nullptr && arena_->recycled_size == size) {
3317 T* result = static_cast<T*>(arena_->recycled);
3318 arena_->recycled = nullptr;
3319 return result;
3320 }
3321 return new T[num_objects];
3322 }
3323
deallocate(T * p,size_t num_objects)3324 void deallocate(T* p, size_t num_objects) {
3325 size_t size = num_objects * sizeof(T);
3326
3327 // Simulate writing to the freed memory as an actual arena allocator might
3328 // do. This triggers an error report if the memory is poisoned.
3329 memset(p, 0xde, size);
3330
3331 if (arena_->recycled == nullptr) {
3332 arena_->recycled = p;
3333 arena_->recycled_size = size;
3334 } else {
3335 delete [] p;
3336 }
3337 }
3338
3339 ArenaLike* arena_;
3340 };
3341
3342 // This test verifies that an arena allocator that reuses memory will not be
3343 // asked to free poisoned BTree memory.
TEST(Btree,ReusePoisonMemory)3344 TEST(Btree, ReusePoisonMemory) {
3345 using Alloc = ArenaLikeAllocator<int64_t>;
3346 using Set = absl::btree_set<int64_t, std::less<int64_t>, Alloc>;
3347 ArenaLike arena;
3348 Alloc alloc(&arena);
3349 Set set(alloc);
3350
3351 set.insert(0);
3352 set.erase(0);
3353 set.insert(0);
3354 }
3355
TEST(Btree,IteratorSubtraction)3356 TEST(Btree, IteratorSubtraction) {
3357 absl::BitGen bitgen;
3358 std::vector<int> vec;
3359 // Randomize the set's insertion order so the nodes aren't all full.
3360 for (int i = 0; i < 1000000; ++i) vec.push_back(i);
3361 absl::c_shuffle(vec, bitgen);
3362
3363 absl::btree_set<int> set;
3364 for (int i : vec) set.insert(i);
3365
3366 for (int i = 0; i < 1000; ++i) {
3367 size_t begin = absl::Uniform(bitgen, 0u, set.size());
3368 size_t end = absl::Uniform(bitgen, begin, set.size());
3369 ASSERT_EQ(end - begin, set.find(end) - set.find(begin))
3370 << begin << " " << end;
3371 }
3372 }
3373
TEST(Btree,DereferencingEndIterator)3374 TEST(Btree, DereferencingEndIterator) {
3375 if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
3376
3377 absl::btree_set<int> set;
3378 for (int i = 0; i < 1000; ++i) set.insert(i);
3379 EXPECT_DEATH(*set.end(), R"regex(Dereferencing end\(\) iterator)regex");
3380 }
3381
TEST(Btree,InvalidIteratorComparison)3382 TEST(Btree, InvalidIteratorComparison) {
3383 if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
3384
3385 absl::btree_set<int> set1, set2;
3386 for (int i = 0; i < 1000; ++i) {
3387 set1.insert(i);
3388 set2.insert(i);
3389 }
3390
3391 constexpr const char *kValueInitDeathMessage =
3392 "Comparing default-constructed iterator with .*non-default-constructed "
3393 "iterator";
3394 typename absl::btree_set<int>::iterator iter1, iter2;
3395 EXPECT_EQ(iter1, iter2);
3396 EXPECT_DEATH(void(set1.begin() == iter1), kValueInitDeathMessage);
3397 EXPECT_DEATH(void(iter1 == set1.begin()), kValueInitDeathMessage);
3398
3399 constexpr const char *kDifferentContainerDeathMessage =
3400 "Comparing iterators from different containers";
3401 iter1 = set1.begin();
3402 iter2 = set2.begin();
3403 EXPECT_DEATH(void(iter1 == iter2), kDifferentContainerDeathMessage);
3404 EXPECT_DEATH(void(iter2 == iter1), kDifferentContainerDeathMessage);
3405 }
3406
TEST(Btree,InvalidPointerUse)3407 TEST(Btree, InvalidPointerUse) {
3408 if (!kAsan)
3409 GTEST_SKIP() << "We only detect invalid pointer use in ASan mode.";
3410
3411 absl::btree_set<int> set;
3412 set.insert(0);
3413 const int *ptr = &*set.begin();
3414 set.insert(1);
3415 EXPECT_DEATH(std::cout << *ptr, "use-after-free");
3416 size_t slots_per_node = BtreeNodePeer::GetNumSlotsPerNode<decltype(set)>();
3417 for (int i = 2; i < slots_per_node - 1; ++i) set.insert(i);
3418 ptr = &*set.begin();
3419 set.insert(static_cast<int>(slots_per_node));
3420 EXPECT_DEATH(std::cout << *ptr, "use-after-free");
3421 }
3422
3423 template<typename Set>
TestBasicFunctionality(Set set)3424 void TestBasicFunctionality(Set set) {
3425 using value_type = typename Set::value_type;
3426 for (int i = 0; i < 100; ++i) { set.insert(value_type(i)); }
3427 for (int i = 50; i < 100; ++i) { set.erase(value_type(i)); }
3428 auto it = set.begin();
3429 for (int i = 0; i < 50; ++i, ++it) {
3430 ASSERT_EQ(set.find(value_type(i)), it) << i;
3431 }
3432 }
3433
3434 template<size_t align>
3435 struct alignas(align) OveralignedKey {
OveralignedKeyabsl::container_internal::__anon7e8713fe0311::OveralignedKey3436 explicit OveralignedKey(int i) : key(i) {}
operator <absl::container_internal::__anon7e8713fe0311::OveralignedKey3437 bool operator<(const OveralignedKey &other) const { return key < other.key; }
3438 int key = 0;
3439 };
3440
TEST(Btree,OveralignedKey)3441 TEST(Btree, OveralignedKey) {
3442 // Test basic functionality with both even and odd numbers of slots per node.
3443 // The goal here is to detect cases where alignment may be incorrect.
3444 TestBasicFunctionality(
3445 SizedBtreeSet<OveralignedKey<16>, /*TargetValuesPerNode=*/8>());
3446 TestBasicFunctionality(
3447 SizedBtreeSet<OveralignedKey<16>, /*TargetValuesPerNode=*/9>());
3448 }
3449
TEST(Btree,FieldTypeEqualsSlotType)3450 TEST(Btree, FieldTypeEqualsSlotType) {
3451 // This breaks if we try to do layout_type::Pointer<slot_type> because
3452 // slot_type is the same as field_type.
3453 using set_type = absl::btree_set<uint8_t>;
3454 static_assert(BtreeNodePeer::FieldTypeEqualsSlotType<set_type>(), "");
3455 TestBasicFunctionality(set_type());
3456 }
3457
3458 } // namespace
3459 } // namespace container_internal
3460 ABSL_NAMESPACE_END
3461 } // namespace absl
3462