tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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_