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 {
38 using iterator = AATreeIterator<>;
45 : unique_keys_(unique_keys) {}
54 [[nodiscard]]
constexpr bool unique_keys()
const {
return unique_keys_; }
62 constexpr iterator
begin() noexcept {
63 return empty() ? iterator(&root_) : iterator(&root_, root_->GetLeftmost());
67 constexpr iterator
end() noexcept {
68 return empty() ? iterator(&root_)
69 : ++(iterator(&root_, root_->GetRightmost()));
75 [[nodiscard]]
constexpr bool empty()
const {
return root_ ==
nullptr; }
84 return std::numeric_limits<ptrdiff_t>::max();
115 AATreeItem* root_ =
nullptr;
128 const bool unique_keys_;
144 using Compare =
Function<bool(Key, Key)>;
145 using GetKey =
Function<Key(
const AATreeItem&)>;
146 using GenericAATree::iterator;
156 compare_(std::move(compare)),
157 get_key_(std::move(get_key)) {}
161 void SetCompare(Compare&& compare) { compare_ = std::move(compare); }
162 void SetGetKey(GetKey&& get_key) { get_key_ = std::move(get_key); }
173 std::pair<iterator, bool>
insert(AATreeItem& item);
178 template <
class Iterator>
179 void insert(Iterator first, Iterator last);
223 AATreeItem* InsertImpl(AATreeItem& parent,
225 AATreeItem*& duplicate);
230 AATreeItem* GetLowerBoundImpl(AATreeItem* item, Key key);
235 AATreeItem* GetUpperBoundImpl(AATreeItem* item, Key key);
252template <
typename K,
typename V>
256 using Key =
typename Base::Key;
257 using Compare =
typename Base::Compare;
258 using GetKey =
Function<Key(
const V&)>;
264 class Item :
public AATreeItem {
266 constexpr explicit Item() =
default;
271 template <
typename,
typename,
bool>
272 friend struct IntrusiveItem;
279 constexpr explicit Pair(Key key) : key_(key) {}
280 constexpr Key key()
const {
return key_; }
282 constexpr bool operator<(
const Pair& rhs) {
return key_ < rhs.key(); }
292 constexpr AATree(
bool unique_keys, Compare&& compare, GetKey&& get_key)
295 std::move([this](const AATreeItem& item) -> Key {
296 return get_key_(static_cast<const V&>(item));
298 get_key_(std::move(get_key)) {}
308 CheckIntrusiveItemIsUncontained(!item.IsMapped());
312 return std::make_pair(iterator(&root_, &item),
true);
314 AATreeItem* duplicate =
nullptr;
315 SetRoot(InsertImpl(*root_, item, duplicate));
316 if (duplicate ==
nullptr) {
317 return std::make_pair(iterator(&root_, &item),
true);
320 return std::make_pair(iterator(&root_, duplicate),
false);
326 AATreeItem*& duplicate) {
327 if (compare_(get_key_(child), get_key_(parent))) {
328 AATreeItem* left = parent.left_.get();
329 left = left ==
nullptr ? &child : InsertImpl(*left, child, duplicate);
330 parent.SetLeft(left);
332 }
else if (compare_(get_key_(parent), get_key_(child)) || !unique_keys()) {
333 AATreeItem* right = parent.right_.get();
334 right = right ==
nullptr ? &child : InsertImpl(*right, child, duplicate);
335 parent.SetRight(right);
342 return parent.Skew()->Split();
346template <
class Iterator>
348 for (Iterator iter = first; iter != last; ++iter) {
349 if constexpr (std::is_pointer_v<
350 typename std::iterator_traits<Iterator>::value_type>) {
361 iterator iter = lower_bound(key);
362 while (iter != end() && !compare_(key, get_key_(*iter))) {
363 iter = erase_one(*iter);
371 auto iter = other.
begin();
372 while (!other.
empty()) {
373 AATreeItem& item = *iter;
381 return std::distance(lower_bound(key), upper_bound(key));
386 iterator iter = lower_bound(key);
387 if (iter == end() || compare_(key, get_key_(*iter))) {
394std::pair<GenericAATree::iterator, GenericAATree::iterator>
396 return std::make_pair(lower_bound(key), upper_bound(key));
401 AATreeItem* item = GetLowerBoundImpl(root_, key);
402 return item ==
nullptr ? end() : iterator(&root_, item);
407 if (item ==
nullptr) {
411 if (compare_(get_key_(*item), key)) {
412 return GetLowerBoundImpl(item->right_.get(), key);
415 AATreeItem* left = item->left_.get();
416 if (left ==
nullptr) {
419 AATreeItem* next = GetLowerBoundImpl(left, key);
420 return next ==
nullptr ? item : next;
425 AATreeItem* item = GetUpperBoundImpl(root_, key);
426 return item ==
nullptr ? end() : iterator(&root_, item);
431 if (item ==
nullptr) {
435 if (!compare_(key, get_key_(*item))) {
436 return GetUpperBoundImpl(item->right_.get(), key);
439 AATreeItem* left = item->left_.get();
440 if (left ==
nullptr) {
443 AATreeItem* next = GetUpperBoundImpl(left, key);
444 return next ==
nullptr ? item : next;
Definition: aa_tree.h:264
An extension of Item that includes storage for a key.
Definition: aa_tree.h:277
Definition: aa_tree.h:253
Definition: aa_tree.h:141
iterator erase_one(AATreeItem &item)
iterator erase_range(AATreeItem &first, AATreeItem &last)
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 insert(Iterator first, Iterator last)
Definition: aa_tree.h:347
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
iterator erase_one(AATreeItem &item)
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.
~GenericAATree()
Destructor.
Definition: aa_tree.h:48
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:75
constexpr GenericAATree(bool unique_keys)
Definition: aa_tree.h:44
constexpr KeyedAATree(bool unique_keys, Compare &&compare, GetKey &&get_key)
Definition: aa_tree.h:152
size_t count(Key key)
Definition: aa_tree.h:380
constexpr AATree(bool unique_keys, Compare &&compare, GetKey &&get_key)
Definition: aa_tree.h:292
constexpr iterator end() noexcept
Returns a pointer to the last item, if any.
Definition: aa_tree.h:67
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:73