Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:27:14

0001 // Copyright 2018 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
0014 //
0015 // -----------------------------------------------------------------------------
0016 // File: btree_set.h
0017 // -----------------------------------------------------------------------------
0018 //
0019 // This header file defines B-tree sets: sorted associative containers of
0020 // values.
0021 //
0022 //     * `absl::btree_set<>`
0023 //     * `absl::btree_multiset<>`
0024 //
0025 // These B-tree types are similar to the corresponding types in the STL
0026 // (`std::set` and `std::multiset`) and generally conform to the STL interfaces
0027 // of those types. However, because they are implemented using B-trees, they
0028 // are more efficient in most situations.
0029 //
0030 // Unlike `std::set` and `std::multiset`, which are commonly implemented using
0031 // red-black tree nodes, B-tree sets use more generic B-tree nodes able to hold
0032 // multiple values per node. Holding multiple values per node often makes
0033 // B-tree sets perform better than their `std::set` counterparts, because
0034 // multiple entries can be checked within the same cache hit.
0035 //
0036 // However, these types should not be considered drop-in replacements for
0037 // `std::set` and `std::multiset` as there are some API differences, which are
0038 // noted in this header file. The most consequential differences with respect to
0039 // migrating to b-tree from the STL types are listed in the next paragraph.
0040 // Other API differences are minor.
0041 //
0042 // Importantly, insertions and deletions may invalidate outstanding iterators,
0043 // pointers, and references to elements. Such invalidations are typically only
0044 // an issue if insertion and deletion operations are interleaved with the use of
0045 // more than one iterator, pointer, or reference simultaneously. For this
0046 // reason, `insert()`, `erase()`, and `extract_and_get_next()` return a valid
0047 // iterator at the current position.
0048 //
0049 // Another API difference is that btree iterators can be subtracted, and this
0050 // is faster than using std::distance.
0051 //
0052 // B-tree sets are not exception-safe.
0053 
0054 #ifndef ABSL_CONTAINER_BTREE_SET_H_
0055 #define ABSL_CONTAINER_BTREE_SET_H_
0056 
0057 #include "absl/base/attributes.h"
0058 #include "absl/container/internal/btree.h"  // IWYU pragma: export
0059 #include "absl/container/internal/btree_container.h"  // IWYU pragma: export
0060 
0061 namespace absl {
0062 ABSL_NAMESPACE_BEGIN
0063 
0064 namespace container_internal {
0065 
0066 template <typename Key>
0067 struct set_slot_policy;
0068 
0069 template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
0070           bool IsMulti>
0071 struct set_params;
0072 
0073 }  // namespace container_internal
0074 
0075 // absl::btree_set<>
0076 //
0077 // An `absl::btree_set<K>` is an ordered associative container of unique key
0078 // values designed to be a more efficient replacement for `std::set` (in most
0079 // cases).
0080 //
0081 // Keys are sorted using an (optional) comparison function, which defaults to
0082 // `std::less<K>`.
0083 //
0084 // An `absl::btree_set<K>` uses a default allocator of `std::allocator<K>` to
0085 // allocate (and deallocate) nodes, and construct and destruct values within
0086 // those nodes. You may instead specify a custom allocator `A` (which in turn
0087 // requires specifying a custom comparator `C`) as in
0088 // `absl::btree_set<K, C, A>`.
0089 //
0090 template <typename Key, typename Compare = std::less<Key>,
0091           typename Alloc = std::allocator<Key>>
0092 class ABSL_INTERNAL_ATTRIBUTE_OWNER btree_set
0093     : public container_internal::btree_set_container<
0094           container_internal::btree<container_internal::set_params<
0095               Key, Compare, Alloc, /*TargetNodeSize=*/256,
0096               /*IsMulti=*/false>>> {
0097   using Base = typename btree_set::btree_set_container;
0098 
0099  public:
0100   // Constructors and Assignment Operators
0101   //
0102   // A `btree_set` supports the same overload set as `std::set`
0103   // for construction and assignment:
0104   //
0105   // * Default constructor
0106   //
0107   //   absl::btree_set<std::string> set1;
0108   //
0109   // * Initializer List constructor
0110   //
0111   //   absl::btree_set<std::string> set2 =
0112   //       {{"huey"}, {"dewey"}, {"louie"},};
0113   //
0114   // * Copy constructor
0115   //
0116   //   absl::btree_set<std::string> set3(set2);
0117   //
0118   // * Copy assignment operator
0119   //
0120   //  absl::btree_set<std::string> set4;
0121   //  set4 = set3;
0122   //
0123   // * Move constructor
0124   //
0125   //   // Move is guaranteed efficient
0126   //   absl::btree_set<std::string> set5(std::move(set4));
0127   //
0128   // * Move assignment operator
0129   //
0130   //   // May be efficient if allocators are compatible
0131   //   absl::btree_set<std::string> set6;
0132   //   set6 = std::move(set5);
0133   //
0134   // * Range constructor
0135   //
0136   //   std::vector<std::string> v = {"a", "b"};
0137   //   absl::btree_set<std::string> set7(v.begin(), v.end());
0138   btree_set() {}
0139   using Base::Base;
0140 
0141   // btree_set::begin()
0142   //
0143   // Returns an iterator to the beginning of the `btree_set`.
0144   using Base::begin;
0145 
0146   // btree_set::cbegin()
0147   //
0148   // Returns a const iterator to the beginning of the `btree_set`.
0149   using Base::cbegin;
0150 
0151   // btree_set::end()
0152   //
0153   // Returns an iterator to the end of the `btree_set`.
0154   using Base::end;
0155 
0156   // btree_set::cend()
0157   //
0158   // Returns a const iterator to the end of the `btree_set`.
0159   using Base::cend;
0160 
0161   // btree_set::empty()
0162   //
0163   // Returns whether or not the `btree_set` is empty.
0164   using Base::empty;
0165 
0166   // btree_set::max_size()
0167   //
0168   // Returns the largest theoretical possible number of elements within a
0169   // `btree_set` under current memory constraints. This value can be thought
0170   // of as the largest value of `std::distance(begin(), end())` for a
0171   // `btree_set<Key>`.
0172   using Base::max_size;
0173 
0174   // btree_set::size()
0175   //
0176   // Returns the number of elements currently within the `btree_set`.
0177   using Base::size;
0178 
0179   // btree_set::clear()
0180   //
0181   // Removes all elements from the `btree_set`. Invalidates any references,
0182   // pointers, or iterators referring to contained elements.
0183   using Base::clear;
0184 
0185   // btree_set::erase()
0186   //
0187   // Erases elements within the `btree_set`. Overloads are listed below.
0188   //
0189   // iterator erase(iterator position):
0190   // iterator erase(const_iterator position):
0191   //
0192   //   Erases the element at `position` of the `btree_set`, returning
0193   //   the iterator pointing to the element after the one that was erased
0194   //   (or end() if none exists).
0195   //
0196   // iterator erase(const_iterator first, const_iterator last):
0197   //
0198   //   Erases the elements in the open interval [`first`, `last`), returning
0199   //   the iterator pointing to the element after the interval that was erased
0200   //   (or end() if none exists).
0201   //
0202   // template <typename K> size_type erase(const K& key):
0203   //
0204   //   Erases the element with the matching key, if it exists, returning the
0205   //   number of elements erased (0 or 1).
0206   using Base::erase;
0207 
0208   // btree_set::insert()
0209   //
0210   // Inserts an element of the specified value into the `btree_set`,
0211   // returning an iterator pointing to the newly inserted element, provided that
0212   // an element with the given key does not already exist. If an insertion
0213   // occurs, any references, pointers, or iterators are invalidated.
0214   // Overloads are listed below.
0215   //
0216   // std::pair<iterator,bool> insert(const value_type& value):
0217   //
0218   //   Inserts a value into the `btree_set`. Returns a pair consisting of an
0219   //   iterator to the inserted element (or to the element that prevented the
0220   //   insertion) and a bool denoting whether the insertion took place.
0221   //
0222   // std::pair<iterator,bool> insert(value_type&& value):
0223   //
0224   //   Inserts a moveable value into the `btree_set`. Returns a pair
0225   //   consisting of an iterator to the inserted element (or to the element that
0226   //   prevented the insertion) and a bool denoting whether the insertion took
0227   //   place.
0228   //
0229   // iterator insert(const_iterator hint, const value_type& value):
0230   // iterator insert(const_iterator hint, value_type&& value):
0231   //
0232   //   Inserts a value, using the position of `hint` as a non-binding suggestion
0233   //   for where to begin the insertion search. Returns an iterator to the
0234   //   inserted element, or to the existing element that prevented the
0235   //   insertion.
0236   //
0237   // void insert(InputIterator first, InputIterator last):
0238   //
0239   //   Inserts a range of values [`first`, `last`).
0240   //
0241   // void insert(std::initializer_list<init_type> ilist):
0242   //
0243   //   Inserts the elements within the initializer list `ilist`.
0244   using Base::insert;
0245 
0246   // btree_set::emplace()
0247   //
0248   // Inserts an element of the specified value by constructing it in-place
0249   // within the `btree_set`, provided that no element with the given key
0250   // already exists.
0251   //
0252   // The element may be constructed even if there already is an element with the
0253   // key in the container, in which case the newly constructed element will be
0254   // destroyed immediately.
0255   //
0256   // If an insertion occurs, any references, pointers, or iterators are
0257   // invalidated.
0258   using Base::emplace;
0259 
0260   // btree_set::emplace_hint()
0261   //
0262   // Inserts an element of the specified value by constructing it in-place
0263   // within the `btree_set`, using the position of `hint` as a non-binding
0264   // suggestion for where to begin the insertion search, and only inserts
0265   // provided that no element with the given key already exists.
0266   //
0267   // The element may be constructed even if there already is an element with the
0268   // key in the container, in which case the newly constructed element will be
0269   // destroyed immediately.
0270   //
0271   // If an insertion occurs, any references, pointers, or iterators are
0272   // invalidated.
0273   using Base::emplace_hint;
0274 
0275   // btree_set::extract()
0276   //
0277   // Extracts the indicated element, erasing it in the process, and returns it
0278   // as a C++17-compatible node handle. Any references, pointers, or iterators
0279   // are invalidated. Overloads are listed below.
0280   //
0281   // node_type extract(const_iterator position):
0282   //
0283   //   Extracts the element at the indicated position and returns a node handle
0284   //   owning that extracted data.
0285   //
0286   // template <typename K> node_type extract(const K& k):
0287   //
0288   //   Extracts the element with the key matching the passed key value and
0289   //   returns a node handle owning that extracted data. If the `btree_set`
0290   //   does not contain an element with a matching key, this function returns an
0291   //   empty node handle.
0292   //
0293   // NOTE: In this context, `node_type` refers to the C++17 concept of a
0294   // move-only type that owns and provides access to the elements in associative
0295   // containers (https://en.cppreference.com/w/cpp/container/node_handle).
0296   // It does NOT refer to the data layout of the underlying btree.
0297   using Base::extract;
0298 
0299   // btree_set::extract_and_get_next()
0300   //
0301   // Extracts the indicated element, erasing it in the process, and returns it
0302   // as a C++17-compatible node handle along with an iterator to the next
0303   // element.
0304   //
0305   // extract_and_get_next_return_type extract_and_get_next(
0306   //     const_iterator position):
0307   //
0308   //   Extracts the element at the indicated position, returns a struct
0309   //   containing a member named `node`: a node handle owning that extracted
0310   //   data and a member named `next`: an iterator pointing to the next element
0311   //   in the btree.
0312   using Base::extract_and_get_next;
0313 
0314   // btree_set::merge()
0315   //
0316   // Extracts elements from a given `source` btree_set into this
0317   // `btree_set`. If the destination `btree_set` already contains an
0318   // element with an equivalent key, that element is not extracted.
0319   using Base::merge;
0320 
0321   // btree_set::swap(btree_set& other)
0322   //
0323   // Exchanges the contents of this `btree_set` with those of the `other`
0324   // btree_set, avoiding invocation of any move, copy, or swap operations on
0325   // individual elements.
0326   //
0327   // All iterators and references on the `btree_set` remain valid, excepting
0328   // for the past-the-end iterator, which is invalidated.
0329   using Base::swap;
0330 
0331   // btree_set::contains()
0332   //
0333   // template <typename K> bool contains(const K& key) const:
0334   //
0335   // Determines whether an element comparing equal to the given `key` exists
0336   // within the `btree_set`, returning `true` if so or `false` otherwise.
0337   //
0338   // Supports heterogeneous lookup, provided that the set has a compatible
0339   // heterogeneous comparator.
0340   using Base::contains;
0341 
0342   // btree_set::count()
0343   //
0344   // template <typename K> size_type count(const K& key) const:
0345   //
0346   // Returns the number of elements comparing equal to the given `key` within
0347   // the `btree_set`. Note that this function will return either `1` or `0`
0348   // since duplicate elements are not allowed within a `btree_set`.
0349   //
0350   // Supports heterogeneous lookup, provided that the set has a compatible
0351   // heterogeneous comparator.
0352   using Base::count;
0353 
0354   // btree_set::equal_range()
0355   //
0356   // Returns a closed range [first, last], defined by a `std::pair` of two
0357   // iterators, containing all elements with the passed key in the
0358   // `btree_set`.
0359   using Base::equal_range;
0360 
0361   // btree_set::find()
0362   //
0363   // template <typename K> iterator find(const K& key):
0364   // template <typename K> const_iterator find(const K& key) const:
0365   //
0366   // Finds an element with the passed `key` within the `btree_set`.
0367   //
0368   // Supports heterogeneous lookup, provided that the set has a compatible
0369   // heterogeneous comparator.
0370   using Base::find;
0371 
0372   // btree_set::lower_bound()
0373   //
0374   // template <typename K> iterator lower_bound(const K& key):
0375   // template <typename K> const_iterator lower_bound(const K& key) const:
0376   //
0377   // Finds the first element that is not less than `key` within the `btree_set`.
0378   //
0379   // Supports heterogeneous lookup, provided that the set has a compatible
0380   // heterogeneous comparator.
0381   using Base::lower_bound;
0382 
0383   // btree_set::upper_bound()
0384   //
0385   // template <typename K> iterator upper_bound(const K& key):
0386   // template <typename K> const_iterator upper_bound(const K& key) const:
0387   //
0388   // Finds the first element that is greater than `key` within the `btree_set`.
0389   //
0390   // Supports heterogeneous lookup, provided that the set has a compatible
0391   // heterogeneous comparator.
0392   using Base::upper_bound;
0393 
0394   // btree_set::get_allocator()
0395   //
0396   // Returns the allocator function associated with this `btree_set`.
0397   using Base::get_allocator;
0398 
0399   // btree_set::key_comp();
0400   //
0401   // Returns the key comparator associated with this `btree_set`.
0402   using Base::key_comp;
0403 
0404   // btree_set::value_comp();
0405   //
0406   // Returns the value comparator associated with this `btree_set`. The keys to
0407   // sort the elements are the values themselves, therefore `value_comp` and its
0408   // sibling member function `key_comp` are equivalent.
0409   using Base::value_comp;
0410 };
0411 
0412 // absl::swap(absl::btree_set<>, absl::btree_set<>)
0413 //
0414 // Swaps the contents of two `absl::btree_set` containers.
0415 template <typename K, typename C, typename A>
0416 void swap(btree_set<K, C, A> &x, btree_set<K, C, A> &y) {
0417   return x.swap(y);
0418 }
0419 
0420 // absl::erase_if(absl::btree_set<>, Pred)
0421 //
0422 // Erases all elements that satisfy the predicate pred from the container.
0423 // Returns the number of erased elements.
0424 template <typename K, typename C, typename A, typename Pred>
0425 typename btree_set<K, C, A>::size_type erase_if(btree_set<K, C, A> &set,
0426                                                 Pred pred) {
0427   return container_internal::btree_access::erase_if(set, std::move(pred));
0428 }
0429 
0430 // absl::btree_multiset<>
0431 //
0432 // An `absl::btree_multiset<K>` is an ordered associative container of
0433 // keys and associated values designed to be a more efficient replacement
0434 // for `std::multiset` (in most cases). Unlike `absl::btree_set`, a B-tree
0435 // multiset allows equivalent elements.
0436 //
0437 // Keys are sorted using an (optional) comparison function, which defaults to
0438 // `std::less<K>`.
0439 //
0440 // An `absl::btree_multiset<K>` uses a default allocator of `std::allocator<K>`
0441 // to allocate (and deallocate) nodes, and construct and destruct values within
0442 // those nodes. You may instead specify a custom allocator `A` (which in turn
0443 // requires specifying a custom comparator `C`) as in
0444 // `absl::btree_multiset<K, C, A>`.
0445 //
0446 template <typename Key, typename Compare = std::less<Key>,
0447           typename Alloc = std::allocator<Key>>
0448 class ABSL_INTERNAL_ATTRIBUTE_OWNER btree_multiset
0449     : public container_internal::btree_multiset_container<
0450           container_internal::btree<container_internal::set_params<
0451               Key, Compare, Alloc, /*TargetNodeSize=*/256,
0452               /*IsMulti=*/true>>> {
0453   using Base = typename btree_multiset::btree_multiset_container;
0454 
0455  public:
0456   // Constructors and Assignment Operators
0457   //
0458   // A `btree_multiset` supports the same overload set as `std::set`
0459   // for construction and assignment:
0460   //
0461   // * Default constructor
0462   //
0463   //   absl::btree_multiset<std::string> set1;
0464   //
0465   // * Initializer List constructor
0466   //
0467   //   absl::btree_multiset<std::string> set2 =
0468   //       {{"huey"}, {"dewey"}, {"louie"},};
0469   //
0470   // * Copy constructor
0471   //
0472   //   absl::btree_multiset<std::string> set3(set2);
0473   //
0474   // * Copy assignment operator
0475   //
0476   //  absl::btree_multiset<std::string> set4;
0477   //  set4 = set3;
0478   //
0479   // * Move constructor
0480   //
0481   //   // Move is guaranteed efficient
0482   //   absl::btree_multiset<std::string> set5(std::move(set4));
0483   //
0484   // * Move assignment operator
0485   //
0486   //   // May be efficient if allocators are compatible
0487   //   absl::btree_multiset<std::string> set6;
0488   //   set6 = std::move(set5);
0489   //
0490   // * Range constructor
0491   //
0492   //   std::vector<std::string> v = {"a", "b"};
0493   //   absl::btree_multiset<std::string> set7(v.begin(), v.end());
0494   btree_multiset() {}
0495   using Base::Base;
0496 
0497   // btree_multiset::begin()
0498   //
0499   // Returns an iterator to the beginning of the `btree_multiset`.
0500   using Base::begin;
0501 
0502   // btree_multiset::cbegin()
0503   //
0504   // Returns a const iterator to the beginning of the `btree_multiset`.
0505   using Base::cbegin;
0506 
0507   // btree_multiset::end()
0508   //
0509   // Returns an iterator to the end of the `btree_multiset`.
0510   using Base::end;
0511 
0512   // btree_multiset::cend()
0513   //
0514   // Returns a const iterator to the end of the `btree_multiset`.
0515   using Base::cend;
0516 
0517   // btree_multiset::empty()
0518   //
0519   // Returns whether or not the `btree_multiset` is empty.
0520   using Base::empty;
0521 
0522   // btree_multiset::max_size()
0523   //
0524   // Returns the largest theoretical possible number of elements within a
0525   // `btree_multiset` under current memory constraints. This value can be
0526   // thought of as the largest value of `std::distance(begin(), end())` for a
0527   // `btree_multiset<Key>`.
0528   using Base::max_size;
0529 
0530   // btree_multiset::size()
0531   //
0532   // Returns the number of elements currently within the `btree_multiset`.
0533   using Base::size;
0534 
0535   // btree_multiset::clear()
0536   //
0537   // Removes all elements from the `btree_multiset`. Invalidates any references,
0538   // pointers, or iterators referring to contained elements.
0539   using Base::clear;
0540 
0541   // btree_multiset::erase()
0542   //
0543   // Erases elements within the `btree_multiset`. Overloads are listed below.
0544   //
0545   // iterator erase(iterator position):
0546   // iterator erase(const_iterator position):
0547   //
0548   //   Erases the element at `position` of the `btree_multiset`, returning
0549   //   the iterator pointing to the element after the one that was erased
0550   //   (or end() if none exists).
0551   //
0552   // iterator erase(const_iterator first, const_iterator last):
0553   //
0554   //   Erases the elements in the open interval [`first`, `last`), returning
0555   //   the iterator pointing to the element after the interval that was erased
0556   //   (or end() if none exists).
0557   //
0558   // template <typename K> size_type erase(const K& key):
0559   //
0560   //   Erases the elements matching the key, if any exist, returning the
0561   //   number of elements erased.
0562   using Base::erase;
0563 
0564   // btree_multiset::insert()
0565   //
0566   // Inserts an element of the specified value into the `btree_multiset`,
0567   // returning an iterator pointing to the newly inserted element.
0568   // Any references, pointers, or iterators are invalidated.  Overloads are
0569   // listed below.
0570   //
0571   // iterator insert(const value_type& value):
0572   //
0573   //   Inserts a value into the `btree_multiset`, returning an iterator to the
0574   //   inserted element.
0575   //
0576   // iterator insert(value_type&& value):
0577   //
0578   //   Inserts a moveable value into the `btree_multiset`, returning an iterator
0579   //   to the inserted element.
0580   //
0581   // iterator insert(const_iterator hint, const value_type& value):
0582   // iterator insert(const_iterator hint, value_type&& value):
0583   //
0584   //   Inserts a value, using the position of `hint` as a non-binding suggestion
0585   //   for where to begin the insertion search. Returns an iterator to the
0586   //   inserted element.
0587   //
0588   // void insert(InputIterator first, InputIterator last):
0589   //
0590   //   Inserts a range of values [`first`, `last`).
0591   //
0592   // void insert(std::initializer_list<init_type> ilist):
0593   //
0594   //   Inserts the elements within the initializer list `ilist`.
0595   using Base::insert;
0596 
0597   // btree_multiset::emplace()
0598   //
0599   // Inserts an element of the specified value by constructing it in-place
0600   // within the `btree_multiset`. Any references, pointers, or iterators are
0601   // invalidated.
0602   using Base::emplace;
0603 
0604   // btree_multiset::emplace_hint()
0605   //
0606   // Inserts an element of the specified value by constructing it in-place
0607   // within the `btree_multiset`, using the position of `hint` as a non-binding
0608   // suggestion for where to begin the insertion search.
0609   //
0610   // Any references, pointers, or iterators are invalidated.
0611   using Base::emplace_hint;
0612 
0613   // btree_multiset::extract()
0614   //
0615   // Extracts the indicated element, erasing it in the process, and returns it
0616   // as a C++17-compatible node handle. Overloads are listed below.
0617   //
0618   // node_type extract(const_iterator position):
0619   //
0620   //   Extracts the element at the indicated position and returns a node handle
0621   //   owning that extracted data.
0622   //
0623   // template <typename K> node_type extract(const K& k):
0624   //
0625   //   Extracts the element with the key matching the passed key value and
0626   //   returns a node handle owning that extracted data. If the `btree_multiset`
0627   //   does not contain an element with a matching key, this function returns an
0628   //   empty node handle.
0629   //
0630   // NOTE: In this context, `node_type` refers to the C++17 concept of a
0631   // move-only type that owns and provides access to the elements in associative
0632   // containers (https://en.cppreference.com/w/cpp/container/node_handle).
0633   // It does NOT refer to the data layout of the underlying btree.
0634   using Base::extract;
0635 
0636   // btree_multiset::extract_and_get_next()
0637   //
0638   // Extracts the indicated element, erasing it in the process, and returns it
0639   // as a C++17-compatible node handle along with an iterator to the next
0640   // element.
0641   //
0642   // extract_and_get_next_return_type extract_and_get_next(
0643   //     const_iterator position):
0644   //
0645   //   Extracts the element at the indicated position, returns a struct
0646   //   containing a member named `node`: a node handle owning that extracted
0647   //   data and a member named `next`: an iterator pointing to the next element
0648   //   in the btree.
0649   using Base::extract_and_get_next;
0650 
0651   // btree_multiset::merge()
0652   //
0653   // Extracts all elements from a given `source` btree_multiset into this
0654   // `btree_multiset`.
0655   using Base::merge;
0656 
0657   // btree_multiset::swap(btree_multiset& other)
0658   //
0659   // Exchanges the contents of this `btree_multiset` with those of the `other`
0660   // btree_multiset, avoiding invocation of any move, copy, or swap operations
0661   // on individual elements.
0662   //
0663   // All iterators and references on the `btree_multiset` remain valid,
0664   // excepting for the past-the-end iterator, which is invalidated.
0665   using Base::swap;
0666 
0667   // btree_multiset::contains()
0668   //
0669   // template <typename K> bool contains(const K& key) const:
0670   //
0671   // Determines whether an element comparing equal to the given `key` exists
0672   // within the `btree_multiset`, returning `true` if so or `false` otherwise.
0673   //
0674   // Supports heterogeneous lookup, provided that the set has a compatible
0675   // heterogeneous comparator.
0676   using Base::contains;
0677 
0678   // btree_multiset::count()
0679   //
0680   // template <typename K> size_type count(const K& key) const:
0681   //
0682   // Returns the number of elements comparing equal to the given `key` within
0683   // the `btree_multiset`.
0684   //
0685   // Supports heterogeneous lookup, provided that the set has a compatible
0686   // heterogeneous comparator.
0687   using Base::count;
0688 
0689   // btree_multiset::equal_range()
0690   //
0691   // Returns a closed range [first, last], defined by a `std::pair` of two
0692   // iterators, containing all elements with the passed key in the
0693   // `btree_multiset`.
0694   using Base::equal_range;
0695 
0696   // btree_multiset::find()
0697   //
0698   // template <typename K> iterator find(const K& key):
0699   // template <typename K> const_iterator find(const K& key) const:
0700   //
0701   // Finds an element with the passed `key` within the `btree_multiset`.
0702   //
0703   // Supports heterogeneous lookup, provided that the set has a compatible
0704   // heterogeneous comparator.
0705   using Base::find;
0706 
0707   // btree_multiset::lower_bound()
0708   //
0709   // template <typename K> iterator lower_bound(const K& key):
0710   // template <typename K> const_iterator lower_bound(const K& key) const:
0711   //
0712   // Finds the first element that is not less than `key` within the
0713   // `btree_multiset`.
0714   //
0715   // Supports heterogeneous lookup, provided that the set has a compatible
0716   // heterogeneous comparator.
0717   using Base::lower_bound;
0718 
0719   // btree_multiset::upper_bound()
0720   //
0721   // template <typename K> iterator upper_bound(const K& key):
0722   // template <typename K> const_iterator upper_bound(const K& key) const:
0723   //
0724   // Finds the first element that is greater than `key` within the
0725   // `btree_multiset`.
0726   //
0727   // Supports heterogeneous lookup, provided that the set has a compatible
0728   // heterogeneous comparator.
0729   using Base::upper_bound;
0730 
0731   // btree_multiset::get_allocator()
0732   //
0733   // Returns the allocator function associated with this `btree_multiset`.
0734   using Base::get_allocator;
0735 
0736   // btree_multiset::key_comp();
0737   //
0738   // Returns the key comparator associated with this `btree_multiset`.
0739   using Base::key_comp;
0740 
0741   // btree_multiset::value_comp();
0742   //
0743   // Returns the value comparator associated with this `btree_multiset`. The
0744   // keys to sort the elements are the values themselves, therefore `value_comp`
0745   // and its sibling member function `key_comp` are equivalent.
0746   using Base::value_comp;
0747 };
0748 
0749 // absl::swap(absl::btree_multiset<>, absl::btree_multiset<>)
0750 //
0751 // Swaps the contents of two `absl::btree_multiset` containers.
0752 template <typename K, typename C, typename A>
0753 void swap(btree_multiset<K, C, A> &x, btree_multiset<K, C, A> &y) {
0754   return x.swap(y);
0755 }
0756 
0757 // absl::erase_if(absl::btree_multiset<>, Pred)
0758 //
0759 // Erases all elements that satisfy the predicate pred from the container.
0760 // Returns the number of erased elements.
0761 template <typename K, typename C, typename A, typename Pred>
0762 typename btree_multiset<K, C, A>::size_type erase_if(
0763    btree_multiset<K, C, A> & set, Pred pred) {
0764   return container_internal::btree_access::erase_if(set, std::move(pred));
0765 }
0766 
0767 namespace container_internal {
0768 
0769 // This type implements the necessary functions from the
0770 // absl::container_internal::slot_type interface for btree_(multi)set.
0771 template <typename Key>
0772 struct set_slot_policy {
0773   using slot_type = Key;
0774   using value_type = Key;
0775   using mutable_value_type = Key;
0776 
0777   static value_type &element(slot_type *slot) { return *slot; }
0778   static const value_type &element(const slot_type *slot) { return *slot; }
0779 
0780   template <typename Alloc, class... Args>
0781   static void construct(Alloc *alloc, slot_type *slot, Args &&...args) {
0782     absl::allocator_traits<Alloc>::construct(*alloc, slot,
0783                                              std::forward<Args>(args)...);
0784   }
0785 
0786   template <typename Alloc>
0787   static void construct(Alloc *alloc, slot_type *slot, slot_type *other) {
0788     absl::allocator_traits<Alloc>::construct(*alloc, slot, std::move(*other));
0789   }
0790 
0791   template <typename Alloc>
0792   static void construct(Alloc *alloc, slot_type *slot, const slot_type *other) {
0793     absl::allocator_traits<Alloc>::construct(*alloc, slot, *other);
0794   }
0795 
0796   template <typename Alloc>
0797   static void destroy(Alloc *alloc, slot_type *slot) {
0798     absl::allocator_traits<Alloc>::destroy(*alloc, slot);
0799   }
0800 };
0801 
0802 // A parameters structure for holding the type parameters for a btree_set.
0803 // Compare and Alloc should be nothrow copy-constructible.
0804 template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
0805           bool IsMulti>
0806 struct set_params : common_params<Key, Compare, Alloc, TargetNodeSize, IsMulti,
0807                                   /*IsMap=*/false, set_slot_policy<Key>> {
0808   using value_type = Key;
0809   using slot_type = typename set_params::common_params::slot_type;
0810 
0811   template <typename V>
0812   static const V &key(const V &value) {
0813     return value;
0814   }
0815   static const Key &key(const slot_type *slot) { return *slot; }
0816   static const Key &key(slot_type *slot) { return *slot; }
0817 };
0818 
0819 }  // namespace container_internal
0820 
0821 ABSL_NAMESPACE_END
0822 }  // namespace absl
0823 
0824 #endif  // ABSL_CONTAINER_BTREE_SET_H_