btree_set.h (29537B)
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 // ----------------------------------------------------------------------------- 16 // File: btree_set.h 17 // ----------------------------------------------------------------------------- 18 // 19 // This header file defines B-tree sets: sorted associative containers of 20 // values. 21 // 22 // * `absl::btree_set<>` 23 // * `absl::btree_multiset<>` 24 // 25 // These B-tree types are similar to the corresponding types in the STL 26 // (`std::set` and `std::multiset`) and generally conform to the STL interfaces 27 // of those types. However, because they are implemented using B-trees, they 28 // are more efficient in most situations. 29 // 30 // Unlike `std::set` and `std::multiset`, which are commonly implemented using 31 // red-black tree nodes, B-tree sets use more generic B-tree nodes able to hold 32 // multiple values per node. Holding multiple values per node often makes 33 // B-tree sets perform better than their `std::set` counterparts, because 34 // multiple entries can be checked within the same cache hit. 35 // 36 // However, these types should not be considered drop-in replacements for 37 // `std::set` and `std::multiset` as there are some API differences, which are 38 // noted in this header file. The most consequential differences with respect to 39 // migrating to b-tree from the STL types are listed in the next paragraph. 40 // Other API differences are minor. 41 // 42 // Importantly, insertions and deletions may invalidate outstanding iterators, 43 // pointers, and references to elements. Such invalidations are typically only 44 // an issue if insertion and deletion operations are interleaved with the use of 45 // more than one iterator, pointer, or reference simultaneously. For this 46 // reason, `insert()`, `erase()`, and `extract_and_get_next()` return a valid 47 // iterator at the current position. 48 // 49 // There are other API differences: first, btree iterators can be subtracted, 50 // and this is faster than using `std::distance`. Additionally, btree 51 // iterators can be advanced via `operator+=` and `operator-=`, which is faster 52 // than using `std::advance`. 53 // 54 // B-tree sets are not exception-safe. 55 56 #ifndef ABSL_CONTAINER_BTREE_SET_H_ 57 #define ABSL_CONTAINER_BTREE_SET_H_ 58 59 #include "absl/base/attributes.h" 60 #include "absl/container/internal/btree.h" // IWYU pragma: export 61 #include "absl/container/internal/btree_container.h" // IWYU pragma: export 62 63 namespace absl { 64 ABSL_NAMESPACE_BEGIN 65 66 namespace container_internal { 67 68 template <typename Key> 69 struct set_slot_policy; 70 71 template <typename Key, typename Compare, typename Alloc, int TargetNodeSize, 72 bool IsMulti> 73 struct set_params; 74 75 } // namespace container_internal 76 77 // absl::btree_set<> 78 // 79 // An `absl::btree_set<K>` is an ordered associative container of unique key 80 // values designed to be a more efficient replacement for `std::set` (in most 81 // cases). 82 // 83 // Keys are sorted using an (optional) comparison function, which defaults to 84 // `std::less<K>`. 85 // 86 // An `absl::btree_set<K>` uses a default allocator of `std::allocator<K>` to 87 // allocate (and deallocate) nodes, and construct and destruct values within 88 // those nodes. You may instead specify a custom allocator `A` (which in turn 89 // requires specifying a custom comparator `C`) as in 90 // `absl::btree_set<K, C, A>`. 91 // 92 template <typename Key, typename Compare = std::less<Key>, 93 typename Alloc = std::allocator<Key>> 94 class ABSL_ATTRIBUTE_OWNER btree_set 95 : public container_internal::btree_set_container< 96 container_internal::btree<container_internal::set_params< 97 Key, Compare, Alloc, /*TargetNodeSize=*/256, 98 /*IsMulti=*/false>>> { 99 using Base = typename btree_set::btree_set_container; 100 101 public: 102 // Constructors and Assignment Operators 103 // 104 // A `btree_set` supports the same overload set as `std::set` 105 // for construction and assignment: 106 // 107 // * Default constructor 108 // 109 // absl::btree_set<std::string> set1; 110 // 111 // * Initializer List constructor 112 // 113 // absl::btree_set<std::string> set2 = 114 // {{"huey"}, {"dewey"}, {"louie"},}; 115 // 116 // * Copy constructor 117 // 118 // absl::btree_set<std::string> set3(set2); 119 // 120 // * Copy assignment operator 121 // 122 // absl::btree_set<std::string> set4; 123 // set4 = set3; 124 // 125 // * Move constructor 126 // 127 // // Move is guaranteed efficient 128 // absl::btree_set<std::string> set5(std::move(set4)); 129 // 130 // * Move assignment operator 131 // 132 // // May be efficient if allocators are compatible 133 // absl::btree_set<std::string> set6; 134 // set6 = std::move(set5); 135 // 136 // * Range constructor 137 // 138 // std::vector<std::string> v = {"a", "b"}; 139 // absl::btree_set<std::string> set7(v.begin(), v.end()); 140 btree_set() {} 141 using Base::Base; 142 143 // btree_set::begin() 144 // 145 // Returns an iterator to the beginning of the `btree_set`. 146 using Base::begin; 147 148 // btree_set::cbegin() 149 // 150 // Returns a const iterator to the beginning of the `btree_set`. 151 using Base::cbegin; 152 153 // btree_set::end() 154 // 155 // Returns an iterator to the end of the `btree_set`. 156 using Base::end; 157 158 // btree_set::cend() 159 // 160 // Returns a const iterator to the end of the `btree_set`. 161 using Base::cend; 162 163 // btree_set::empty() 164 // 165 // Returns whether or not the `btree_set` is empty. 166 using Base::empty; 167 168 // btree_set::max_size() 169 // 170 // Returns the largest theoretical possible number of elements within a 171 // `btree_set` under current memory constraints. This value can be thought 172 // of as the largest value of `std::distance(begin(), end())` for a 173 // `btree_set<Key>`. 174 using Base::max_size; 175 176 // btree_set::size() 177 // 178 // Returns the number of elements currently within the `btree_set`. 179 using Base::size; 180 181 // btree_set::clear() 182 // 183 // Removes all elements from the `btree_set`. Invalidates any references, 184 // pointers, or iterators referring to contained elements. 185 using Base::clear; 186 187 // btree_set::erase() 188 // 189 // Erases elements within the `btree_set`. Overloads are listed below. 190 // 191 // iterator erase(iterator position): 192 // iterator erase(const_iterator position): 193 // 194 // Erases the element at `position` of the `btree_set`, returning 195 // the iterator pointing to the element after the one that was erased 196 // (or end() if none exists). 197 // 198 // iterator erase(const_iterator first, const_iterator last): 199 // 200 // Erases the elements in the open interval [`first`, `last`), returning 201 // the iterator pointing to the element after the interval that was erased 202 // (or end() if none exists). 203 // 204 // template <typename K> size_type erase(const K& key): 205 // 206 // Erases the element with the matching key, if it exists, returning the 207 // number of elements erased (0 or 1). 208 using Base::erase; 209 210 // btree_set::insert() 211 // 212 // Inserts an element of the specified value into the `btree_set`, 213 // returning an iterator pointing to the newly inserted element, provided that 214 // an element with the given key does not already exist. If an insertion 215 // occurs, any references, pointers, or iterators are invalidated. 216 // Overloads are listed below. 217 // 218 // std::pair<iterator,bool> insert(const value_type& value): 219 // 220 // Inserts a value into the `btree_set`. Returns a pair consisting of an 221 // iterator to the inserted element (or to the element that prevented the 222 // insertion) and a bool denoting whether the insertion took place. 223 // 224 // std::pair<iterator,bool> insert(value_type&& value): 225 // 226 // Inserts a moveable value into the `btree_set`. Returns a pair 227 // consisting of an iterator to the inserted element (or to the element that 228 // prevented the insertion) and a bool denoting whether the insertion took 229 // place. 230 // 231 // iterator insert(const_iterator hint, const value_type& value): 232 // iterator insert(const_iterator hint, value_type&& value): 233 // 234 // Inserts a value, using the position of `hint` as a non-binding suggestion 235 // for where to begin the insertion search. Returns an iterator to the 236 // inserted element, or to the existing element that prevented the 237 // insertion. 238 // 239 // void insert(InputIterator first, InputIterator last): 240 // 241 // Inserts a range of values [`first`, `last`). 242 // 243 // void insert(std::initializer_list<init_type> ilist): 244 // 245 // Inserts the elements within the initializer list `ilist`. 246 using Base::insert; 247 248 // btree_set::emplace() 249 // 250 // Inserts an element of the specified value by constructing it in-place 251 // within the `btree_set`, provided that no element with the given key 252 // already exists. 253 // 254 // The element may be constructed even if there already is an element with the 255 // key in the container, in which case the newly constructed element will be 256 // destroyed immediately. 257 // 258 // If an insertion occurs, any references, pointers, or iterators are 259 // invalidated. 260 using Base::emplace; 261 262 // btree_set::emplace_hint() 263 // 264 // Inserts an element of the specified value by constructing it in-place 265 // within the `btree_set`, using the position of `hint` as a non-binding 266 // suggestion for where to begin the insertion search, and only inserts 267 // provided that no element with the given key already exists. 268 // 269 // The element may be constructed even if there already is an element with the 270 // key in the container, in which case the newly constructed element will be 271 // destroyed immediately. 272 // 273 // If an insertion occurs, any references, pointers, or iterators are 274 // invalidated. 275 using Base::emplace_hint; 276 277 // btree_set::extract() 278 // 279 // Extracts the indicated element, erasing it in the process, and returns it 280 // as a C++17-compatible node handle. Any references, pointers, or iterators 281 // are invalidated. Overloads are listed below. 282 // 283 // node_type extract(const_iterator position): 284 // 285 // Extracts the element at the indicated position and returns a node handle 286 // owning that extracted data. 287 // 288 // template <typename K> node_type extract(const K& k): 289 // 290 // Extracts the element with the key matching the passed key value and 291 // returns a node handle owning that extracted data. If the `btree_set` 292 // does not contain an element with a matching key, this function returns an 293 // empty node handle. 294 // 295 // NOTE: In this context, `node_type` refers to the C++17 concept of a 296 // move-only type that owns and provides access to the elements in associative 297 // containers (https://en.cppreference.com/w/cpp/container/node_handle). 298 // It does NOT refer to the data layout of the underlying btree. 299 using Base::extract; 300 301 // btree_set::extract_and_get_next() 302 // 303 // Extracts the indicated element, erasing it in the process, and returns it 304 // as a C++17-compatible node handle along with an iterator to the next 305 // element. 306 // 307 // extract_and_get_next_return_type extract_and_get_next( 308 // const_iterator position): 309 // 310 // Extracts the element at the indicated position, returns a struct 311 // containing a member named `node`: a node handle owning that extracted 312 // data and a member named `next`: an iterator pointing to the next element 313 // in the btree. 314 using Base::extract_and_get_next; 315 316 // btree_set::merge() 317 // 318 // Extracts elements from a given `source` btree_set into this 319 // `btree_set`. If the destination `btree_set` already contains an 320 // element with an equivalent key, that element is not extracted. 321 using Base::merge; 322 323 // btree_set::swap(btree_set& other) 324 // 325 // Exchanges the contents of this `btree_set` with those of the `other` 326 // btree_set, avoiding invocation of any move, copy, or swap operations on 327 // individual elements. 328 // 329 // All iterators and references on the `btree_set` remain valid, excepting 330 // for the past-the-end iterator, which is invalidated. 331 using Base::swap; 332 333 // btree_set::contains() 334 // 335 // template <typename K> bool contains(const K& key) const: 336 // 337 // Determines whether an element comparing equal to the given `key` exists 338 // within the `btree_set`, returning `true` if so or `false` otherwise. 339 // 340 // Supports heterogeneous lookup, provided that the set has a compatible 341 // heterogeneous comparator. 342 using Base::contains; 343 344 // btree_set::count() 345 // 346 // template <typename K> size_type count(const K& key) const: 347 // 348 // Returns the number of elements comparing equal to the given `key` within 349 // the `btree_set`. Note that this function will return either `1` or `0` 350 // since duplicate elements are not allowed within a `btree_set`. 351 // 352 // Supports heterogeneous lookup, provided that the set has a compatible 353 // heterogeneous comparator. 354 using Base::count; 355 356 // btree_set::equal_range() 357 // 358 // Returns a closed range [first, last], defined by a `std::pair` of two 359 // iterators, containing all elements with the passed key in the 360 // `btree_set`. 361 using Base::equal_range; 362 363 // btree_set::find() 364 // 365 // template <typename K> iterator find(const K& key): 366 // template <typename K> const_iterator find(const K& key) const: 367 // 368 // Finds an element with the passed `key` within the `btree_set`. 369 // 370 // Supports heterogeneous lookup, provided that the set has a compatible 371 // heterogeneous comparator. 372 using Base::find; 373 374 // btree_set::lower_bound() 375 // 376 // template <typename K> iterator lower_bound(const K& key): 377 // template <typename K> const_iterator lower_bound(const K& key) const: 378 // 379 // Finds the first element that is not less than `key` within the `btree_set`. 380 // 381 // Supports heterogeneous lookup, provided that the set has a compatible 382 // heterogeneous comparator. 383 using Base::lower_bound; 384 385 // btree_set::upper_bound() 386 // 387 // template <typename K> iterator upper_bound(const K& key): 388 // template <typename K> const_iterator upper_bound(const K& key) const: 389 // 390 // Finds the first element that is greater than `key` within the `btree_set`. 391 // 392 // Supports heterogeneous lookup, provided that the set has a compatible 393 // heterogeneous comparator. 394 using Base::upper_bound; 395 396 // btree_set::get_allocator() 397 // 398 // Returns the allocator function associated with this `btree_set`. 399 using Base::get_allocator; 400 401 // btree_set::key_comp(); 402 // 403 // Returns the key comparator associated with this `btree_set`. 404 using Base::key_comp; 405 406 // btree_set::value_comp(); 407 // 408 // Returns the value comparator associated with this `btree_set`. The keys to 409 // sort the elements are the values themselves, therefore `value_comp` and its 410 // sibling member function `key_comp` are equivalent. 411 using Base::value_comp; 412 }; 413 414 // absl::swap(absl::btree_set<>, absl::btree_set<>) 415 // 416 // Swaps the contents of two `absl::btree_set` containers. 417 template <typename K, typename C, typename A> 418 void swap(btree_set<K, C, A> &x, btree_set<K, C, A> &y) { 419 return x.swap(y); 420 } 421 422 // absl::erase_if(absl::btree_set<>, Pred) 423 // 424 // Erases all elements that satisfy the predicate pred from the container. 425 // Returns the number of erased elements. 426 template <typename K, typename C, typename A, typename Pred> 427 typename btree_set<K, C, A>::size_type erase_if(btree_set<K, C, A> &set, 428 Pred pred) { 429 return container_internal::btree_access::erase_if(set, std::move(pred)); 430 } 431 432 // absl::btree_multiset<> 433 // 434 // An `absl::btree_multiset<K>` is an ordered associative container of 435 // keys and associated values designed to be a more efficient replacement 436 // for `std::multiset` (in most cases). Unlike `absl::btree_set`, a B-tree 437 // multiset allows equivalent elements. 438 // 439 // Keys are sorted using an (optional) comparison function, which defaults to 440 // `std::less<K>`. 441 // 442 // An `absl::btree_multiset<K>` uses a default allocator of `std::allocator<K>` 443 // to allocate (and deallocate) nodes, and construct and destruct values within 444 // those nodes. You may instead specify a custom allocator `A` (which in turn 445 // requires specifying a custom comparator `C`) as in 446 // `absl::btree_multiset<K, C, A>`. 447 // 448 template <typename Key, typename Compare = std::less<Key>, 449 typename Alloc = std::allocator<Key>> 450 class ABSL_ATTRIBUTE_OWNER btree_multiset 451 : public container_internal::btree_multiset_container< 452 container_internal::btree<container_internal::set_params< 453 Key, Compare, Alloc, /*TargetNodeSize=*/256, 454 /*IsMulti=*/true>>> { 455 using Base = typename btree_multiset::btree_multiset_container; 456 457 public: 458 // Constructors and Assignment Operators 459 // 460 // A `btree_multiset` supports the same overload set as `std::set` 461 // for construction and assignment: 462 // 463 // * Default constructor 464 // 465 // absl::btree_multiset<std::string> set1; 466 // 467 // * Initializer List constructor 468 // 469 // absl::btree_multiset<std::string> set2 = 470 // {{"huey"}, {"dewey"}, {"louie"},}; 471 // 472 // * Copy constructor 473 // 474 // absl::btree_multiset<std::string> set3(set2); 475 // 476 // * Copy assignment operator 477 // 478 // absl::btree_multiset<std::string> set4; 479 // set4 = set3; 480 // 481 // * Move constructor 482 // 483 // // Move is guaranteed efficient 484 // absl::btree_multiset<std::string> set5(std::move(set4)); 485 // 486 // * Move assignment operator 487 // 488 // // May be efficient if allocators are compatible 489 // absl::btree_multiset<std::string> set6; 490 // set6 = std::move(set5); 491 // 492 // * Range constructor 493 // 494 // std::vector<std::string> v = {"a", "b"}; 495 // absl::btree_multiset<std::string> set7(v.begin(), v.end()); 496 btree_multiset() {} 497 using Base::Base; 498 499 // btree_multiset::begin() 500 // 501 // Returns an iterator to the beginning of the `btree_multiset`. 502 using Base::begin; 503 504 // btree_multiset::cbegin() 505 // 506 // Returns a const iterator to the beginning of the `btree_multiset`. 507 using Base::cbegin; 508 509 // btree_multiset::end() 510 // 511 // Returns an iterator to the end of the `btree_multiset`. 512 using Base::end; 513 514 // btree_multiset::cend() 515 // 516 // Returns a const iterator to the end of the `btree_multiset`. 517 using Base::cend; 518 519 // btree_multiset::empty() 520 // 521 // Returns whether or not the `btree_multiset` is empty. 522 using Base::empty; 523 524 // btree_multiset::max_size() 525 // 526 // Returns the largest theoretical possible number of elements within a 527 // `btree_multiset` under current memory constraints. This value can be 528 // thought of as the largest value of `std::distance(begin(), end())` for a 529 // `btree_multiset<Key>`. 530 using Base::max_size; 531 532 // btree_multiset::size() 533 // 534 // Returns the number of elements currently within the `btree_multiset`. 535 using Base::size; 536 537 // btree_multiset::clear() 538 // 539 // Removes all elements from the `btree_multiset`. Invalidates any references, 540 // pointers, or iterators referring to contained elements. 541 using Base::clear; 542 543 // btree_multiset::erase() 544 // 545 // Erases elements within the `btree_multiset`. Overloads are listed below. 546 // 547 // iterator erase(iterator position): 548 // iterator erase(const_iterator position): 549 // 550 // Erases the element at `position` of the `btree_multiset`, returning 551 // the iterator pointing to the element after the one that was erased 552 // (or end() if none exists). 553 // 554 // iterator erase(const_iterator first, const_iterator last): 555 // 556 // Erases the elements in the open interval [`first`, `last`), returning 557 // the iterator pointing to the element after the interval that was erased 558 // (or end() if none exists). 559 // 560 // template <typename K> size_type erase(const K& key): 561 // 562 // Erases the elements matching the key, if any exist, returning the 563 // number of elements erased. 564 using Base::erase; 565 566 // btree_multiset::insert() 567 // 568 // Inserts an element of the specified value into the `btree_multiset`, 569 // returning an iterator pointing to the newly inserted element. 570 // Any references, pointers, or iterators are invalidated. Overloads are 571 // listed below. 572 // 573 // iterator insert(const value_type& value): 574 // 575 // Inserts a value into the `btree_multiset`, returning an iterator to the 576 // inserted element. 577 // 578 // iterator insert(value_type&& value): 579 // 580 // Inserts a moveable value into the `btree_multiset`, returning an iterator 581 // to the inserted element. 582 // 583 // iterator insert(const_iterator hint, const value_type& value): 584 // iterator insert(const_iterator hint, value_type&& value): 585 // 586 // Inserts a value, using the position of `hint` as a non-binding suggestion 587 // for where to begin the insertion search. Returns an iterator to the 588 // inserted element. 589 // 590 // void insert(InputIterator first, InputIterator last): 591 // 592 // Inserts a range of values [`first`, `last`). 593 // 594 // void insert(std::initializer_list<init_type> ilist): 595 // 596 // Inserts the elements within the initializer list `ilist`. 597 using Base::insert; 598 599 // btree_multiset::emplace() 600 // 601 // Inserts an element of the specified value by constructing it in-place 602 // within the `btree_multiset`. Any references, pointers, or iterators are 603 // invalidated. 604 using Base::emplace; 605 606 // btree_multiset::emplace_hint() 607 // 608 // Inserts an element of the specified value by constructing it in-place 609 // within the `btree_multiset`, using the position of `hint` as a non-binding 610 // suggestion for where to begin the insertion search. 611 // 612 // Any references, pointers, or iterators are invalidated. 613 using Base::emplace_hint; 614 615 // btree_multiset::extract() 616 // 617 // Extracts the indicated element, erasing it in the process, and returns it 618 // as a C++17-compatible node handle. Overloads are listed below. 619 // 620 // node_type extract(const_iterator position): 621 // 622 // Extracts the element at the indicated position and returns a node handle 623 // owning that extracted data. 624 // 625 // template <typename K> node_type extract(const K& k): 626 // 627 // Extracts the element with the key matching the passed key value and 628 // returns a node handle owning that extracted data. If the `btree_multiset` 629 // does not contain an element with a matching key, this function returns an 630 // empty node handle. 631 // 632 // NOTE: In this context, `node_type` refers to the C++17 concept of a 633 // move-only type that owns and provides access to the elements in associative 634 // containers (https://en.cppreference.com/w/cpp/container/node_handle). 635 // It does NOT refer to the data layout of the underlying btree. 636 using Base::extract; 637 638 // btree_multiset::extract_and_get_next() 639 // 640 // Extracts the indicated element, erasing it in the process, and returns it 641 // as a C++17-compatible node handle along with an iterator to the next 642 // element. 643 // 644 // extract_and_get_next_return_type extract_and_get_next( 645 // const_iterator position): 646 // 647 // Extracts the element at the indicated position, returns a struct 648 // containing a member named `node`: a node handle owning that extracted 649 // data and a member named `next`: an iterator pointing to the next element 650 // in the btree. 651 using Base::extract_and_get_next; 652 653 // btree_multiset::merge() 654 // 655 // Extracts all elements from a given `source` btree_multiset into this 656 // `btree_multiset`. 657 using Base::merge; 658 659 // btree_multiset::swap(btree_multiset& other) 660 // 661 // Exchanges the contents of this `btree_multiset` with those of the `other` 662 // btree_multiset, avoiding invocation of any move, copy, or swap operations 663 // on individual elements. 664 // 665 // All iterators and references on the `btree_multiset` remain valid, 666 // excepting for the past-the-end iterator, which is invalidated. 667 using Base::swap; 668 669 // btree_multiset::contains() 670 // 671 // template <typename K> bool contains(const K& key) const: 672 // 673 // Determines whether an element comparing equal to the given `key` exists 674 // within the `btree_multiset`, returning `true` if so or `false` otherwise. 675 // 676 // Supports heterogeneous lookup, provided that the set has a compatible 677 // heterogeneous comparator. 678 using Base::contains; 679 680 // btree_multiset::count() 681 // 682 // template <typename K> size_type count(const K& key) const: 683 // 684 // Returns the number of elements comparing equal to the given `key` within 685 // the `btree_multiset`. 686 // 687 // Supports heterogeneous lookup, provided that the set has a compatible 688 // heterogeneous comparator. 689 using Base::count; 690 691 // btree_multiset::equal_range() 692 // 693 // Returns a closed range [first, last], defined by a `std::pair` of two 694 // iterators, containing all elements with the passed key in the 695 // `btree_multiset`. 696 using Base::equal_range; 697 698 // btree_multiset::find() 699 // 700 // template <typename K> iterator find(const K& key): 701 // template <typename K> const_iterator find(const K& key) const: 702 // 703 // Finds an element with the passed `key` within the `btree_multiset`. 704 // 705 // Supports heterogeneous lookup, provided that the set has a compatible 706 // heterogeneous comparator. 707 using Base::find; 708 709 // btree_multiset::lower_bound() 710 // 711 // template <typename K> iterator lower_bound(const K& key): 712 // template <typename K> const_iterator lower_bound(const K& key) const: 713 // 714 // Finds the first element that is not less than `key` within the 715 // `btree_multiset`. 716 // 717 // Supports heterogeneous lookup, provided that the set has a compatible 718 // heterogeneous comparator. 719 using Base::lower_bound; 720 721 // btree_multiset::upper_bound() 722 // 723 // template <typename K> iterator upper_bound(const K& key): 724 // template <typename K> const_iterator upper_bound(const K& key) const: 725 // 726 // Finds the first element that is greater than `key` within the 727 // `btree_multiset`. 728 // 729 // Supports heterogeneous lookup, provided that the set has a compatible 730 // heterogeneous comparator. 731 using Base::upper_bound; 732 733 // btree_multiset::get_allocator() 734 // 735 // Returns the allocator function associated with this `btree_multiset`. 736 using Base::get_allocator; 737 738 // btree_multiset::key_comp(); 739 // 740 // Returns the key comparator associated with this `btree_multiset`. 741 using Base::key_comp; 742 743 // btree_multiset::value_comp(); 744 // 745 // Returns the value comparator associated with this `btree_multiset`. The 746 // keys to sort the elements are the values themselves, therefore `value_comp` 747 // and its sibling member function `key_comp` are equivalent. 748 using Base::value_comp; 749 }; 750 751 // absl::swap(absl::btree_multiset<>, absl::btree_multiset<>) 752 // 753 // Swaps the contents of two `absl::btree_multiset` containers. 754 template <typename K, typename C, typename A> 755 void swap(btree_multiset<K, C, A> &x, btree_multiset<K, C, A> &y) { 756 return x.swap(y); 757 } 758 759 // absl::erase_if(absl::btree_multiset<>, Pred) 760 // 761 // Erases all elements that satisfy the predicate pred from the container. 762 // Returns the number of erased elements. 763 template <typename K, typename C, typename A, typename Pred> 764 typename btree_multiset<K, C, A>::size_type erase_if( 765 btree_multiset<K, C, A> & set, Pred pred) { 766 return container_internal::btree_access::erase_if(set, std::move(pred)); 767 } 768 769 namespace container_internal { 770 771 // This type implements the necessary functions from the 772 // absl::container_internal::slot_type interface for btree_(multi)set. 773 template <typename Key> 774 struct set_slot_policy { 775 using slot_type = Key; 776 using value_type = Key; 777 using mutable_value_type = Key; 778 779 static value_type &element(slot_type *slot) { return *slot; } 780 static const value_type &element(const slot_type *slot) { return *slot; } 781 782 template <typename Alloc, class... Args> 783 static void construct(Alloc *alloc, slot_type *slot, Args &&...args) { 784 absl::allocator_traits<Alloc>::construct(*alloc, slot, 785 std::forward<Args>(args)...); 786 } 787 788 template <typename Alloc> 789 static void construct(Alloc *alloc, slot_type *slot, slot_type *other) { 790 absl::allocator_traits<Alloc>::construct(*alloc, slot, std::move(*other)); 791 } 792 793 template <typename Alloc> 794 static void construct(Alloc *alloc, slot_type *slot, const slot_type *other) { 795 absl::allocator_traits<Alloc>::construct(*alloc, slot, *other); 796 } 797 798 template <typename Alloc> 799 static void destroy(Alloc *alloc, slot_type *slot) { 800 absl::allocator_traits<Alloc>::destroy(*alloc, slot); 801 } 802 }; 803 804 // A parameters structure for holding the type parameters for a btree_set. 805 // Compare and Alloc should be nothrow copy-constructible. 806 template <typename Key, typename Compare, typename Alloc, int TargetNodeSize, 807 bool IsMulti> 808 struct set_params : common_params<Key, Compare, Alloc, TargetNodeSize, IsMulti, 809 /*IsMap=*/false, set_slot_policy<Key>> { 810 using value_type = Key; 811 using slot_type = typename set_params::common_params::slot_type; 812 813 template <typename V> 814 static const V &key(const V &value) { 815 return value; 816 } 817 static const Key &key(const slot_type *slot) { return *slot; } 818 static const Key &key(slot_type *slot) { return *slot; } 819 }; 820 821 } // namespace container_internal 822 823 ABSL_NAMESPACE_END 824 } // namespace absl 825 826 #endif // ABSL_CONTAINER_BTREE_SET_H_