Pigweed
 
Loading...
Searching...
No Matches
intrusive_multimap.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
59template <typename Key, typename T>
61 private:
62 using GenericIterator = containers::internal::GenericAATree::iterator;
64 using Compare = typename Tree::Compare;
65 using GetKey = typename Tree::GetKey;
66
67 public:
72 using Item = typename Tree::Item;
73 using Pair = typename Tree::Pair;
74
75 using key_type = Key;
76 using mapped_type = std::remove_cv_t<T>;
77 using value_type = Item;
78 using size_type = std::size_t;
79 using difference_type = std::ptrdiff_t;
80 using key_compare = Compare;
81 using reference = value_type&;
82 using const_reference = const value_type&;
83 using pointer = value_type*;
84 using const_pointer = const value_type*;
85
86 class iterator : public containers::internal::AATreeIterator<T> {
87 public:
88 constexpr iterator() = default;
89
90 private:
91 using Base = containers::internal::AATreeIterator<T>;
92 friend IntrusiveMultiMap;
93 constexpr explicit iterator(GenericIterator iter) : Base(iter) {}
94 };
95
97 : public containers::internal::AATreeIterator<std::add_const_t<T>> {
98 public:
99 constexpr const_iterator() = default;
100
101 private:
102 using Base = containers::internal::AATreeIterator<std::add_const_t<T>>;
103 friend IntrusiveMultiMap;
104 constexpr explicit const_iterator(GenericIterator iter) : Base(iter) {}
105 };
106
107 using reverse_iterator = std::reverse_iterator<iterator>;
108 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
109
111 constexpr explicit IntrusiveMultiMap()
112 : IntrusiveMultiMap(std::less<Key>()) {}
113
123 template <typename Comparator>
124 constexpr explicit IntrusiveMultiMap(Comparator&& compare)
125 : IntrusiveMultiMap(std::forward<Comparator>(compare),
126 [](const T& t) { return t.key(); }) {}
127
134 template <typename Comparator, typename KeyRetriever>
135 constexpr IntrusiveMultiMap(Comparator&& compare, KeyRetriever&& get_key)
136 : tree_(false,
137 std::forward<Comparator>(compare),
138 std::forward<KeyRetriever>(get_key)) {
139 CheckItemType();
140 }
141
146 template <typename Iterator, typename... Functors>
147 IntrusiveMultiMap(Iterator first, Iterator last, Functors&&... functors)
148 : IntrusiveMultiMap(std::forward<Functors>(functors)...) {
149 tree_.insert(first, last);
150 }
151
154 template <typename... Functors>
155 IntrusiveMultiMap(std::initializer_list<T*> items, Functors&&... functors)
157 items.begin(), items.end(), std::forward<Functors>(functors)...) {}
158
159 // Iterators
160
161 iterator begin() noexcept { return iterator(tree_.begin()); }
162 const_iterator begin() const noexcept {
163 return const_iterator(tree_.begin());
164 }
165 const_iterator cbegin() const noexcept { return begin(); }
166
167 iterator end() noexcept { return iterator(tree_.end()); }
168 const_iterator end() const noexcept { return const_iterator(tree_.end()); }
169 const_iterator cend() const noexcept { return end(); }
170
171 reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
172 const_reverse_iterator rbegin() const noexcept {
173 return const_reverse_iterator(end());
174 }
175 const_reverse_iterator crbegin() const noexcept { return rbegin(); }
176
177 reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
178 const_reverse_iterator rend() const noexcept {
179 return const_reverse_iterator(begin());
180 }
181 const_reverse_iterator crend() const noexcept { return rend(); }
182
183 // Capacity
184
186 [[nodiscard]] bool empty() const noexcept { return tree_.empty(); }
187
189 size_t size() const { return tree_.size(); }
190
194 constexpr size_t max_size() const noexcept { return tree_.max_size(); }
195
196 // Modifiers
197
201 void clear() { tree_.clear(); }
202
204 iterator insert(T& item) { return iterator(tree_.insert(item).first); }
205
206 iterator insert(iterator, T& item) {
207 // Disregard the hint.
208 return iterator(insert(item));
209 }
210
211 template <class Iterator>
212 void insert(Iterator first, Iterator last) {
213 tree_.insert(first, last);
214 }
215
216 void insert(std::initializer_list<T*> ilist) {
217 tree_.insert(ilist.begin(), ilist.end());
218 }
219
224 iterator erase(T& item) { return iterator(tree_.erase_one(item)); }
225
226 iterator erase(iterator pos) { return iterator(tree_.erase_one(*pos)); }
227
228 iterator erase(iterator first, iterator last) {
229 return iterator(tree_.erase_range(*first, *last));
230 }
231
232 size_t erase(const Key& key) { return tree_.erase_all(key); }
233
235 void swap(IntrusiveMultiMap<Key, T>& other) { tree_.swap(other.tree_); }
236
238 template <typename MapType>
239 void merge(MapType& other) {
240 tree_.merge(other.tree_);
241 }
242
244 size_t count(const Key& key) const { return tree_.count(key); }
245
248 iterator find(const Key& key) { return iterator(tree_.find(key)); }
249
250 const_iterator find(const Key& key) const {
251 return const_iterator(tree_.find(key));
252 }
253
257 std::pair<iterator, iterator> equal_range(const Key& key) {
258 auto result = tree_.equal_range(key);
259 return std::make_pair(iterator(result.first), iterator(result.second));
260 }
261 std::pair<const_iterator, const_iterator> equal_range(const Key& key) const {
262 auto result = tree_.equal_range(key);
263 return std::make_pair(const_iterator(result.first),
264 const_iterator(result.second));
265 }
266
270 iterator lower_bound(const Key& key) {
271 return iterator(tree_.lower_bound(key));
272 }
273 const_iterator lower_bound(const Key& key) const {
274 return const_iterator(tree_.lower_bound(key));
275 }
276
280 iterator upper_bound(const Key& key) {
281 return iterator(tree_.upper_bound(key));
282 }
283 const_iterator upper_bound(const Key& key) const {
284 return const_iterator(tree_.upper_bound(key));
285 }
286
287 private:
288 // Check that T is an Item in a function, since the class T will not be fully
289 // defined when the IntrusiveList<T> class is instantiated.
290 static constexpr void CheckItemType() {
291 using ItemBase = containers::internal::AATreeItem;
292 using IntrusiveItemType =
293 typename containers::internal::IntrusiveItem<ItemBase, T>::Type;
294 static_assert(
295 std::is_base_of<IntrusiveItemType, T>(),
296 "IntrusiveMultiMap items must be derived from "
297 "IntrusiveMultiMap<Key, T>::Item, where T is the item or one of its "
298 "bases.");
299 }
300
301 // Allow maps to access the tree for `merge`.
302 template <typename, typename>
303 friend class IntrusiveMap;
304
305 // The AA tree that stores the map.
306 //
307 // This field is mutable so that it doesn't need const overloads.
308 mutable Tree tree_;
309};
310
311} // namespace pw
Definition: intrusive_multimap.h:97
Definition: intrusive_multimap.h:86
Definition: intrusive_multimap.h:60
constexpr IntrusiveMultiMap(Comparator &&compare, KeyRetriever &&get_key)
Definition: intrusive_multimap.h:135
iterator insert(T &item)
Adds the given item to the multimap.
Definition: intrusive_multimap.h:204
iterator upper_bound(const Key &key)
Definition: intrusive_multimap.h:280
constexpr IntrusiveMultiMap(Comparator &&compare)
Definition: intrusive_multimap.h:124
std::pair< iterator, iterator > equal_range(const Key &key)
Definition: intrusive_multimap.h:257
typename Tree::Item Item
Definition: intrusive_multimap.h:72
constexpr IntrusiveMultiMap()
Constructs an empty map of items.
Definition: intrusive_multimap.h:111
void merge(MapType &other)
Splices items from the other map into this one.
Definition: intrusive_multimap.h:239
iterator lower_bound(const Key &key)
Definition: intrusive_multimap.h:270
IntrusiveMultiMap(Iterator first, Iterator last, Functors &&... functors)
Definition: intrusive_multimap.h:147
IntrusiveMultiMap(std::initializer_list< T * > items, Functors &&... functors)
Definition: intrusive_multimap.h:155
void swap(IntrusiveMultiMap< Key, T > &other)
Exchanges this multimap's items with the other multimap's items.
Definition: intrusive_multimap.h:235
iterator find(const Key &key)
Definition: intrusive_multimap.h:248
size_t count(const Key &key) const
Returns the number of items in the multimap with the given key.
Definition: intrusive_multimap.h:244
size_t size() const
Returns the number of items in the multimap.
Definition: intrusive_multimap.h:189
bool empty() const noexcept
Returns whether the multimap has zero items or not.
Definition: intrusive_multimap.h:186
iterator erase(T &item)
Definition: intrusive_multimap.h:224
void clear()
Definition: intrusive_multimap.h:201
constexpr size_t max_size() const noexcept
Definition: intrusive_multimap.h:194
iterator erase_range(AATreeItem &first, AATreeItem &last)
iterator find(Key key)
Definition: aa_tree.h:351
std::pair< iterator, bool > insert(AATreeItem &item)
Definition: aa_tree.h:272
size_t erase_all(Key key)
Definition: aa_tree.h:325
iterator upper_bound(Key key)
Definition: aa_tree.h:390
iterator erase_one(AATreeItem &item)
std::pair< iterator, iterator > equal_range(Key key)
Definition: aa_tree.h:361
iterator lower_bound(Key key)
Definition: aa_tree.h:366
void merge(AATree< K, V > &other)
Definition: aa_tree.h:336
size_t count(Key key)
Definition: aa_tree.h:346
constexpr iterator begin() noexcept
Returns a pointer to the first item, if any.
Definition: aa_tree.h:60
constexpr size_t max_size() const noexcept
Definition: aa_tree.h:81
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:73
constexpr iterator end() noexcept
Returns a pointer to the last item, if any.
Definition: aa_tree.h:65
Provides basic helpers for reading and writing UTF-8 encoded strings.
Definition: alignment.h:27