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