pineapple-src/src/common/intrusive_red_black_tree.h

628 lines
19 KiB
C
Raw Normal View History

2022-04-23 18:49:07 +00:00
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
2020-12-31 07:31:47 +00:00
#pragma once
2022-03-12 10:35:05 +00:00
#include "common/common_funcs.h"
2020-12-31 07:31:47 +00:00
#include "common/parent_of_member.h"
#include "common/tree.h"
namespace Common {
namespace impl {
class IntrusiveRedBlackTreeImpl;
}
2022-03-12 10:35:05 +00:00
#pragma pack(push, 4)
2020-12-31 07:31:47 +00:00
struct IntrusiveRedBlackTreeNode {
2022-03-12 10:35:05 +00:00
YUZU_NON_COPYABLE(IntrusiveRedBlackTreeNode);
2021-01-13 19:34:26 +00:00
public:
2022-03-12 10:35:05 +00:00
using RBEntry = freebsd::RBEntry<IntrusiveRedBlackTreeNode>;
2021-01-13 19:34:26 +00:00
2022-03-12 10:35:05 +00:00
private:
RBEntry m_entry;
2021-01-13 19:34:26 +00:00
2022-03-12 10:35:05 +00:00
public:
explicit IntrusiveRedBlackTreeNode() = default;
2021-01-13 19:34:26 +00:00
2022-03-12 10:35:05 +00:00
[[nodiscard]] constexpr RBEntry& GetRBEntry() {
return m_entry;
2021-01-13 19:34:26 +00:00
}
2022-03-12 10:35:05 +00:00
[[nodiscard]] constexpr const RBEntry& GetRBEntry() const {
return m_entry;
2021-01-13 19:34:26 +00:00
}
2020-12-31 07:31:47 +00:00
2022-03-12 10:35:05 +00:00
constexpr void SetRBEntry(const RBEntry& entry) {
m_entry = entry;
}
2020-12-31 07:31:47 +00:00
};
2022-03-12 10:35:05 +00:00
static_assert(sizeof(IntrusiveRedBlackTreeNode) ==
3 * sizeof(void*) + std::max<size_t>(sizeof(freebsd::RBColor), 4));
#pragma pack(pop)
2020-12-31 07:31:47 +00:00
template <class T, class Traits, class Comparator>
class IntrusiveRedBlackTree;
namespace impl {
class IntrusiveRedBlackTreeImpl {
2022-03-12 10:35:05 +00:00
YUZU_NON_COPYABLE(IntrusiveRedBlackTreeImpl);
2020-12-31 07:31:47 +00:00
private:
template <class, class, class>
friend class ::Common::IntrusiveRedBlackTree;
2022-03-12 10:35:05 +00:00
private:
using RootType = freebsd::RBHead<IntrusiveRedBlackTreeNode>;
private:
RootType m_root;
2020-12-31 07:31:47 +00:00
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;
2022-03-13 09:13:48 +00:00
using pointer = std::conditional_t<Const, IntrusiveRedBlackTreeImpl::const_pointer,
IntrusiveRedBlackTreeImpl::pointer>;
2022-03-15 02:53:56 +00:00
using reference = std::conditional_t<Const, IntrusiveRedBlackTreeImpl::const_reference,
IntrusiveRedBlackTreeImpl::reference>;
2020-12-31 07:31:47 +00:00
private:
2022-03-12 10:35:05 +00:00
pointer m_node;
2020-12-31 07:31:47 +00:00
public:
2022-03-12 10:35:05 +00:00
constexpr explicit Iterator(pointer n) : m_node(n) {}
2020-12-31 07:31:47 +00:00
2022-03-12 10:35:05 +00:00
constexpr bool operator==(const Iterator& rhs) const {
return m_node == rhs.m_node;
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr bool operator!=(const Iterator& rhs) const {
2020-12-31 07:31:47 +00:00
return !(*this == rhs);
}
2022-03-12 10:35:05 +00:00
constexpr pointer operator->() const {
return m_node;
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr reference operator*() const {
return *m_node;
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr Iterator& operator++() {
m_node = GetNext(m_node);
2020-12-31 07:31:47 +00:00
return *this;
}
2022-03-12 10:35:05 +00:00
constexpr Iterator& operator--() {
m_node = GetPrev(m_node);
2020-12-31 07:31:47 +00:00
return *this;
}
2022-03-12 10:35:05 +00:00
constexpr Iterator operator++(int) {
2020-12-31 07:31:47 +00:00
const Iterator it{*this};
++(*this);
return it;
}
2022-03-12 10:35:05 +00:00
constexpr Iterator operator--(int) {
2020-12-31 07:31:47 +00:00
const Iterator it{*this};
--(*this);
return it;
}
2022-03-12 10:35:05 +00:00
constexpr operator Iterator<true>() const {
return Iterator<true>(m_node);
2020-12-31 07:31:47 +00:00
}
};
private:
2022-03-12 10:35:05 +00:00
constexpr bool EmptyImpl() const {
return m_root.IsEmpty();
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr IntrusiveRedBlackTreeNode* GetMinImpl() const {
return freebsd::RB_MIN(const_cast<RootType&>(m_root));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr IntrusiveRedBlackTreeNode* GetMaxImpl() const {
return freebsd::RB_MAX(const_cast<RootType&>(m_root));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) {
return freebsd::RB_REMOVE(m_root, node);
2020-12-31 07:31:47 +00:00
}
public:
2022-03-12 10:35:05 +00:00
static constexpr IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) {
return freebsd::RB_NEXT(node);
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
static constexpr IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) {
return freebsd::RB_PREV(node);
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
static constexpr IntrusiveRedBlackTreeNode const* GetNext(
IntrusiveRedBlackTreeNode const* node) {
2020-12-31 07:31:47 +00:00
return static_cast<const IntrusiveRedBlackTreeNode*>(
GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node)));
}
2022-03-12 10:35:05 +00:00
static constexpr IntrusiveRedBlackTreeNode const* GetPrev(
IntrusiveRedBlackTreeNode const* node) {
2020-12-31 07:31:47 +00:00
return static_cast<const IntrusiveRedBlackTreeNode*>(
GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node)));
}
public:
2022-03-12 10:35:05 +00:00
constexpr IntrusiveRedBlackTreeImpl() = default;
2020-12-31 07:31:47 +00:00
2021-01-12 09:22:33 +00:00
// Iterator accessors.
2022-03-12 10:35:05 +00:00
constexpr iterator begin() {
2020-12-31 07:31:47 +00:00
return iterator(this->GetMinImpl());
}
2022-03-12 10:35:05 +00:00
constexpr const_iterator begin() const {
2020-12-31 07:31:47 +00:00
return const_iterator(this->GetMinImpl());
}
2022-03-12 10:35:05 +00:00
constexpr iterator end() {
2020-12-31 07:31:47 +00:00
return iterator(static_cast<IntrusiveRedBlackTreeNode*>(nullptr));
}
2022-03-12 10:35:05 +00:00
constexpr const_iterator end() const {
2020-12-31 07:31:47 +00:00
return const_iterator(static_cast<const IntrusiveRedBlackTreeNode*>(nullptr));
}
2022-03-12 10:35:05 +00:00
constexpr const_iterator cbegin() const {
2020-12-31 07:31:47 +00:00
return this->begin();
}
2022-03-12 10:35:05 +00:00
constexpr const_iterator cend() const {
2020-12-31 07:31:47 +00:00
return this->end();
}
2022-03-12 10:35:05 +00:00
constexpr iterator iterator_to(reference ref) {
return iterator(std::addressof(ref));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr const_iterator iterator_to(const_reference ref) const {
return const_iterator(std::addressof(ref));
2020-12-31 07:31:47 +00:00
}
2021-01-12 09:22:33 +00:00
// Content management.
2022-03-12 10:35:05 +00:00
constexpr bool empty() const {
2020-12-31 07:31:47 +00:00
return this->EmptyImpl();
}
2022-03-12 10:35:05 +00:00
constexpr reference back() {
2020-12-31 07:31:47 +00:00
return *this->GetMaxImpl();
}
2022-03-12 10:35:05 +00:00
constexpr const_reference back() const {
2020-12-31 07:31:47 +00:00
return *this->GetMaxImpl();
}
2022-03-12 10:35:05 +00:00
constexpr reference front() {
2020-12-31 07:31:47 +00:00
return *this->GetMinImpl();
}
2022-03-12 10:35:05 +00:00
constexpr const_reference front() const {
2020-12-31 07:31:47 +00:00
return *this->GetMinImpl();
}
2022-03-12 10:35:05 +00:00
constexpr iterator erase(iterator it) {
2020-12-31 07:31:47 +00:00
auto cur = std::addressof(*it);
auto next = GetNext(cur);
this->RemoveImpl(cur);
return iterator(next);
}
};
} // namespace impl
template <typename T>
2022-03-12 10:35:05 +00:00
concept HasRedBlackKeyType = requires {
{ std::is_same<typename T::RedBlackKeyType, void>::value } -> std::convertible_to<bool>;
2020-12-31 07:31:47 +00:00
};
namespace impl {
2021-09-24 22:06:04 +00:00
template <typename T, typename Default>
2022-03-12 10:35:05 +00:00
consteval auto* GetRedBlackKeyType() {
if constexpr (HasRedBlackKeyType<T>) {
return static_cast<typename T::RedBlackKeyType*>(nullptr);
2021-09-24 22:06:04 +00:00
} else {
return static_cast<Default*>(nullptr);
}
2020-12-31 07:31:47 +00:00
}
} // namespace impl
template <typename T, typename Default>
2022-03-15 02:53:56 +00:00
using RedBlackKeyType = std::remove_pointer_t<decltype(impl::GetRedBlackKeyType<T, Default>())>;
2020-12-31 07:31:47 +00:00
template <class T, class Traits, class Comparator>
class IntrusiveRedBlackTree {
2022-03-12 10:35:05 +00:00
YUZU_NON_COPYABLE(IntrusiveRedBlackTree);
2020-12-31 07:31:47 +00:00
public:
using ImplType = impl::IntrusiveRedBlackTreeImpl;
private:
2022-03-12 10:35:05 +00:00
ImplType m_impl;
2020-12-31 07:31:47 +00:00
public:
template <bool Const>
class Iterator;
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using iterator = Iterator<false>;
using const_iterator = Iterator<true>;
2022-03-12 10:35:05 +00:00
using key_type = RedBlackKeyType<Comparator, value_type>;
using const_key_pointer = const key_type*;
using const_key_reference = const key_type&;
2020-12-31 07:31:47 +00:00
template <bool Const>
class Iterator {
public:
friend class IntrusiveRedBlackTree<T, Traits, Comparator>;
using ImplIterator =
2022-03-13 09:13:48 +00:00
std::conditional_t<Const, ImplType::const_iterator, ImplType::iterator>;
2020-12-31 07:31:47 +00:00
using iterator_category = std::bidirectional_iterator_tag;
using value_type = typename IntrusiveRedBlackTree::value_type;
using difference_type = typename IntrusiveRedBlackTree::difference_type;
2021-01-12 09:22:33 +00:00
using pointer = std::conditional_t<Const, IntrusiveRedBlackTree::const_pointer,
IntrusiveRedBlackTree::pointer>;
using reference = std::conditional_t<Const, IntrusiveRedBlackTree::const_reference,
IntrusiveRedBlackTree::reference>;
2020-12-31 07:31:47 +00:00
private:
2022-03-12 10:35:05 +00:00
ImplIterator m_impl;
2020-12-31 07:31:47 +00:00
private:
2022-03-12 10:35:05 +00:00
constexpr explicit Iterator(ImplIterator it) : m_impl(it) {}
2020-12-31 07:31:47 +00:00
2022-03-14 16:02:12 +00:00
constexpr explicit Iterator(typename ImplIterator::pointer p) : m_impl(p) {}
2020-12-31 07:31:47 +00:00
2022-03-12 10:35:05 +00:00
constexpr ImplIterator GetImplIterator() const {
return m_impl;
2020-12-31 07:31:47 +00:00
}
public:
2022-03-12 10:35:05 +00:00
constexpr bool operator==(const Iterator& rhs) const {
return m_impl == rhs.m_impl;
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr bool operator!=(const Iterator& rhs) const {
2020-12-31 07:31:47 +00:00
return !(*this == rhs);
}
2022-03-12 10:35:05 +00:00
constexpr pointer operator->() const {
return Traits::GetParent(std::addressof(*m_impl));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr reference operator*() const {
return *Traits::GetParent(std::addressof(*m_impl));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr Iterator& operator++() {
++m_impl;
2020-12-31 07:31:47 +00:00
return *this;
}
2022-03-12 10:35:05 +00:00
constexpr Iterator& operator--() {
--m_impl;
2020-12-31 07:31:47 +00:00
return *this;
}
2022-03-12 10:35:05 +00:00
constexpr Iterator operator++(int) {
2020-12-31 07:31:47 +00:00
const Iterator it{*this};
2022-03-12 10:35:05 +00:00
++m_impl;
2020-12-31 07:31:47 +00:00
return it;
}
2022-03-12 10:35:05 +00:00
constexpr Iterator operator--(int) {
2020-12-31 07:31:47 +00:00
const Iterator it{*this};
2022-03-12 10:35:05 +00:00
--m_impl;
2020-12-31 07:31:47 +00:00
return it;
}
2022-03-12 10:35:05 +00:00
constexpr operator Iterator<true>() const {
return Iterator<true>(m_impl);
2020-12-31 07:31:47 +00:00
}
};
private:
2022-03-12 10:35:05 +00:00
static constexpr int CompareImpl(const IntrusiveRedBlackTreeNode* lhs,
const IntrusiveRedBlackTreeNode* rhs) {
2020-12-31 07:31:47 +00:00
return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs));
}
2022-03-12 10:35:05 +00:00
static constexpr int CompareKeyImpl(const_key_reference key,
const IntrusiveRedBlackTreeNode* rhs) {
return Comparator::Compare(key, *Traits::GetParent(rhs));
2020-12-31 07:31:47 +00:00
}
2021-01-12 09:22:33 +00:00
// Define accessors using RB_* functions.
2022-03-12 10:35:05 +00:00
constexpr IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) {
return freebsd::RB_INSERT(m_impl.m_root, node, CompareImpl);
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr IntrusiveRedBlackTreeNode* FindImpl(IntrusiveRedBlackTreeNode const* node) const {
return freebsd::RB_FIND(const_cast<ImplType::RootType&>(m_impl.m_root),
const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr IntrusiveRedBlackTreeNode* NFindImpl(IntrusiveRedBlackTreeNode const* node) const {
return freebsd::RB_NFIND(const_cast<ImplType::RootType&>(m_impl.m_root),
const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr IntrusiveRedBlackTreeNode* FindKeyImpl(const_key_reference key) const {
return freebsd::RB_FIND_KEY(const_cast<ImplType::RootType&>(m_impl.m_root), key,
CompareKeyImpl);
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr IntrusiveRedBlackTreeNode* NFindKeyImpl(const_key_reference key) const {
return freebsd::RB_NFIND_KEY(const_cast<ImplType::RootType&>(m_impl.m_root), key,
CompareKeyImpl);
}
constexpr IntrusiveRedBlackTreeNode* FindExistingImpl(
IntrusiveRedBlackTreeNode const* node) const {
return freebsd::RB_FIND_EXISTING(const_cast<ImplType::RootType&>(m_impl.m_root),
const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
}
constexpr IntrusiveRedBlackTreeNode* FindExistingKeyImpl(const_key_reference key) const {
return freebsd::RB_FIND_EXISTING_KEY(const_cast<ImplType::RootType&>(m_impl.m_root), key,
CompareKeyImpl);
2020-12-31 07:31:47 +00:00
}
public:
2021-01-12 09:22:33 +00:00
constexpr IntrusiveRedBlackTree() = default;
2020-12-31 07:31:47 +00:00
2021-01-12 09:22:33 +00:00
// Iterator accessors.
2022-03-12 10:35:05 +00:00
constexpr iterator begin() {
return iterator(m_impl.begin());
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr const_iterator begin() const {
return const_iterator(m_impl.begin());
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr iterator end() {
return iterator(m_impl.end());
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr const_iterator end() const {
return const_iterator(m_impl.end());
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr const_iterator cbegin() const {
2020-12-31 07:31:47 +00:00
return this->begin();
}
2022-03-12 10:35:05 +00:00
constexpr const_iterator cend() const {
2020-12-31 07:31:47 +00:00
return this->end();
}
2022-03-12 10:35:05 +00:00
constexpr iterator iterator_to(reference ref) {
return iterator(m_impl.iterator_to(*Traits::GetNode(std::addressof(ref))));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr const_iterator iterator_to(const_reference ref) const {
return const_iterator(m_impl.iterator_to(*Traits::GetNode(std::addressof(ref))));
2020-12-31 07:31:47 +00:00
}
2021-01-12 09:22:33 +00:00
// Content management.
2022-03-12 10:35:05 +00:00
constexpr bool empty() const {
return m_impl.empty();
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr reference back() {
return *Traits::GetParent(std::addressof(m_impl.back()));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr const_reference back() const {
return *Traits::GetParent(std::addressof(m_impl.back()));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr reference front() {
return *Traits::GetParent(std::addressof(m_impl.front()));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr const_reference front() const {
return *Traits::GetParent(std::addressof(m_impl.front()));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr iterator erase(iterator it) {
return iterator(m_impl.erase(it.GetImplIterator()));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr iterator insert(reference ref) {
2020-12-31 07:31:47 +00:00
ImplType::pointer node = Traits::GetNode(std::addressof(ref));
this->InsertImpl(node);
return iterator(node);
}
2022-03-12 10:35:05 +00:00
constexpr iterator find(const_reference ref) const {
2020-12-31 07:31:47 +00:00
return iterator(this->FindImpl(Traits::GetNode(std::addressof(ref))));
}
2022-03-12 10:35:05 +00:00
constexpr iterator nfind(const_reference ref) const {
2020-12-31 07:31:47 +00:00
return iterator(this->NFindImpl(Traits::GetNode(std::addressof(ref))));
}
2022-03-12 10:35:05 +00:00
constexpr iterator find_key(const_key_reference ref) const {
return iterator(this->FindKeyImpl(ref));
}
constexpr iterator nfind_key(const_key_reference ref) const {
return iterator(this->NFindKeyImpl(ref));
}
constexpr iterator find_existing(const_reference ref) const {
return iterator(this->FindExistingImpl(Traits::GetNode(std::addressof(ref))));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
constexpr iterator find_existing_key(const_key_reference ref) const {
return iterator(this->FindExistingKeyImpl(ref));
2020-12-31 07:31:47 +00:00
}
};
2022-03-12 10:35:05 +00:00
template <auto T, class Derived = Common::impl::GetParentType<T>>
2020-12-31 07:31:47 +00:00
class IntrusiveRedBlackTreeMemberTraits;
template <class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived>
class IntrusiveRedBlackTreeMemberTraits<Member, Derived> {
public:
template <class Comparator>
using TreeType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraits, Comparator>;
using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl;
private:
template <class, class, class>
friend class IntrusiveRedBlackTree;
friend class impl::IntrusiveRedBlackTreeImpl;
static constexpr IntrusiveRedBlackTreeNode* GetNode(Derived* parent) {
return std::addressof(parent->*Member);
}
static constexpr IntrusiveRedBlackTreeNode const* GetNode(Derived const* parent) {
return std::addressof(parent->*Member);
}
2022-03-12 10:35:05 +00:00
static Derived* GetParent(IntrusiveRedBlackTreeNode* node) {
return Common::GetParentPointer<Member, Derived>(node);
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
static Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
return Common::GetParentPointer<Member, Derived>(node);
2020-12-31 07:31:47 +00:00
}
};
2022-03-12 10:35:05 +00:00
template <auto T, class Derived = Common::impl::GetParentType<T>>
2020-12-31 07:31:47 +00:00
class IntrusiveRedBlackTreeMemberTraitsDeferredAssert;
template <class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived>
class IntrusiveRedBlackTreeMemberTraitsDeferredAssert<Member, Derived> {
public:
template <class Comparator>
using TreeType =
IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraitsDeferredAssert, Comparator>;
using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl;
private:
template <class, class, class>
friend class IntrusiveRedBlackTree;
friend class impl::IntrusiveRedBlackTreeImpl;
static constexpr IntrusiveRedBlackTreeNode* GetNode(Derived* parent) {
return std::addressof(parent->*Member);
}
static constexpr IntrusiveRedBlackTreeNode const* GetNode(Derived const* parent) {
return std::addressof(parent->*Member);
}
2022-03-12 10:35:05 +00:00
static Derived* GetParent(IntrusiveRedBlackTreeNode* node) {
return Common::GetParentPointer<Member, Derived>(node);
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
static Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
return Common::GetParentPointer<Member, Derived>(node);
2020-12-31 07:31:47 +00:00
}
};
template <class Derived>
2022-03-12 10:35:05 +00:00
class alignas(void*) IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode {
2020-12-31 07:31:47 +00:00
public:
2022-03-12 10:35:05 +00:00
using IntrusiveRedBlackTreeNode::IntrusiveRedBlackTreeNode;
2020-12-31 07:31:47 +00:00
constexpr Derived* GetPrev() {
2022-03-12 10:35:05 +00:00
return static_cast<Derived*>(static_cast<IntrusiveRedBlackTreeBaseNode*>(
impl::IntrusiveRedBlackTreeImpl::GetPrev(this)));
2020-12-31 07:31:47 +00:00
}
constexpr const Derived* GetPrev() const {
2022-03-12 10:35:05 +00:00
return static_cast<const Derived*>(static_cast<const IntrusiveRedBlackTreeBaseNode*>(
impl::IntrusiveRedBlackTreeImpl::GetPrev(this)));
2020-12-31 07:31:47 +00:00
}
constexpr Derived* GetNext() {
2022-03-12 10:35:05 +00:00
return static_cast<Derived*>(static_cast<IntrusiveRedBlackTreeBaseNode*>(
impl::IntrusiveRedBlackTreeImpl::GetNext(this)));
2020-12-31 07:31:47 +00:00
}
constexpr const Derived* GetNext() const {
2022-03-12 10:35:05 +00:00
return static_cast<const Derived*>(static_cast<const IntrusiveRedBlackTreeBaseNode*>(
impl::IntrusiveRedBlackTreeImpl::GetNext(this)));
2020-12-31 07:31:47 +00:00
}
};
template <class Derived>
class IntrusiveRedBlackTreeBaseTraits {
public:
template <class Comparator>
using TreeType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeBaseTraits, Comparator>;
using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl;
private:
template <class, class, class>
friend class IntrusiveRedBlackTree;
friend class impl::IntrusiveRedBlackTreeImpl;
static constexpr IntrusiveRedBlackTreeNode* GetNode(Derived* parent) {
2022-03-12 10:35:05 +00:00
return static_cast<IntrusiveRedBlackTreeNode*>(
static_cast<IntrusiveRedBlackTreeBaseNode<Derived>*>(parent));
2020-12-31 07:31:47 +00:00
}
static constexpr IntrusiveRedBlackTreeNode const* GetNode(Derived const* parent) {
2022-03-12 10:35:05 +00:00
return static_cast<const IntrusiveRedBlackTreeNode*>(
static_cast<const IntrusiveRedBlackTreeBaseNode<Derived>*>(parent));
2020-12-31 07:31:47 +00:00
}
static constexpr Derived* GetParent(IntrusiveRedBlackTreeNode* node) {
2022-03-12 10:35:05 +00:00
return static_cast<Derived*>(static_cast<IntrusiveRedBlackTreeBaseNode<Derived>*>(node));
2020-12-31 07:31:47 +00:00
}
2022-03-12 10:35:05 +00:00
static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
return static_cast<const Derived*>(
static_cast<const IntrusiveRedBlackTreeBaseNode<Derived>*>(node));
2020-12-31 07:31:47 +00:00
}
};
} // namespace Common