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