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