common/tree: Convert defines over to templates

Reworks the tree header to operate off of templates as opposed to a
series of defines.

This allows all tree facilities to obey namespacing rules, and also
allows this code to be used within modules once compiler support is in
place.

This also gets rid to use a macro to define functions and structs for
necessary data types. With templates, these will be generated when
they're actually used, eliminating the need for the separate
declaration.
This commit is contained in:
Lioncash 2021-01-12 02:47:36 -05:00
parent 197b5d19bc
commit b15e1a3501
2 changed files with 633 additions and 559 deletions

View file

@ -16,17 +16,30 @@ class IntrusiveRedBlackTreeImpl;
} }
struct IntrusiveRedBlackTreeNode { struct IntrusiveRedBlackTreeNode {
public:
using EntryType = 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:
RB_ENTRY(IntrusiveRedBlackTreeNode) entry{}; EntryType entry{};
friend class impl::IntrusiveRedBlackTreeImpl; friend class impl::IntrusiveRedBlackTreeImpl;
template <class, class, class> template <class, class, class>
friend class IntrusiveRedBlackTree; friend class IntrusiveRedBlackTree;
public:
constexpr IntrusiveRedBlackTreeNode() = default;
}; };
template <class T, class Traits, class Comparator> template <class T, class Traits, class Comparator>
@ -35,17 +48,12 @@ class IntrusiveRedBlackTree;
namespace impl { namespace impl {
class IntrusiveRedBlackTreeImpl { class IntrusiveRedBlackTreeImpl {
private: private:
template <class, class, class> template <class, class, class>
friend class ::Common::IntrusiveRedBlackTree; friend class ::Common::IntrusiveRedBlackTree;
private: using RootType = RBHead<IntrusiveRedBlackTreeNode>;
RB_HEAD(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode); RootType root;
using RootType = IntrusiveRedBlackTreeRoot;
private:
IntrusiveRedBlackTreeRoot root;
public: public:
template <bool Const> template <bool Const>
@ -121,57 +129,45 @@ public:
} }
}; };
protected:
// Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot.
RB_GENERATE_WITHOUT_COMPARE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry);
private: private:
// Define accessors using RB_* functions. // Define accessors using RB_* functions.
constexpr void InitializeImpl() {
RB_INIT(&this->root);
}
bool EmptyImpl() const { bool EmptyImpl() const {
return RB_EMPTY(&this->root); return root.IsEmpty();
} }
IntrusiveRedBlackTreeNode* GetMinImpl() const { IntrusiveRedBlackTreeNode* GetMinImpl() const {
return RB_MIN(IntrusiveRedBlackTreeRoot, return RB_MIN(const_cast<RootType*>(&root));
const_cast<IntrusiveRedBlackTreeRoot*>(&this->root));
} }
IntrusiveRedBlackTreeNode* GetMaxImpl() const { IntrusiveRedBlackTreeNode* GetMaxImpl() const {
return RB_MAX(IntrusiveRedBlackTreeRoot, return RB_MAX(const_cast<RootType*>(&root));
const_cast<IntrusiveRedBlackTreeRoot*>(&this->root));
} }
IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) { IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) {
return RB_REMOVE(IntrusiveRedBlackTreeRoot, &this->root, node); return RB_REMOVE(&root, node);
} }
public: public:
static IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) { static IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) {
return RB_NEXT(IntrusiveRedBlackTreeRoot, nullptr, node); return RB_NEXT(node);
} }
static IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) { static IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) {
return RB_PREV(IntrusiveRedBlackTreeRoot, nullptr, node); return RB_PREV(node);
} }
static IntrusiveRedBlackTreeNode const* GetNext(const IntrusiveRedBlackTreeNode* node) { static const IntrusiveRedBlackTreeNode* GetNext(const IntrusiveRedBlackTreeNode* node) {
return static_cast<const IntrusiveRedBlackTreeNode*>( return static_cast<const IntrusiveRedBlackTreeNode*>(
GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node))); GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node)));
} }
static IntrusiveRedBlackTreeNode const* GetPrev(const IntrusiveRedBlackTreeNode* node) { static const IntrusiveRedBlackTreeNode* GetPrev(const IntrusiveRedBlackTreeNode* 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() : root() { constexpr IntrusiveRedBlackTreeImpl() {}
this->InitializeImpl();
}
// Iterator accessors. // Iterator accessors.
iterator begin() { iterator begin() {
@ -269,8 +265,6 @@ private:
ImplType impl{}; ImplType impl{};
public: public:
struct IntrusiveRedBlackTreeRootWithCompare : ImplType::IntrusiveRedBlackTreeRoot {};
template <bool Const> template <bool Const>
class Iterator; class Iterator;
@ -362,11 +356,6 @@ public:
} }
}; };
private:
// Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot.
RB_GENERATE_WITH_COMPARE_STATIC(IntrusiveRedBlackTreeRootWithCompare, IntrusiveRedBlackTreeNode,
entry, CompareImpl, LightCompareImpl);
private: private:
static int CompareImpl(const IntrusiveRedBlackTreeNode* lhs, static int CompareImpl(const IntrusiveRedBlackTreeNode* lhs,
const IntrusiveRedBlackTreeNode* rhs) { const IntrusiveRedBlackTreeNode* rhs) {
@ -379,41 +368,27 @@ private:
// Define accessors using RB_* functions. // Define accessors using RB_* functions.
IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) { IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) {
return RB_INSERT(IntrusiveRedBlackTreeRootWithCompare, return RB_INSERT(&impl.root, node, CompareImpl);
static_cast<IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root),
node);
} }
IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const { IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const {
return RB_FIND( return RB_FIND(const_cast<ImplType::RootType*>(&impl.root),
IntrusiveRedBlackTreeRootWithCompare, const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
const_cast<IntrusiveRedBlackTreeRootWithCompare*>(
static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)),
const_cast<IntrusiveRedBlackTreeNode*>(node));
} }
IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const { IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const {
return RB_NFIND( return RB_NFIND(const_cast<ImplType::RootType*>(&impl.root),
IntrusiveRedBlackTreeRootWithCompare, const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
const_cast<IntrusiveRedBlackTreeRootWithCompare*>(
static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)),
const_cast<IntrusiveRedBlackTreeNode*>(node));
} }
IntrusiveRedBlackTreeNode* FindLightImpl(const_light_pointer lelm) const { IntrusiveRedBlackTreeNode* FindLightImpl(const_light_pointer lelm) const {
return RB_FIND_LIGHT( return RB_FIND_LIGHT(const_cast<ImplType::RootType*>(&impl.root),
IntrusiveRedBlackTreeRootWithCompare, static_cast<const void*>(lelm), LightCompareImpl);
const_cast<IntrusiveRedBlackTreeRootWithCompare*>(
static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)),
static_cast<const void*>(lelm));
} }
IntrusiveRedBlackTreeNode* NFindLightImpl(const_light_pointer lelm) const { IntrusiveRedBlackTreeNode* NFindLightImpl(const_light_pointer lelm) const {
return RB_NFIND_LIGHT( return RB_NFIND_LIGHT(const_cast<ImplType::RootType*>(&impl.root),
IntrusiveRedBlackTreeRootWithCompare, static_cast<const void*>(lelm), LightCompareImpl);
const_cast<IntrusiveRedBlackTreeRootWithCompare*>(
static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)),
static_cast<const void*>(lelm));
} }
public: public:

File diff suppressed because it is too large Load diff