#pragma once #include #include #include namespace renderive { template class Node { public: explicit Node() = default; int index() { if (!father) return -1; auto found = std::find(father->sons.begin(), father->sons.end(), static_cast(this)); return found == father->sons.end() ? -1 : static_cast(std::distance(father->sons.begin(), found)); } bool root() { return !father; } bool leaf() { return sons.empty(); } bool first() { if (!father) return false; return this == father->sons.front(); } bool last() { if (!father) return false; return this == father->sons.back(); } That* previous() { if (!father) return nullptr; int i = index() - 1; if (i < 0) return nullptr; return father->sons[i]; } That* next() { if (!father) return nullptr; int i = index() + 1; if (i < 0 || i >= static_cast(father->sons.size())) return nullptr; return father->sons[i]; } That* last_child() { if (sons.empty()) return nullptr; return sons.back(); } That* first_child() { if (sons.empty()) return nullptr; return sons.front(); } That* root_node() { That* ret = static_cast(this); while (ret->father != nullptr) { ret = ret->father; } return ret; } int deep() { int result = 0; That* current = static_cast(this); while (current->father != nullptr) { current = current->father; ++result; } return result; } // 遍历值 std::vector deep_traversed() { std::vector ret; ret.push_back(static_cast(this)); for (auto& child : sons) { std::vector descendants = child->deep_traversed(); ret.insert(ret.end(), descendants.begin(), descendants.end()); } return ret; } std::vector sequence_traversed() { std::vector ret; std::queue que; That* that = static_cast(this); que.push(that); while (!que.empty()) { That* cur = que.front(); que.pop(); int n = static_cast(cur->sons.size()); ret.push_back(cur); for (int i = 0; i < n; ++i) { que.push(cur->sons[i]); } } return ret; } std::vector descendants() { std::vector&& ret = sequence_traversed(); ret.erase(ret.begin()); return ret; } That* father = nullptr; std::vector sons; }; template class Node_Manager { public: std::vector roots; }; } // namespace renderive