21#include "pw_assert/assert.h"
22#include "pw_containers/internal/aa_tree_item.h"
23#include "pw_containers/internal/aa_tree_iterator.h"
24#include "pw_containers/internal/intrusive_item.h"
25#include "pw_function/function.h"
27namespace pw::containers::internal {
36 using iterator = AATreeIterator<>;
43 : unique_keys_(unique_keys) {}
52 [[nodiscard]]
constexpr bool unique_keys()
const {
return unique_keys_; }
60 constexpr iterator
begin() noexcept {
61 return empty() ? iterator(&root_) : iterator(&root_, root_->GetLeftmost());
65 constexpr iterator
end() noexcept {
66 return empty() ? iterator(&root_)
67 : ++(iterator(&root_, root_->GetRightmost()));
73 [[nodiscard]]
constexpr bool empty()
const {
return root_ ==
nullptr; }
82 return std::numeric_limits<ptrdiff_t>::max();
109 template <
typename,
typename>
113 AATreeItem* root_ =
nullptr;
126 const bool unique_keys_;
140template <
typename K,
typename V>
144 using Compare =
Function<bool(Key, Key)>;
145 using GetKey =
Function<Key(
const V&)>;
146 using GenericAATree::iterator;
152 class Item :
public AATreeItem {
154 constexpr explicit Item() =
default;
159 template <
typename,
typename,
bool>
160 friend struct IntrusiveItem;
167 constexpr explicit Pair(Key key) : key_(key) {}
168 constexpr Key key()
const {
return key_; }
170 constexpr bool operator<(
const Pair& rhs) {
return key_ < rhs.key(); }
180 constexpr AATree(
bool unique_keys, Compare&& compare, GetKey&& get_key)
182 compare_(std::move(compare)),
183 get_key_(std::move(get_key)) {}
196 std::pair<iterator, bool>
insert(AATreeItem& item);
201 template <
class Iterator>
202 void insert(Iterator first, Iterator last);
246 AATreeItem* InsertImpl(AATreeItem& parent,
248 AATreeItem*& duplicate);
253 AATreeItem* GetLowerBoundImpl(AATreeItem* item, Key key);
258 AATreeItem* GetUpperBoundImpl(AATreeItem* item, Key key);
261 constexpr Key DoGetKey(
const AATreeItem& item) {
262 return get_key_(
static_cast<const V&
>(item));
271template <
typename K,
typename V>
274 CheckIntrusiveItemIsUncontained(!item.IsMapped());
278 return std::make_pair(iterator(&root_, &item),
true);
280 AATreeItem* duplicate =
nullptr;
281 SetRoot(InsertImpl(*root_, item, duplicate));
282 if (duplicate ==
nullptr) {
283 return std::make_pair(iterator(&root_, &item),
true);
286 return std::make_pair(iterator(&root_, duplicate),
false);
289template <
typename K,
typename V>
292 AATreeItem*& duplicate) {
293 if (compare_(DoGetKey(child), DoGetKey(parent))) {
294 AATreeItem* left = parent.left_.get();
295 left = left ==
nullptr ? &child : InsertImpl(*left, child, duplicate);
296 parent.SetLeft(left);
298 }
else if (compare_(DoGetKey(parent), DoGetKey(child)) || !unique_keys()) {
299 AATreeItem* right = parent.right_.get();
300 right = right ==
nullptr ? &child : InsertImpl(*right, child, duplicate);
301 parent.SetRight(right);
308 return parent.Skew()->Split();
311template <
typename K,
typename V>
312template <
class Iterator>
314 for (Iterator iter = first; iter != last; ++iter) {
315 if constexpr (std::is_pointer_v<
316 typename std::iterator_traits<Iterator>::value_type>) {
324template <
typename K,
typename V>
327 iterator iter = lower_bound(key);
328 while (iter != end() && !compare_(key, DoGetKey(*iter))) {
329 iter = erase_one(*iter);
335template <
typename K,
typename V>
337 auto iter = other.
begin();
338 while (!other.
empty()) {
339 AATreeItem& item = *iter;
345template <
typename K,
typename V>
347 return std::distance(lower_bound(key), upper_bound(key));
350template <
typename K,
typename V>
352 iterator iter = lower_bound(key);
353 if (iter == end() || compare_(key, DoGetKey(*iter))) {
359template <
typename K,
typename V>
360std::pair<GenericAATree::iterator, GenericAATree::iterator>
362 return std::make_pair(lower_bound(key), upper_bound(key));
365template <
typename K,
typename V>
367 AATreeItem* item = GetLowerBoundImpl(root_, key);
368 return item ==
nullptr ? end() : iterator(&root_, item);
371template <
typename K,
typename V>
373 if (item ==
nullptr) {
377 if (compare_(DoGetKey(*item), key)) {
378 return GetLowerBoundImpl(item->right_.get(), key);
381 AATreeItem* left = item->left_.get();
382 if (left ==
nullptr) {
385 AATreeItem* next = GetLowerBoundImpl(left, key);
386 return next ==
nullptr ? item : next;
389template <
typename K,
typename V>
391 AATreeItem* item = GetUpperBoundImpl(root_, key);
392 return item ==
nullptr ? end() : iterator(&root_, item);
395template <
typename K,
typename V>
397 if (item ==
nullptr) {
401 if (!compare_(key, DoGetKey(*item))) {
402 return GetUpperBoundImpl(item->right_.get(), key);
405 AATreeItem* left = item->left_.get();
406 if (left ==
nullptr) {
409 AATreeItem* next = GetUpperBoundImpl(left, key);
410 return next ==
nullptr ? item : next;
Definition: aa_tree.h:152
An extension of Item that includes storage for a key.
Definition: aa_tree.h:165
Definition: aa_tree.h:141
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
void insert(Iterator first, Iterator last)
Definition: aa_tree.h:313
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 AATree(bool unique_keys, Compare &&compare, GetKey &&get_key)
Definition: aa_tree.h:180
iterator erase_range(AATreeItem &first, AATreeItem &last)
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
iterator erase_one(AATreeItem &item)
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.
~GenericAATree()
Destructor.
Definition: aa_tree.h:46
void SetRoot(AATreeItem *item)
Sets the tree's root item.
constexpr bool empty() const
Returns whether the tree has zero items or not.
Definition: aa_tree.h:73
constexpr GenericAATree(bool unique_keys)
Definition: aa_tree.h:42
constexpr iterator end() noexcept
Returns a pointer to the last item, if any.
Definition: aa_tree.h:65
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:74