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