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