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