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