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