#ifndef SEAD_TREENODE_H_ #define SEAD_TREENODE_H_ #include namespace sead { class TreeNode { public: TreeNode(); void clearLinks(); s32 countChildren() const; void detachAll(); void detachSubTree(); TreeNode* findRoot(); const TreeNode* findRoot() const; void insertAfterSelf(TreeNode* node); void insertBeforeSelf(TreeNode* node); void pushBackChild(TreeNode* node); void pushBackSibling(TreeNode* node); void pushFrontChild(TreeNode* node); protected: void clearChildLinksRecursively_(); TreeNode* mParent; TreeNode* mChild; TreeNode* mNext; TreeNode* mPrev; }; template class TTreeNode : public TreeNode { public: TTreeNode() = default; explicit TTreeNode(T data) : mData(data) {} T& value() { return mData; } const T& value() const { return mData; } TTreeNode* parent() const { return static_cast(mParent); } TTreeNode* child() const { return static_cast(mChild); } TTreeNode* next() const { return static_cast(mNext); } TTreeNode* prev() const { return static_cast(mPrev); } TTreeNode* findRoot() { return static_cast(TreeNode::findRoot()); } const TTreeNode* findRoot() const { return static_cast(TreeNode::findRoot()); } void insertAfterSelf(TTreeNode* node) { TreeNode::insertAfterSelf(node); } void insertBeforeSelf(TTreeNode* node) { TreeNode::insertBeforeSelf(node); } void pushBackChild(TTreeNode* node) { TreeNode::pushBackChild(node); } void pushBackSibling(TTreeNode* node) { TreeNode::pushBackSibling(node); } void pushFrontChild(TTreeNode* node) { TreeNode::pushFrontChild(node); } // TODO: probably iterators protected: T mData; }; } // namespace sead #endif // SEAD_TREENODE_H_