common: intrusive_red_black_tree: Various updates.

This commit is contained in:
bunnei 2022-03-10 22:55:05 -08:00
parent cd07a43724
commit 69c2faeb6a

View file

@ -4,6 +4,8 @@
#pragma once #pragma once
#include "common/alignment.h"
#include "common/common_funcs.h"
#include "common/parent_of_member.h" #include "common/parent_of_member.h"
#include "common/tree.h" #include "common/tree.h"
@ -15,32 +17,33 @@ class IntrusiveRedBlackTreeImpl;
} }
#pragma pack(push, 4)
struct IntrusiveRedBlackTreeNode { struct IntrusiveRedBlackTreeNode {
YUZU_NON_COPYABLE(IntrusiveRedBlackTreeNode);
public: public:
using EntryType = RBEntry<IntrusiveRedBlackTreeNode>; using RBEntry = freebsd::RBEntry<IntrusiveRedBlackTreeNode>;
constexpr IntrusiveRedBlackTreeNode() = default;
void SetEntry(const EntryType& new_entry) {
entry = new_entry;
}
[[nodiscard]] EntryType& GetEntry() {
return entry;
}
[[nodiscard]] const EntryType& GetEntry() const {
return entry;
}
private: private:
EntryType entry{}; RBEntry m_entry;
friend class impl::IntrusiveRedBlackTreeImpl; public:
explicit IntrusiveRedBlackTreeNode() = default;
template <class, class, class> [[nodiscard]] constexpr RBEntry& GetRBEntry() {
friend class IntrusiveRedBlackTree; return m_entry;
}
[[nodiscard]] constexpr const RBEntry& GetRBEntry() const {
return m_entry;
}
constexpr void SetRBEntry(const RBEntry& entry) {
m_entry = entry;
}
}; };
static_assert(sizeof(IntrusiveRedBlackTreeNode) ==
3 * sizeof(void*) + std::max<size_t>(sizeof(freebsd::RBColor), 4));
#pragma pack(pop)
template <class T, class Traits, class Comparator> template <class T, class Traits, class Comparator>
class IntrusiveRedBlackTree; class IntrusiveRedBlackTree;
@ -48,12 +51,17 @@ class IntrusiveRedBlackTree;
namespace impl { namespace impl {
class IntrusiveRedBlackTreeImpl { class IntrusiveRedBlackTreeImpl {
YUZU_NON_COPYABLE(IntrusiveRedBlackTreeImpl);
private: private:
template <class, class, class> template <class, class, class>
friend class ::Common::IntrusiveRedBlackTree; friend class ::Common::IntrusiveRedBlackTree;
using RootType = RBHead<IntrusiveRedBlackTreeNode>; private:
RootType root; using RootType = freebsd::RBHead<IntrusiveRedBlackTreeNode>;
private:
RootType m_root;
public: public:
template <bool Const> template <bool Const>
@ -81,149 +89,150 @@ public:
IntrusiveRedBlackTreeImpl::reference>; IntrusiveRedBlackTreeImpl::reference>;
private: private:
pointer node; pointer m_node;
public: public:
explicit Iterator(pointer n) : node(n) {} constexpr explicit Iterator(pointer n) : m_node(n) {}
bool operator==(const Iterator& rhs) const { constexpr bool operator==(const Iterator& rhs) const {
return this->node == rhs.node; return m_node == rhs.m_node;
} }
bool operator!=(const Iterator& rhs) const { constexpr bool operator!=(const Iterator& rhs) const {
return !(*this == rhs); return !(*this == rhs);
} }
pointer operator->() const { constexpr pointer operator->() const {
return this->node; return m_node;
} }
reference operator*() const { constexpr reference operator*() const {
return *this->node; return *m_node;
} }
Iterator& operator++() { constexpr Iterator& operator++() {
this->node = GetNext(this->node); m_node = GetNext(m_node);
return *this; return *this;
} }
Iterator& operator--() { constexpr Iterator& operator--() {
this->node = GetPrev(this->node); m_node = GetPrev(m_node);
return *this; return *this;
} }
Iterator operator++(int) { constexpr Iterator operator++(int) {
const Iterator it{*this}; const Iterator it{*this};
++(*this); ++(*this);
return it; return it;
} }
Iterator operator--(int) { constexpr Iterator operator--(int) {
const Iterator it{*this}; const Iterator it{*this};
--(*this); --(*this);
return it; return it;
} }
operator Iterator<true>() const { constexpr operator Iterator<true>() const {
return Iterator<true>(this->node); return Iterator<true>(m_node);
} }
}; };
private: private:
// Define accessors using RB_* functions. constexpr bool EmptyImpl() const {
bool EmptyImpl() const { return m_root.IsEmpty();
return root.IsEmpty();
} }
IntrusiveRedBlackTreeNode* GetMinImpl() const { constexpr IntrusiveRedBlackTreeNode* GetMinImpl() const {
return RB_MIN(const_cast<RootType*>(&root)); return freebsd::RB_MIN(const_cast<RootType&>(m_root));
} }
IntrusiveRedBlackTreeNode* GetMaxImpl() const { constexpr IntrusiveRedBlackTreeNode* GetMaxImpl() const {
return RB_MAX(const_cast<RootType*>(&root)); return freebsd::RB_MAX(const_cast<RootType&>(m_root));
} }
IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) { constexpr IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) {
return RB_REMOVE(&root, node); return freebsd::RB_REMOVE(m_root, node);
} }
public: public:
static IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) { static constexpr IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) {
return RB_NEXT(node); return freebsd::RB_NEXT(node);
} }
static IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) { static constexpr IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) {
return RB_PREV(node); return freebsd::RB_PREV(node);
} }
static const IntrusiveRedBlackTreeNode* GetNext(const IntrusiveRedBlackTreeNode* node) { static constexpr IntrusiveRedBlackTreeNode const* GetNext(
IntrusiveRedBlackTreeNode const* node) {
return static_cast<const IntrusiveRedBlackTreeNode*>( return static_cast<const IntrusiveRedBlackTreeNode*>(
GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node))); GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node)));
} }
static const IntrusiveRedBlackTreeNode* GetPrev(const IntrusiveRedBlackTreeNode* node) { static constexpr IntrusiveRedBlackTreeNode const* GetPrev(
IntrusiveRedBlackTreeNode const* node) {
return static_cast<const IntrusiveRedBlackTreeNode*>( return static_cast<const IntrusiveRedBlackTreeNode*>(
GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node))); GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node)));
} }
public: public:
constexpr IntrusiveRedBlackTreeImpl() {} constexpr IntrusiveRedBlackTreeImpl() = default;
// Iterator accessors. // Iterator accessors.
iterator begin() { constexpr iterator begin() {
return iterator(this->GetMinImpl()); return iterator(this->GetMinImpl());
} }
const_iterator begin() const { constexpr const_iterator begin() const {
return const_iterator(this->GetMinImpl()); return const_iterator(this->GetMinImpl());
} }
iterator end() { constexpr iterator end() {
return iterator(static_cast<IntrusiveRedBlackTreeNode*>(nullptr)); return iterator(static_cast<IntrusiveRedBlackTreeNode*>(nullptr));
} }
const_iterator end() const { constexpr const_iterator end() const {
return const_iterator(static_cast<const IntrusiveRedBlackTreeNode*>(nullptr)); return const_iterator(static_cast<const IntrusiveRedBlackTreeNode*>(nullptr));
} }
const_iterator cbegin() const { constexpr const_iterator cbegin() const {
return this->begin(); return this->begin();
} }
const_iterator cend() const { constexpr const_iterator cend() const {
return this->end(); return this->end();
} }
iterator iterator_to(reference ref) { constexpr iterator iterator_to(reference ref) {
return iterator(&ref); return iterator(std::addressof(ref));
} }
const_iterator iterator_to(const_reference ref) const { constexpr const_iterator iterator_to(const_reference ref) const {
return const_iterator(&ref); return const_iterator(std::addressof(ref));
} }
// Content management. // Content management.
bool empty() const { constexpr bool empty() const {
return this->EmptyImpl(); return this->EmptyImpl();
} }
reference back() { constexpr reference back() {
return *this->GetMaxImpl(); return *this->GetMaxImpl();
} }
const_reference back() const { constexpr const_reference back() const {
return *this->GetMaxImpl(); return *this->GetMaxImpl();
} }
reference front() { constexpr reference front() {
return *this->GetMinImpl(); return *this->GetMinImpl();
} }
const_reference front() const { constexpr const_reference front() const {
return *this->GetMinImpl(); return *this->GetMinImpl();
} }
iterator erase(iterator it) { constexpr iterator erase(iterator it) {
auto cur = std::addressof(*it); auto cur = std::addressof(*it);
auto next = GetNext(cur); auto next = GetNext(cur);
this->RemoveImpl(cur); this->RemoveImpl(cur);
@ -234,16 +243,16 @@ public:
} // namespace impl } // namespace impl
template <typename T> template <typename T>
concept HasLightCompareType = requires { concept HasRedBlackKeyType = requires {
{ std::is_same<typename T::LightCompareType, void>::value } -> std::convertible_to<bool>; { std::is_same<typename T::RedBlackKeyType, void>::value } -> std::convertible_to<bool>;
}; };
namespace impl { namespace impl {
template <typename T, typename Default> template <typename T, typename Default>
consteval auto* GetLightCompareType() { consteval auto* GetRedBlackKeyType() {
if constexpr (HasLightCompareType<T>) { if constexpr (HasRedBlackKeyType<T>) {
return static_cast<typename T::LightCompareType*>(nullptr); return static_cast<typename T::RedBlackKeyType*>(nullptr);
} else { } else {
return static_cast<Default*>(nullptr); return static_cast<Default*>(nullptr);
} }
@ -252,16 +261,17 @@ namespace impl {
} // namespace impl } // namespace impl
template <typename T, typename Default> template <typename T, typename Default>
using LightCompareType = std::remove_pointer_t<decltype(impl::GetLightCompareType<T, Default>())>; using RedBlackKeyType = std::remove_pointer_t<decltype(impl::GetRedBlackKeyType<T, Default>())>;
template <class T, class Traits, class Comparator> template <class T, class Traits, class Comparator>
class IntrusiveRedBlackTree { class IntrusiveRedBlackTree {
YUZU_NON_COPYABLE(IntrusiveRedBlackTree);
public: public:
using ImplType = impl::IntrusiveRedBlackTreeImpl; using ImplType = impl::IntrusiveRedBlackTreeImpl;
private: private:
ImplType impl{}; ImplType m_impl;
public: public:
template <bool Const> template <bool Const>
@ -277,9 +287,9 @@ public:
using iterator = Iterator<false>; using iterator = Iterator<false>;
using const_iterator = Iterator<true>; using const_iterator = Iterator<true>;
using light_value_type = LightCompareType<Comparator, value_type>; using key_type = RedBlackKeyType<Comparator, value_type>;
using const_light_pointer = const light_value_type*; using const_key_pointer = const key_type*;
using const_light_reference = const light_value_type&; using const_key_reference = const key_type&;
template <bool Const> template <bool Const>
class Iterator { class Iterator {
@ -298,183 +308,201 @@ public:
IntrusiveRedBlackTree::reference>; IntrusiveRedBlackTree::reference>;
private: private:
ImplIterator iterator; ImplIterator m_impl;
private: private:
explicit Iterator(ImplIterator it) : iterator(it) {} constexpr explicit Iterator(ImplIterator it) : m_impl(it) {}
explicit Iterator(typename std::conditional<Const, ImplType::const_iterator, constexpr explicit Iterator(typename ImplIterator::pointer p) : m_impl(p) {}
ImplType::iterator>::type::pointer ptr)
: iterator(ptr) {}
ImplIterator GetImplIterator() const { constexpr ImplIterator GetImplIterator() const {
return this->iterator; return m_impl;
} }
public: public:
bool operator==(const Iterator& rhs) const { constexpr bool operator==(const Iterator& rhs) const {
return this->iterator == rhs.iterator; return m_impl == rhs.m_impl;
} }
bool operator!=(const Iterator& rhs) const { constexpr bool operator!=(const Iterator& rhs) const {
return !(*this == rhs); return !(*this == rhs);
} }
pointer operator->() const { constexpr pointer operator->() const {
return Traits::GetParent(std::addressof(*this->iterator)); return Traits::GetParent(std::addressof(*m_impl));
} }
reference operator*() const { constexpr reference operator*() const {
return *Traits::GetParent(std::addressof(*this->iterator)); return *Traits::GetParent(std::addressof(*m_impl));
} }
Iterator& operator++() { constexpr Iterator& operator++() {
++this->iterator; ++m_impl;
return *this; return *this;
} }
Iterator& operator--() { constexpr Iterator& operator--() {
--this->iterator; --m_impl;
return *this; return *this;
} }
Iterator operator++(int) { constexpr Iterator operator++(int) {
const Iterator it{*this}; const Iterator it{*this};
++this->iterator; ++m_impl;
return it; return it;
} }
Iterator operator--(int) { constexpr Iterator operator--(int) {
const Iterator it{*this}; const Iterator it{*this};
--this->iterator; --m_impl;
return it; return it;
} }
operator Iterator<true>() const { constexpr operator Iterator<true>() const {
return Iterator<true>(this->iterator); return Iterator<true>(m_impl);
} }
}; };
private: private:
static int CompareImpl(const IntrusiveRedBlackTreeNode* lhs, static constexpr int CompareImpl(const IntrusiveRedBlackTreeNode* lhs,
const IntrusiveRedBlackTreeNode* rhs) { const IntrusiveRedBlackTreeNode* rhs) {
return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs)); return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs));
} }
static int LightCompareImpl(const void* elm, const IntrusiveRedBlackTreeNode* rhs) { static constexpr int CompareKeyImpl(const_key_reference key,
return Comparator::Compare(*static_cast<const_light_pointer>(elm), *Traits::GetParent(rhs)); const IntrusiveRedBlackTreeNode* rhs) {
return Comparator::Compare(key, *Traits::GetParent(rhs));
} }
// Define accessors using RB_* functions. // Define accessors using RB_* functions.
IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) { constexpr IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) {
return RB_INSERT(&impl.root, node, CompareImpl); return freebsd::RB_INSERT(m_impl.m_root, node, CompareImpl);
} }
IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const { constexpr IntrusiveRedBlackTreeNode* FindImpl(IntrusiveRedBlackTreeNode const* node) const {
return RB_FIND(const_cast<ImplType::RootType*>(&impl.root), return freebsd::RB_FIND(const_cast<ImplType::RootType&>(m_impl.m_root),
const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl); const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
} }
IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const { constexpr IntrusiveRedBlackTreeNode* NFindImpl(IntrusiveRedBlackTreeNode const* node) const {
return RB_NFIND(const_cast<ImplType::RootType*>(&impl.root), return freebsd::RB_NFIND(const_cast<ImplType::RootType&>(m_impl.m_root),
const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl); const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
} }
IntrusiveRedBlackTreeNode* FindLightImpl(const_light_pointer lelm) const { constexpr IntrusiveRedBlackTreeNode* FindKeyImpl(const_key_reference key) const {
return RB_FIND_LIGHT(const_cast<ImplType::RootType*>(&impl.root), return freebsd::RB_FIND_KEY(const_cast<ImplType::RootType&>(m_impl.m_root), key,
static_cast<const void*>(lelm), LightCompareImpl); CompareKeyImpl);
} }
IntrusiveRedBlackTreeNode* NFindLightImpl(const_light_pointer lelm) const { constexpr IntrusiveRedBlackTreeNode* NFindKeyImpl(const_key_reference key) const {
return RB_NFIND_LIGHT(const_cast<ImplType::RootType*>(&impl.root), return freebsd::RB_NFIND_KEY(const_cast<ImplType::RootType&>(m_impl.m_root), key,
static_cast<const void*>(lelm), LightCompareImpl); 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);
} }
public: public:
constexpr IntrusiveRedBlackTree() = default; constexpr IntrusiveRedBlackTree() = default;
// Iterator accessors. // Iterator accessors.
iterator begin() { constexpr iterator begin() {
return iterator(this->impl.begin()); return iterator(m_impl.begin());
} }
const_iterator begin() const { constexpr const_iterator begin() const {
return const_iterator(this->impl.begin()); return const_iterator(m_impl.begin());
} }
iterator end() { constexpr iterator end() {
return iterator(this->impl.end()); return iterator(m_impl.end());
} }
const_iterator end() const { constexpr const_iterator end() const {
return const_iterator(this->impl.end()); return const_iterator(m_impl.end());
} }
const_iterator cbegin() const { constexpr const_iterator cbegin() const {
return this->begin(); return this->begin();
} }
const_iterator cend() const { constexpr const_iterator cend() const {
return this->end(); return this->end();
} }
iterator iterator_to(reference ref) { constexpr iterator iterator_to(reference ref) {
return iterator(this->impl.iterator_to(*Traits::GetNode(std::addressof(ref)))); return iterator(m_impl.iterator_to(*Traits::GetNode(std::addressof(ref))));
} }
const_iterator iterator_to(const_reference ref) const { constexpr const_iterator iterator_to(const_reference ref) const {
return const_iterator(this->impl.iterator_to(*Traits::GetNode(std::addressof(ref)))); return const_iterator(m_impl.iterator_to(*Traits::GetNode(std::addressof(ref))));
} }
// Content management. // Content management.
bool empty() const { constexpr bool empty() const {
return this->impl.empty(); return m_impl.empty();
} }
reference back() { constexpr reference back() {
return *Traits::GetParent(std::addressof(this->impl.back())); return *Traits::GetParent(std::addressof(m_impl.back()));
} }
const_reference back() const { constexpr const_reference back() const {
return *Traits::GetParent(std::addressof(this->impl.back())); return *Traits::GetParent(std::addressof(m_impl.back()));
} }
reference front() { constexpr reference front() {
return *Traits::GetParent(std::addressof(this->impl.front())); return *Traits::GetParent(std::addressof(m_impl.front()));
} }
const_reference front() const { constexpr const_reference front() const {
return *Traits::GetParent(std::addressof(this->impl.front())); return *Traits::GetParent(std::addressof(m_impl.front()));
} }
iterator erase(iterator it) { constexpr iterator erase(iterator it) {
return iterator(this->impl.erase(it.GetImplIterator())); return iterator(m_impl.erase(it.GetImplIterator()));
} }
iterator insert(reference ref) { constexpr iterator insert(reference ref) {
ImplType::pointer node = Traits::GetNode(std::addressof(ref)); ImplType::pointer node = Traits::GetNode(std::addressof(ref));
this->InsertImpl(node); this->InsertImpl(node);
return iterator(node); return iterator(node);
} }
iterator find(const_reference ref) const { constexpr iterator find(const_reference ref) const {
return iterator(this->FindImpl(Traits::GetNode(std::addressof(ref)))); return iterator(this->FindImpl(Traits::GetNode(std::addressof(ref))));
} }
iterator nfind(const_reference ref) const { constexpr iterator nfind(const_reference ref) const {
return iterator(this->NFindImpl(Traits::GetNode(std::addressof(ref)))); return iterator(this->NFindImpl(Traits::GetNode(std::addressof(ref))));
} }
iterator find_light(const_light_reference ref) const { constexpr iterator find_key(const_key_reference ref) const {
return iterator(this->FindLightImpl(std::addressof(ref))); return iterator(this->FindKeyImpl(ref));
} }
iterator nfind_light(const_light_reference ref) const { constexpr iterator nfind_key(const_key_reference ref) const {
return iterator(this->NFindLightImpl(std::addressof(ref))); return iterator(this->NFindKeyImpl(ref));
}
constexpr iterator find_existing(const_reference ref) const {
return iterator(this->FindExistingImpl(Traits::GetNode(std::addressof(ref))));
}
constexpr iterator find_existing_key(const_key_reference ref) const {
return iterator(this->FindExistingKeyImpl(ref));
} }
}; };
template <auto T, class Derived = impl::GetParentType<T>> template <auto T, class Derived = Common::impl::GetParentType<T>>
class IntrusiveRedBlackTreeMemberTraits; class IntrusiveRedBlackTreeMemberTraits;
template <class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived> template <class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived>
@ -498,19 +526,16 @@ private:
return std::addressof(parent->*Member); return std::addressof(parent->*Member);
} }
static constexpr Derived* GetParent(IntrusiveRedBlackTreeNode* node) { static Derived* GetParent(IntrusiveRedBlackTreeNode* node) {
return GetParentPointer<Member, Derived>(node); return Common::GetParentPointer<Member, Derived>(node);
} }
static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { static Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
return GetParentPointer<Member, Derived>(node); return Common::GetParentPointer<Member, Derived>(node);
} }
private:
static constexpr TypedStorage<Derived> DerivedStorage = {};
}; };
template <auto T, class Derived = impl::GetParentType<T>> template <auto T, class Derived = Common::impl::GetParentType<T>>
class IntrusiveRedBlackTreeMemberTraitsDeferredAssert; class IntrusiveRedBlackTreeMemberTraitsDeferredAssert;
template <class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived> template <class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived>
@ -521,11 +546,6 @@ public:
IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraitsDeferredAssert, Comparator>; IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraitsDeferredAssert, Comparator>;
using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl; using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl;
static constexpr bool IsValid() {
TypedStorage<Derived> DerivedStorage = {};
return GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage);
}
private: private:
template <class, class, class> template <class, class, class>
friend class IntrusiveRedBlackTree; friend class IntrusiveRedBlackTree;
@ -540,30 +560,36 @@ private:
return std::addressof(parent->*Member); return std::addressof(parent->*Member);
} }
static constexpr Derived* GetParent(IntrusiveRedBlackTreeNode* node) { static Derived* GetParent(IntrusiveRedBlackTreeNode* node) {
return GetParentPointer<Member, Derived>(node); return Common::GetParentPointer<Member, Derived>(node);
} }
static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { static Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
return GetParentPointer<Member, Derived>(node); return Common::GetParentPointer<Member, Derived>(node);
} }
}; };
template <class Derived> template <class Derived>
class IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode { class alignas(void*) IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode {
public: public:
using IntrusiveRedBlackTreeNode::IntrusiveRedBlackTreeNode;
constexpr Derived* GetPrev() { constexpr Derived* GetPrev() {
return static_cast<Derived*>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this)); return static_cast<Derived*>(static_cast<IntrusiveRedBlackTreeBaseNode*>(
impl::IntrusiveRedBlackTreeImpl::GetPrev(this)));
} }
constexpr const Derived* GetPrev() const { constexpr const Derived* GetPrev() const {
return static_cast<const Derived*>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this)); return static_cast<const Derived*>(static_cast<const IntrusiveRedBlackTreeBaseNode*>(
impl::IntrusiveRedBlackTreeImpl::GetPrev(this)));
} }
constexpr Derived* GetNext() { constexpr Derived* GetNext() {
return static_cast<Derived*>(impl::IntrusiveRedBlackTreeImpl::GetNext(this)); return static_cast<Derived*>(static_cast<IntrusiveRedBlackTreeBaseNode*>(
impl::IntrusiveRedBlackTreeImpl::GetNext(this)));
} }
constexpr const Derived* GetNext() const { constexpr const Derived* GetNext() const {
return static_cast<const Derived*>(impl::IntrusiveRedBlackTreeImpl::GetNext(this)); return static_cast<const Derived*>(static_cast<const IntrusiveRedBlackTreeBaseNode*>(
impl::IntrusiveRedBlackTreeImpl::GetNext(this)));
} }
}; };
@ -581,19 +607,22 @@ private:
friend class impl::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*>(
static_cast<IntrusiveRedBlackTreeBaseNode<Derived>*>(parent));
} }
static constexpr IntrusiveRedBlackTreeNode const* GetNode(Derived const* parent) { static constexpr IntrusiveRedBlackTreeNode const* GetNode(Derived const* parent) {
return static_cast<const IntrusiveRedBlackTreeNode*>(parent); return static_cast<const IntrusiveRedBlackTreeNode*>(
static_cast<const IntrusiveRedBlackTreeBaseNode<Derived>*>(parent));
} }
static constexpr Derived* GetParent(IntrusiveRedBlackTreeNode* node) { static constexpr Derived* GetParent(IntrusiveRedBlackTreeNode* node) {
return static_cast<Derived*>(node); return static_cast<Derived*>(static_cast<IntrusiveRedBlackTreeBaseNode<Derived>*>(node));
} }
static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
return static_cast<const Derived*>(node); return static_cast<const Derived*>(
static_cast<const IntrusiveRedBlackTreeBaseNode<Derived>*>(node));
} }
}; };