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