mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
util: follow 90fd771
to its natural conclusion (generic base rbtree)
This commit is contained in:
parent
388f9e6455
commit
d52179c708
1 changed files with 290 additions and 158 deletions
|
@ -22,58 +22,267 @@
|
||||||
|
|
||||||
namespace ams::util {
|
namespace ams::util {
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
|
class IntrusiveRedBlackTreeImpl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct IntrusiveRedBlackTreeNode {
|
struct IntrusiveRedBlackTreeNode {
|
||||||
NON_COPYABLE(IntrusiveRedBlackTreeNode);
|
NON_COPYABLE(IntrusiveRedBlackTreeNode);
|
||||||
private:
|
private:
|
||||||
RB_ENTRY(IntrusiveRedBlackTreeNode) entry;
|
RB_ENTRY(IntrusiveRedBlackTreeNode) entry;
|
||||||
|
|
||||||
|
friend class impl::IntrusiveRedBlackTreeImpl;
|
||||||
|
|
||||||
template<class, class, class>
|
template<class, class, class>
|
||||||
friend class IntrusiveRedBlackTree;
|
friend class IntrusiveRedBlackTree;
|
||||||
|
|
||||||
template<class, class>
|
|
||||||
friend class IntrusiveRedBlackTreeImpl;
|
|
||||||
public:
|
public:
|
||||||
constexpr IntrusiveRedBlackTreeNode() : entry() { /* ... */}
|
constexpr IntrusiveRedBlackTreeNode() : entry() { /* ... */}
|
||||||
};
|
};
|
||||||
static_assert(std::is_literal_type<IntrusiveRedBlackTreeNode>::value);
|
static_assert(std::is_literal_type<IntrusiveRedBlackTreeNode>::value);
|
||||||
|
|
||||||
template<class T, class Traits>
|
template<class T, class Traits, class Comparator>
|
||||||
class IntrusiveRedBlackTreeImpl {
|
class IntrusiveRedBlackTree;
|
||||||
NON_COPYABLE(IntrusiveRedBlackTreeImpl);
|
|
||||||
protected:
|
namespace impl {
|
||||||
RB_HEAD(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode);
|
|
||||||
using RootType = IntrusiveRedBlackTreeRoot;
|
class IntrusiveRedBlackTreeImpl {
|
||||||
protected:
|
NON_COPYABLE(IntrusiveRedBlackTreeImpl);
|
||||||
IntrusiveRedBlackTreeRoot root;
|
private:
|
||||||
|
template<class, class, class>
|
||||||
|
friend class ::ams::util::IntrusiveRedBlackTree;
|
||||||
|
private:
|
||||||
|
RB_HEAD(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode);
|
||||||
|
using RootType = IntrusiveRedBlackTreeRoot;
|
||||||
|
private:
|
||||||
|
IntrusiveRedBlackTreeRoot root;
|
||||||
|
public:
|
||||||
|
template<bool Const>
|
||||||
|
class Iterator;
|
||||||
|
|
||||||
|
using value_type = IntrusiveRedBlackTreeNode;
|
||||||
|
using size_type = size_t;
|
||||||
|
using difference_type = ptrdiff_t;
|
||||||
|
using pointer = value_type *;
|
||||||
|
using const_pointer = const value_type *;
|
||||||
|
using reference = value_type &;
|
||||||
|
using const_reference = const value_type &;
|
||||||
|
using iterator = Iterator<false>;
|
||||||
|
using const_iterator = Iterator<true>;
|
||||||
|
|
||||||
|
template<bool Const>
|
||||||
|
class Iterator {
|
||||||
|
public:
|
||||||
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
|
using value_type = typename IntrusiveRedBlackTreeImpl::value_type;
|
||||||
|
using difference_type = typename IntrusiveRedBlackTreeImpl::difference_type;
|
||||||
|
using pointer = typename std::conditional<Const, IntrusiveRedBlackTreeImpl::const_pointer, IntrusiveRedBlackTreeImpl::pointer>::type;
|
||||||
|
using reference = typename std::conditional<Const, IntrusiveRedBlackTreeImpl::const_reference, IntrusiveRedBlackTreeImpl::reference>::type;
|
||||||
|
private:
|
||||||
|
pointer node;
|
||||||
|
public:
|
||||||
|
explicit Iterator(pointer n) : node(n) { /* ... */ }
|
||||||
|
|
||||||
|
bool operator==(const Iterator &rhs) const {
|
||||||
|
return this->node == rhs.node;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Iterator &rhs) const {
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer operator->() const {
|
||||||
|
return this->node;
|
||||||
|
}
|
||||||
|
|
||||||
|
reference operator*() const {
|
||||||
|
return *this->node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator &operator++() {
|
||||||
|
this->node = GetNext(this->node);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator &operator--() {
|
||||||
|
this->node = GetPrev(this->node);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator operator++(int) {
|
||||||
|
const Iterator it{*this};
|
||||||
|
++(*this);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator operator--(int) {
|
||||||
|
const Iterator it{*this};
|
||||||
|
--(*this);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator Iterator<true>() const {
|
||||||
|
return Iterator<true>(this->node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
/* Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot. */
|
||||||
|
RB_GENERATE_WITHOUT_COMPARE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry);
|
||||||
|
private:
|
||||||
|
/* Define accessors using RB_* functions. */
|
||||||
|
constexpr ALWAYS_INLINE void InitializeImpl() {
|
||||||
|
RB_INIT(&this->root);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EmptyImpl() const {
|
||||||
|
return RB_EMPTY(&this->root);
|
||||||
|
}
|
||||||
|
|
||||||
|
IntrusiveRedBlackTreeNode *GetMinImpl() const {
|
||||||
|
return RB_MIN(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root));
|
||||||
|
}
|
||||||
|
|
||||||
|
IntrusiveRedBlackTreeNode *GetMaxImpl() const {
|
||||||
|
return RB_MAX(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root));
|
||||||
|
}
|
||||||
|
|
||||||
|
IntrusiveRedBlackTreeNode *RemoveImpl(IntrusiveRedBlackTreeNode *node) {
|
||||||
|
return RB_REMOVE(IntrusiveRedBlackTreeRoot, &this->root, node);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
static IntrusiveRedBlackTreeNode *GetNext(IntrusiveRedBlackTreeNode *node) {
|
||||||
|
return RB_NEXT(IntrusiveRedBlackTreeRoot, nullptr, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static IntrusiveRedBlackTreeNode *GetPrev(IntrusiveRedBlackTreeNode *node) {
|
||||||
|
return RB_PREV(IntrusiveRedBlackTreeRoot, nullptr, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALWAYS_INLINE IntrusiveRedBlackTreeNode const *GetNext(IntrusiveRedBlackTreeNode const *node) {
|
||||||
|
return static_cast<const IntrusiveRedBlackTreeNode *>(GetNext(const_cast<IntrusiveRedBlackTreeNode *>(node)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALWAYS_INLINE IntrusiveRedBlackTreeNode const *GetPrev(IntrusiveRedBlackTreeNode const *node) {
|
||||||
|
return static_cast<const IntrusiveRedBlackTreeNode *>(GetPrev(const_cast<IntrusiveRedBlackTreeNode *>(node)));
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
constexpr IntrusiveRedBlackTreeImpl() : root() {
|
||||||
|
this->InitializeImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterator accessors. */
|
||||||
|
iterator begin() {
|
||||||
|
return iterator(this->GetMinImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator begin() const {
|
||||||
|
return const_iterator(this->GetMinImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end() {
|
||||||
|
return iterator(static_cast<IntrusiveRedBlackTreeNode *>(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator end() const {
|
||||||
|
return const_iterator(static_cast<const IntrusiveRedBlackTreeNode *>(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator cbegin() const {
|
||||||
|
return this->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator cend() const {
|
||||||
|
return this->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator iterator_to(reference ref) {
|
||||||
|
return iterator(&ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator iterator_to(const_reference ref) const {
|
||||||
|
return const_iterator(&ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Content management. */
|
||||||
|
bool empty() const {
|
||||||
|
return this->EmptyImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
reference back() {
|
||||||
|
return *this->GetMaxImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference back() const {
|
||||||
|
return *this->GetMaxImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
reference front() {
|
||||||
|
return *this->GetMinImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference front() const {
|
||||||
|
return *this->GetMinImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator erase(iterator it) {
|
||||||
|
auto cur = std::addressof(*it);
|
||||||
|
auto next = GetNext(cur);
|
||||||
|
this->RemoveImpl(cur);
|
||||||
|
return iterator(next);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class Traits, class Comparator>
|
||||||
|
class IntrusiveRedBlackTree {
|
||||||
|
NON_COPYABLE(IntrusiveRedBlackTree);
|
||||||
public:
|
public:
|
||||||
|
using ImplType = impl::IntrusiveRedBlackTreeImpl;
|
||||||
|
private:
|
||||||
|
ImplType impl;
|
||||||
|
public:
|
||||||
|
struct IntrusiveRedBlackTreeRootWithCompare : ImplType::IntrusiveRedBlackTreeRoot{};
|
||||||
|
|
||||||
template<bool Const>
|
template<bool Const>
|
||||||
class Iterator;
|
class Iterator;
|
||||||
|
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using size_type = size_t;
|
using size_type = size_t;
|
||||||
using difference_type = ptrdiff_t;
|
using difference_type = ptrdiff_t;
|
||||||
using pointer = T *;
|
using pointer = T *;
|
||||||
using const_pointer = const T *;
|
using const_pointer = const T *;
|
||||||
using reference = T &;
|
using reference = T &;
|
||||||
using const_reference = const T &;
|
using const_reference = const T &;
|
||||||
using iterator = Iterator<false>;
|
using iterator = Iterator<false>;
|
||||||
using const_iterator = Iterator<true>;
|
using const_iterator = Iterator<true>;
|
||||||
|
|
||||||
template<bool Const>
|
template<bool Const>
|
||||||
class Iterator {
|
class Iterator {
|
||||||
public:
|
public:
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
friend class IntrusiveRedBlackTree<T, Traits, Comparator>;
|
||||||
using value_type = typename IntrusiveRedBlackTreeImpl::value_type;
|
|
||||||
using difference_type = typename IntrusiveRedBlackTreeImpl::difference_type;
|
|
||||||
using pointer = typename std::conditional<Const, IntrusiveRedBlackTreeImpl::const_pointer, IntrusiveRedBlackTreeImpl::pointer>::type;
|
|
||||||
using reference = typename std::conditional<Const, IntrusiveRedBlackTreeImpl::const_reference, IntrusiveRedBlackTreeImpl::reference>::type;
|
|
||||||
private:
|
|
||||||
pointer node;
|
|
||||||
public:
|
|
||||||
explicit Iterator(pointer n) : node(n) { /* ... */ }
|
|
||||||
|
|
||||||
|
using ImplIterator = typename std::conditional<Const, ImplType::const_iterator, ImplType::iterator>::type;
|
||||||
|
|
||||||
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
|
using value_type = typename IntrusiveRedBlackTree::value_type;
|
||||||
|
using difference_type = typename IntrusiveRedBlackTree::difference_type;
|
||||||
|
using pointer = typename std::conditional<Const, IntrusiveRedBlackTree::const_pointer, IntrusiveRedBlackTree::pointer>::type;
|
||||||
|
using reference = typename std::conditional<Const, IntrusiveRedBlackTree::const_reference, IntrusiveRedBlackTree::reference>::type;
|
||||||
|
private:
|
||||||
|
ImplIterator iterator;
|
||||||
|
private:
|
||||||
|
explicit Iterator(ImplIterator it) : iterator(it) { /* ... */ }
|
||||||
|
|
||||||
|
explicit Iterator(ImplIterator::pointer p) : iterator(p) { /* ... */ }
|
||||||
|
|
||||||
|
ImplIterator GetImplIterator() const {
|
||||||
|
return this->iterator;
|
||||||
|
}
|
||||||
|
public:
|
||||||
bool operator==(const Iterator &rhs) const {
|
bool operator==(const Iterator &rhs) const {
|
||||||
return this->node == rhs.node;
|
return this->iterator == rhs.iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Iterator &rhs) const {
|
bool operator!=(const Iterator &rhs) const {
|
||||||
|
@ -81,99 +290,77 @@ namespace ams::util {
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer operator->() const {
|
pointer operator->() const {
|
||||||
return this->node;
|
return Traits::GetParent(std::addressof(*this->iterator));
|
||||||
}
|
}
|
||||||
|
|
||||||
reference operator*() const {
|
reference operator*() const {
|
||||||
return *this->node;
|
return *Traits::GetParent(std::addressof(*this->iterator));
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator &operator++() {
|
Iterator &operator++() {
|
||||||
this->node = Traits::GetParent(GetNext(Traits::GetNode(this->node)));
|
++this->iterator;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator &operator--() {
|
Iterator &operator--() {
|
||||||
this->node = Traits::GetParent(GetPrev(Traits::GetNode(this->node)));
|
--this->iterator;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator operator++(int) {
|
Iterator operator++(int) {
|
||||||
const Iterator it{*this};
|
const Iterator it{*this};
|
||||||
++(*this);
|
++this->iterator;
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator operator--(int) {
|
Iterator operator--(int) {
|
||||||
const Iterator it{*this};
|
const Iterator it{*this};
|
||||||
--(*this);
|
--this->iterator;
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator Iterator<true>() const {
|
operator Iterator<true>() const {
|
||||||
return Iterator<true>(this->node);
|
return Iterator<true>(this->iterator);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
protected:
|
|
||||||
/* Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot. */
|
|
||||||
RB_GENERATE_WITHOUT_COMPARE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry);
|
|
||||||
private:
|
private:
|
||||||
|
/* Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot. */
|
||||||
|
RB_GENERATE_WITH_COMPARE_STATIC(IntrusiveRedBlackTreeRootWithCompare, IntrusiveRedBlackTreeNode, entry, CompareImpl);
|
||||||
|
private:
|
||||||
|
static int CompareImpl(const IntrusiveRedBlackTreeNode *lhs, const IntrusiveRedBlackTreeNode *rhs) {
|
||||||
|
return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
/* Define accessors using RB_* functions. */
|
/* Define accessors using RB_* functions. */
|
||||||
constexpr ALWAYS_INLINE void InitializeImpl() {
|
IntrusiveRedBlackTreeNode *InsertImpl(IntrusiveRedBlackTreeNode *node) {
|
||||||
RB_INIT(&this->root);
|
return RB_INSERT(IntrusiveRedBlackTreeRootWithCompare, static_cast<IntrusiveRedBlackTreeRootWithCompare *>(&this->impl.root), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmptyImpl() const {
|
IntrusiveRedBlackTreeNode *FindImpl(IntrusiveRedBlackTreeNode const *node) const {
|
||||||
return RB_EMPTY(&this->root);
|
return RB_FIND(IntrusiveRedBlackTreeRootWithCompare, const_cast<IntrusiveRedBlackTreeRootWithCompare *>(static_cast<const IntrusiveRedBlackTreeRootWithCompare *>(&this->impl.root)), const_cast<IntrusiveRedBlackTreeNode *>(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
IntrusiveRedBlackTreeNode *GetMinImpl() const {
|
IntrusiveRedBlackTreeNode *NFindImpl(IntrusiveRedBlackTreeNode const *node) const {
|
||||||
return RB_MIN(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root));
|
return RB_NFIND(IntrusiveRedBlackTreeRootWithCompare, const_cast<IntrusiveRedBlackTreeRootWithCompare *>(static_cast<const IntrusiveRedBlackTreeRootWithCompare *>(&this->impl.root)), const_cast<IntrusiveRedBlackTreeNode *>(node));
|
||||||
}
|
|
||||||
|
|
||||||
IntrusiveRedBlackTreeNode *GetMaxImpl() const {
|
|
||||||
return RB_MAX(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root));
|
|
||||||
}
|
|
||||||
|
|
||||||
IntrusiveRedBlackTreeNode *RemoveImpl(IntrusiveRedBlackTreeNode *node) {
|
|
||||||
return RB_REMOVE(IntrusiveRedBlackTreeRoot, &this->root, node);
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
static constexpr inline IntrusiveRedBlackTreeNode *GetNext(IntrusiveRedBlackTreeNode *node) {
|
constexpr ALWAYS_INLINE IntrusiveRedBlackTree() : impl() { /* ... */ }
|
||||||
return RB_NEXT(IntrusiveRedBlackTreeRoot, nullptr, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr inline IntrusiveRedBlackTreeNode const *GetNext(IntrusiveRedBlackTreeNode const *node) {
|
|
||||||
return const_cast<const IntrusiveRedBlackTreeNode *>(GetNext(const_cast<IntrusiveRedBlackTreeNode *>(node)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr inline IntrusiveRedBlackTreeNode *GetPrev(IntrusiveRedBlackTreeNode *node) {
|
|
||||||
return RB_PREV(IntrusiveRedBlackTreeRoot, nullptr, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr inline IntrusiveRedBlackTreeNode const *GetPrev(IntrusiveRedBlackTreeNode const *node) {
|
|
||||||
return const_cast<const IntrusiveRedBlackTreeNode *>(GetPrev(const_cast<IntrusiveRedBlackTreeNode *>(node)));
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
constexpr ALWAYS_INLINE IntrusiveRedBlackTreeImpl() : root() {
|
|
||||||
this->InitializeImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterator accessors. */
|
/* Iterator accessors. */
|
||||||
iterator begin() {
|
iterator begin() {
|
||||||
return iterator(Traits::GetParent(this->GetMinImpl()));
|
return iterator(this->impl.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator begin() const {
|
const_iterator begin() const {
|
||||||
return const_iterator(Traits::GetParent(this->GetMinImpl()));
|
return const_iterator(this->impl.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator end() {
|
iterator end() {
|
||||||
return iterator(Traits::GetParent(static_cast<IntrusiveRedBlackTreeNode *>(nullptr)));
|
return iterator(this->impl.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator end() const {
|
const_iterator end() const {
|
||||||
return const_iterator(Traits::GetParent(static_cast<IntrusiveRedBlackTreeNode *>(nullptr)));
|
return const_iterator(this->impl.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator cbegin() const {
|
const_iterator cbegin() const {
|
||||||
|
@ -185,93 +372,50 @@ namespace ams::util {
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator iterator_to(reference ref) {
|
iterator iterator_to(reference ref) {
|
||||||
return iterator(&ref);
|
return iterator(this->impl.iterator_to(*Traits::GetNode(std::addressof(ref))));
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator iterator_to(const_reference ref) const {
|
const_iterator iterator_to(const_reference ref) const {
|
||||||
return const_iterator(&ref);
|
return const_iterator(this->impl.iterator_to(*Traits::GetNode(std::addressof(ref))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Content management. */
|
/* Content management. */
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
return this->EmptyImpl();
|
return this->impl.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
reference back() {
|
reference back() {
|
||||||
return *Traits::GetParent(this->GetMaxImpl());
|
return *Traits::GetParent(std::addressof(this->impl.back()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const_reference back() const {
|
const_reference back() const {
|
||||||
return *Traits::GetParent(this->GetMaxImpl());
|
return *Traits::GetParent(std::addressof(this->impl.back()));
|
||||||
}
|
}
|
||||||
|
|
||||||
reference front() {
|
reference front() {
|
||||||
return *Traits::GetParent(this->GetMinImpl());
|
return *Traits::GetParent(std::addressof(this->impl.front()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const_reference front() const {
|
const_reference front() const {
|
||||||
return *Traits::GetParent(this->GetMinImpl());
|
return *Traits::GetParent(std::addressof(this->impl.front()));
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator erase(iterator it) {
|
iterator erase(iterator it) {
|
||||||
auto cur = Traits::GetNode(&*it);
|
return iterator(this->impl.erase(it.GetImplIterator()));
|
||||||
auto next = Traits::GetParent(GetNext(cur));
|
|
||||||
this->RemoveImpl(cur);
|
|
||||||
return iterator(next);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, class Traits, class Comparator>
|
|
||||||
class IntrusiveRedBlackTree : public IntrusiveRedBlackTreeImpl<T, Traits> {
|
|
||||||
NON_COPYABLE(IntrusiveRedBlackTree);
|
|
||||||
public:
|
|
||||||
using ImplType = IntrusiveRedBlackTreeImpl<T, Traits>;
|
|
||||||
|
|
||||||
struct IntrusiveRedBlackTreeRootWithCompare : ImplType::IntrusiveRedBlackTreeRoot{};
|
|
||||||
|
|
||||||
using value_type = ImplType::value_type;
|
|
||||||
using size_type = ImplType::size_type;
|
|
||||||
using difference_type = ImplType::difference_type;
|
|
||||||
using pointer = ImplType::pointer;
|
|
||||||
using const_pointer = ImplType::const_pointer;
|
|
||||||
using reference = ImplType::reference;
|
|
||||||
using const_reference = ImplType::const_reference;
|
|
||||||
using iterator = ImplType::iterator;
|
|
||||||
using const_iterator = ImplType::const_iterator;
|
|
||||||
protected:
|
|
||||||
/* Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot. */
|
|
||||||
RB_GENERATE_WITH_COMPARE_STATIC(IntrusiveRedBlackTreeRootWithCompare, IntrusiveRedBlackTreeNode, entry, CompareImpl);
|
|
||||||
private:
|
|
||||||
static int CompareImpl(const IntrusiveRedBlackTreeNode *lhs, const IntrusiveRedBlackTreeNode *rhs) {
|
|
||||||
return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Define accessors using RB_* functions. */
|
|
||||||
IntrusiveRedBlackTreeNode *InsertImpl(IntrusiveRedBlackTreeNode *node) {
|
|
||||||
return RB_INSERT(IntrusiveRedBlackTreeRootWithCompare, static_cast<IntrusiveRedBlackTreeRootWithCompare *>(&this->root), node);
|
|
||||||
}
|
|
||||||
|
|
||||||
IntrusiveRedBlackTreeNode *FindImpl(IntrusiveRedBlackTreeNode const *node) const {
|
|
||||||
return RB_FIND(IntrusiveRedBlackTreeRootWithCompare, const_cast<IntrusiveRedBlackTreeRootWithCompare *>(static_cast<const IntrusiveRedBlackTreeRootWithCompare *>(&this->root)), const_cast<IntrusiveRedBlackTreeNode *>(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
IntrusiveRedBlackTreeNode *NFindImpl(IntrusiveRedBlackTreeNode const *node) const {
|
|
||||||
return RB_NFIND(IntrusiveRedBlackTreeRootWithCompare, const_cast<IntrusiveRedBlackTreeRootWithCompare *>(static_cast<const IntrusiveRedBlackTreeRootWithCompare *>(&this->root)), const_cast<IntrusiveRedBlackTreeNode *>(node));
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
constexpr ALWAYS_INLINE IntrusiveRedBlackTree() : ImplType() { /* ... */ }
|
|
||||||
|
|
||||||
iterator insert(reference ref) {
|
iterator insert(reference ref) {
|
||||||
this->InsertImpl(Traits::GetNode(&ref));
|
ImplType::pointer node = Traits::GetNode(std::addressof(ref));
|
||||||
return iterator(&ref);
|
this->InsertImpl(node);
|
||||||
|
return iterator(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator find(const_reference ref) const {
|
iterator find(const_reference ref) const {
|
||||||
return iterator(Traits::GetParent(this->FindImpl(Traits::GetNode(&ref))));
|
return iterator(this->FindImpl(Traits::GetNode(std::addressof(ref))));
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator nfind(const_reference ref) const {
|
iterator nfind(const_reference ref) const {
|
||||||
return iterator(Traits::GetParent(this->NFindImpl(Traits::GetNode(&ref))));
|
return iterator(this->NFindImpl(Traits::GetNode(std::addressof(ref))));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -283,12 +427,12 @@ namespace ams::util {
|
||||||
public:
|
public:
|
||||||
template<class Comparator>
|
template<class Comparator>
|
||||||
using TreeType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraits, Comparator>;
|
using TreeType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraits, Comparator>;
|
||||||
using TreeTypeImpl = IntrusiveRedBlackTreeImpl<Derived, IntrusiveRedBlackTreeMemberTraits>;
|
using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl;
|
||||||
private:
|
private:
|
||||||
template<class, class, class>
|
template<class, class, class>
|
||||||
friend class IntrusiveRedBlackTree;
|
friend class IntrusiveRedBlackTree;
|
||||||
template<class, class>
|
|
||||||
friend class IntrusiveRedBlackTreeImpl;
|
friend class impl::IntrusiveRedBlackTreeImpl;
|
||||||
|
|
||||||
static constexpr IntrusiveRedBlackTreeNode *GetNode(Derived *parent) {
|
static constexpr IntrusiveRedBlackTreeNode *GetNode(Derived *parent) {
|
||||||
return std::addressof(parent->*Member);
|
return std::addressof(parent->*Member);
|
||||||
|
@ -318,7 +462,7 @@ namespace ams::util {
|
||||||
public:
|
public:
|
||||||
template<class Comparator>
|
template<class Comparator>
|
||||||
using TreeType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraitsDeferredAssert, Comparator>;
|
using TreeType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraitsDeferredAssert, Comparator>;
|
||||||
using TreeTypeImpl = IntrusiveRedBlackTreeImpl<Derived, IntrusiveRedBlackTreeMemberTraitsDeferredAssert>;
|
using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl;
|
||||||
|
|
||||||
static constexpr bool IsValid() {
|
static constexpr bool IsValid() {
|
||||||
TYPED_STORAGE(Derived) DerivedStorage = {};
|
TYPED_STORAGE(Derived) DerivedStorage = {};
|
||||||
|
@ -327,8 +471,8 @@ namespace ams::util {
|
||||||
private:
|
private:
|
||||||
template<class, class, class>
|
template<class, class, class>
|
||||||
friend class IntrusiveRedBlackTree;
|
friend class IntrusiveRedBlackTree;
|
||||||
template<class, class>
|
|
||||||
friend class IntrusiveRedBlackTreeImpl;
|
friend class impl::IntrusiveRedBlackTreeImpl;
|
||||||
|
|
||||||
static constexpr IntrusiveRedBlackTreeNode *GetNode(Derived *parent) {
|
static constexpr IntrusiveRedBlackTreeNode *GetNode(Derived *parent) {
|
||||||
return std::addressof(parent->*Member);
|
return std::addressof(parent->*Member);
|
||||||
|
@ -350,11 +494,11 @@ namespace ams::util {
|
||||||
template<class Derived>
|
template<class Derived>
|
||||||
class IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode {
|
class IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode {
|
||||||
public:
|
public:
|
||||||
constexpr ALWAYS_INLINE Derived *GetPrev();
|
constexpr ALWAYS_INLINE Derived *GetPrev() { return static_cast< Derived *>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this)); }
|
||||||
constexpr ALWAYS_INLINE const Derived *GetPrev() const;
|
constexpr ALWAYS_INLINE const Derived *GetPrev() const { return static_cast<const Derived *>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this)); }
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE Derived *GetNext();
|
constexpr ALWAYS_INLINE Derived *GetNext() { return static_cast< Derived *>(impl::IntrusiveRedBlackTreeImpl::GetNext(this)); }
|
||||||
constexpr ALWAYS_INLINE const Derived *GetNext() const;
|
constexpr ALWAYS_INLINE const Derived *GetNext() const { return static_cast<const Derived *>(impl::IntrusiveRedBlackTreeImpl::GetNext(this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Derived>
|
template<class Derived>
|
||||||
|
@ -362,12 +506,12 @@ namespace ams::util {
|
||||||
public:
|
public:
|
||||||
template<class Comparator>
|
template<class Comparator>
|
||||||
using TreeType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeBaseTraits, Comparator>;
|
using TreeType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeBaseTraits, Comparator>;
|
||||||
using TreeTypeImpl = IntrusiveRedBlackTreeImpl<Derived, IntrusiveRedBlackTreeBaseTraits>;
|
using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl;
|
||||||
private:
|
private:
|
||||||
template<class, class, class>
|
template<class, class, class>
|
||||||
friend class IntrusiveRedBlackTree;
|
friend class IntrusiveRedBlackTree;
|
||||||
template<class, class>
|
|
||||||
friend class IntrusiveRedBlackTreeImpl;
|
friend class impl::IntrusiveRedBlackTreeImpl;
|
||||||
|
|
||||||
static constexpr IntrusiveRedBlackTreeNode *GetNode(Derived *parent) {
|
static constexpr IntrusiveRedBlackTreeNode *GetNode(Derived *parent) {
|
||||||
return static_cast<IntrusiveRedBlackTreeNode *>(parent);
|
return static_cast<IntrusiveRedBlackTreeNode *>(parent);
|
||||||
|
@ -386,16 +530,4 @@ namespace ams::util {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Derived>
|
|
||||||
constexpr Derived *IntrusiveRedBlackTreeBaseNode<Derived>::GetPrev() { using TreeType = typename IntrusiveRedBlackTreeBaseTraits<Derived>::TreeTypeImpl; return static_cast<Derived *>(TreeType::GetPrev(static_cast<Derived *>(this))); }
|
|
||||||
|
|
||||||
template<class Derived>
|
|
||||||
constexpr const Derived *IntrusiveRedBlackTreeBaseNode<Derived>::GetPrev() const { using TreeType = typename IntrusiveRedBlackTreeBaseTraits<Derived>::TreeTypeImpl; return static_cast<const Derived *>(TreeType::GetPrev(static_cast<const Derived *>(this))); }
|
|
||||||
|
|
||||||
template<class Derived>
|
|
||||||
constexpr Derived *IntrusiveRedBlackTreeBaseNode<Derived>::GetNext() { using TreeType = typename IntrusiveRedBlackTreeBaseTraits<Derived>::TreeTypeImpl; return static_cast<Derived *>(TreeType::GetNext(static_cast<Derived *>(this))); }
|
|
||||||
|
|
||||||
template<class Derived>
|
|
||||||
constexpr const Derived *IntrusiveRedBlackTreeBaseNode<Derived>::GetNext() const { using TreeType = typename IntrusiveRedBlackTreeBaseTraits<Derived>::TreeTypeImpl; return static_cast<const Derived *>(TreeType::GetNext(static_cast<const Derived *>(this))); }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue