C/C++ API Reference
Loading...
Searching...
No Matches
intrusive_multiset.h
1// Copyright 2024 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// 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, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include "pw_containers/internal/aa_tree.h"
17#include "pw_containers/internal/aa_tree_item.h"
18
19namespace pw {
20
22
25
60template <typename T>
62 private:
63 using GenericIterator = containers::internal::GenericAATree::iterator;
65 using Compare = typename Tree::Compare;
66 using GetKey = typename Tree::GetKey;
67
68 public:
70 using Item = typename Tree::Item;
71
72 using key_type = T;
73 using value_type = T;
74 using size_type = std::size_t;
75 using difference_type = std::ptrdiff_t;
76 using key_compare = Compare;
77 using value_compare = Compare;
78 using reference = value_type&;
79 using const_reference = const value_type&;
80 using pointer = value_type*;
81 using const_pointer = const value_type*;
82
83 public:
84 class iterator : public containers::internal::AATreeIterator<T> {
85 public:
86 constexpr iterator() = default;
87
88 private:
89 using Base = containers::internal::AATreeIterator<T>;
90 friend IntrusiveMultiSet;
91 constexpr explicit iterator(GenericIterator iter) : Base(iter) {}
92 };
93
95 : public containers::internal::AATreeIterator<std::add_const_t<T>> {
96 public:
97 constexpr const_iterator() = default;
98
99 private:
100 using Base = containers::internal::AATreeIterator<std::add_const_t<T>>;
101 friend IntrusiveMultiSet;
102 constexpr explicit const_iterator(GenericIterator iter) : Base(iter) {}
103 };
104
105 using reverse_iterator = std::reverse_iterator<iterator>;
106 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
107
109 constexpr explicit IntrusiveMultiSet() : IntrusiveMultiSet(std::less<>()) {}
110
118 template <typename Comparator>
119 constexpr explicit IntrusiveMultiSet(Comparator compare)
120 : tree_(false, std::move(compare), [](const T& t) -> const T& {
121 return t;
122 }) {
123 CheckItemType();
124 }
125
130 template <typename Iterator, typename... Functors>
131 IntrusiveMultiSet(Iterator first, Iterator last, Functors&&... functors)
132 : IntrusiveMultiSet(std::forward<Functors>(functors)...) {
133 tree_.insert(first, last);
134 }
135
138 template <typename... Functors>
139 IntrusiveMultiSet(std::initializer_list<T*> items, Functors&&... functors)
141 items.begin(), items.end(), std::forward<Functors>(functors)...) {}
142
143 // Iterators
144
145 iterator begin() noexcept { return iterator(tree_.begin()); }
146 const_iterator begin() const noexcept {
147 return const_iterator(tree_.begin());
148 }
149 const_iterator cbegin() const noexcept { return begin(); }
150
151 iterator end() noexcept { return iterator(tree_.end()); }
152 const_iterator end() const noexcept { return const_iterator(tree_.end()); }
153 const_iterator cend() const noexcept { return end(); }
154
155 reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
156 const_reverse_iterator rbegin() const noexcept {
157 return const_reverse_iterator(end());
158 }
159 const_reverse_iterator crbegin() const noexcept { return rbegin(); }
160
161 reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
162 const_reverse_iterator rend() const noexcept {
163 return const_reverse_iterator(begin());
164 }
165 const_reverse_iterator crend() const noexcept { return rend(); }
166
167 // Capacity
168
170 [[nodiscard]] bool empty() const noexcept { return tree_.empty(); }
171
173 size_t size() const { return tree_.size(); }
174
178 constexpr size_t max_size() const noexcept { return tree_.max_size(); }
179
180 // Modifiers
181
185 void clear() { tree_.clear(); }
186
188 iterator insert(T& item) { return iterator(tree_.insert(item).first); }
189
190 iterator insert(iterator, T& item) {
191 // Disregard the hint.
192 return iterator(insert(item));
193 }
194
195 template <class Iterator>
196 void insert(Iterator first, Iterator last) {
197 tree_.insert(first, last);
198 }
199
200 void insert(std::initializer_list<T*> ilist) {
201 tree_.insert(ilist.begin(), ilist.end());
202 }
203
208 iterator erase(iterator pos) { return iterator(tree_.erase_one(*pos)); }
209
210 iterator erase(iterator first, iterator last) {
211 return iterator(tree_.erase_range(*first, *last));
212 }
213
214 size_t erase(const T& item) { return tree_.erase_all(item); }
215
217 void swap(IntrusiveMultiSet<T>& other) { tree_.swap(other.tree_); }
218
222 template <typename MapType>
223 void merge(MapType& other) {
224 tree_.merge(other.tree_);
225 }
226
228 size_t count(const T& item) const { return tree_.count(item); }
229
232 iterator find(const T& item) { return iterator(tree_.find(item)); }
233
234 const_iterator find(const T& item) const {
235 return const_iterator(tree_.find(item));
236 }
237
241 std::pair<iterator, iterator> equal_range(const T& item) {
242 auto result = tree_.equal_range(item);
243 return std::make_pair(iterator(result.first), iterator(result.second));
244 }
245 std::pair<const_iterator, const_iterator> equal_range(const T& item) const {
246 auto result = tree_.equal_range(item);
247 return std::make_pair(const_iterator(result.first),
248 const_iterator(result.second));
249 }
250
254 iterator lower_bound(const T& item) {
255 return iterator(tree_.lower_bound(item));
256 }
257 const_iterator lower_bound(const T& item) const {
258 return const_iterator(tree_.lower_bound(item));
259 }
260
264 iterator upper_bound(const T& item) {
265 return iterator(tree_.upper_bound(item));
266 }
267 const_iterator upper_bound(const T& item) const {
268 return const_iterator(tree_.upper_bound(item));
269 }
270
271 private:
272 // Check that T is an Item in a function, since the class T will not be fully
273 // defined when the IntrusiveList<T> class is instantiated.
274 static constexpr void CheckItemType() {
275 using ItemBase = containers::internal::AATreeItem;
276 using IntrusiveItemType =
277 typename containers::internal::IntrusiveItem<ItemBase, T>::Type;
278 static_assert(
279 std::is_base_of<IntrusiveItemType, T>(),
280 "IntrusiveMultiSet items must be derived from "
281 "IntrusiveMultiSet<T>::Item, where T is the item or one of its "
282 "bases.");
283 }
284
285 // Allow sets to access the tree for `merge`.
286 template <typename>
287 friend class IntrusiveSet;
288
289 // The AA tree that stores the set.
290 //
291 // This field is mutable so that it doesn't need const overloads.
292 mutable Tree tree_;
293};
294
295} // namespace pw
Definition: intrusive_multiset.h:95
Definition: intrusive_multiset.h:84
Definition: intrusive_multiset.h:61
iterator erase_range(AATreeItem &first, AATreeItem &last)
iterator erase_one(AATreeItem &item)
void swap(IntrusiveMultiSet< T > &other)
Exchanges this multiset's items with the other multiset's items.
Definition: intrusive_multiset.h:217
iterator erase(iterator pos)
Definition: intrusive_multiset.h:208
constexpr IntrusiveMultiSet()
Constructs an empty set of items.
Definition: intrusive_multiset.h:109
IntrusiveMultiSet(std::initializer_list< T * > items, Functors &&... functors)
Definition: intrusive_multiset.h:139
size_t size() const
Returns the number of items in the multiset.
Definition: intrusive_multiset.h:173
bool empty() const noexcept
Returns whether the multiset has zero items or not.
Definition: intrusive_multiset.h:170
iterator upper_bound(const T &item)
Definition: intrusive_multiset.h:264
void clear()
Definition: intrusive_multiset.h:185
iterator find(const T &item)
Definition: intrusive_multiset.h:232
constexpr IntrusiveMultiSet(Comparator compare)
Definition: intrusive_multiset.h:119
typename Tree::Item Item
IntrusiveMultiSet items must derive from Item.
Definition: intrusive_multiset.h:70
iterator lower_bound(const T &item)
Definition: intrusive_multiset.h:254
std::pair< iterator, iterator > equal_range(const T &item)
Definition: intrusive_multiset.h:241
constexpr size_t max_size() const noexcept
Definition: intrusive_multiset.h:178
void merge(MapType &other)
Definition: intrusive_multiset.h:223
size_t count(const T &item) const
Returns the number of items in the multimap with the given key.
Definition: intrusive_multiset.h:228
iterator insert(T &item)
Adds the given item to the multiset.
Definition: intrusive_multiset.h:188
IntrusiveMultiSet(Iterator first, Iterator last, Functors &&... functors)
Definition: intrusive_multiset.h:131
iterator lower_bound(Key key)
Definition: aa_tree.h:400
constexpr iterator begin() noexcept
Returns a pointer to the first item, if any.
Definition: aa_tree.h:62
constexpr size_t max_size() const noexcept
Definition: aa_tree.h:83
std::pair< iterator, iterator > equal_range(Key key)
Definition: aa_tree.h:395
iterator upper_bound(Key key)
Definition: aa_tree.h:424
void merge(KeyedAATree< K > &other)
Definition: aa_tree.h:370
iterator find(Key key)
Definition: aa_tree.h:385
std::pair< iterator, bool > insert(AATreeItem &item)
Definition: aa_tree.h:306
size_t erase_all(Key key)
Definition: aa_tree.h:359
void swap(GenericAATree &other)
Exchanges this tree's items with the other tree's items.
size_t size() const
Returns the number of items in the tree.
constexpr bool empty() const
Returns whether the tree has zero items or not.
Definition: aa_tree.h:75
size_t count(Key key)
Definition: aa_tree.h:380
constexpr iterator end() noexcept
Returns a pointer to the last item, if any.
Definition: aa_tree.h:67
The Pigweed namespace.
Definition: alignment.h:27