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