diff --git a/vxorg.cpp b/vxorg.cpp new file mode 100644 index 0000000..ae3dfc2 --- /dev/null +++ b/vxorg.cpp @@ -0,0 +1,134 @@ +#include +#include +#include + +#include + +/// Port of tree.py to C++ +template +struct Tree { + + // FIXME make T not require default constructability + struct Node { + protected: + friend Tree; + Node* parent = nullptr; + std::vector children{}; + T item{}; + public: + ~Node() { + for(auto& child: children) + delete child; + } + + T& data() { + return item; + } + + const T& data() const { + return item; + } + + bool is_leaf() const { + return children.size() == 0; + } + + Node* create_leaf(const T& item) { + auto* node = new Node; + node->parent = this; + node->item = item; + children.push_back(node); + return node; + } + + template + void walk(Fn&& fn) { + fn(this); + if(!is_leaf()) { + for(auto& child: children) + child->walk(fn); + } + } + + template + std::optional find_child(Pred&& predicate) { + if(predicate(*this)) + return this; + + for(auto& child: children) + if(predicate(*child)) + return child; + + return std::nullopt; + } + + std::size_t parent_count() const { + auto* parent = this->parent; + auto parent_count = 0z; + while(parent) { + parent_count ++; + parent = parent->parent; + } + return parent_count; + } + + }; + + Tree() { + root = new Node; + } + + ~Tree() { + delete root; + } + + // Trees are not copyable but they can move + Tree(const Tree&) = delete; + Tree(Tree&&) = default; + + template + void walk(Fn&& fn) { + root->walk(fn); + } + + + Node* create_leaf(const T& item) { + return root->create_leaf(item); + } + +private: + Node* root; +}; + +void test_tree() { + Tree tree; + + auto* virus = tree.create_leaf("Virus"); + auto* worm = tree.create_leaf("Worm"); + + auto* test = virus->create_leaf("test"); + + test->create_leaf("a"); + test->create_leaf("b"); + test->create_leaf("c"); + test->create_leaf("884"); + + tree.walk([](auto* node) { + auto tab_count = node->parent_count(); + auto& data = node->data(); + + for(auto i = 0; i < tab_count; ++i) + std::printf("\t"); + + if(data.empty()) { + std::printf("(root)\n"); + } else { + std::printf("%s\n", data.c_str()); + } + }); +} + +int main() { + test_tree(); + return 0; +} \ No newline at end of file