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