diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..292c875 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +__pycache__/ +*.o +/vxorg +/tree_test +/testdata diff --git a/tree.hpp b/tree.hpp index b6993e3..bd00eae 100644 --- a/tree.hpp +++ b/tree.hpp @@ -2,105 +2,87 @@ #include /// Port of tree.py to C++ -template +template struct Tree { + // FIXME make T not require default constructability + struct Node { + protected: + friend Tree; + Node* parent = nullptr; + std::vector children {}; + T item {}; - // 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; - } + public: + ~Node() { + for(auto& child : children) + delete child; + } - T& data() { - return item; - } + T& data() { return item; } - const T& data() const { - return item; - } + const T& data() const { return item; } - bool is_leaf() const { - return children.size() == 0; - } + bool is_leaf() const { return children.size() == 0; } - Node* parent_node() { - return parent; - } + Node* parent_node() { return parent; } - Node* create_leaf(const T& item) { - auto* node = new Node; - node->parent = this; - node->item = item; - children.push_back(node); - return node; - } + 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 + void walk(Fn&& fn) { + fn(this); + if(!is_leaf()) { + for(auto& child : children) + child->walk(fn); + } + } - template - Node* find_child(Pred&& predicate) { - if(predicate(this) == true) - return this; + template + Node* find_child(Pred&& predicate) { + if(predicate(this) == true) + return this; - for(auto& child: children) - if(predicate(child) == true) - return child; + for(auto& child : children) + if(predicate(child) == true) + return child; - return nullptr; - } + return nullptr; + } - std::size_t parent_count() const { - auto* parent = this->parent; - auto parent_count = 0z; - while(parent) { - parent_count ++; - parent = parent->parent; - } - return parent_count; - } + 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() { - root = new Node; - } + ~Tree() { delete root; } - ~Tree() { - delete root; - } + // Trees are not copyable but they can move + Tree(const Tree&) = delete; + Tree(Tree&&) = default; - // Trees are not copyable but they can move - Tree(const Tree&) = delete; - Tree(Tree&&) = default; + template + void walk(Fn&& fn) { + root->walk(fn); + } - template - void walk(Fn&& fn) { - root->walk(fn); - } + Node* create_leaf(const T& item) { return root->create_leaf(item); } + Node* root_node() { return root; } - Node* create_leaf(const T& item) { - return root->create_leaf(item); - } - - Node* root_node() { - return root; - } - -private: - Node* root; + private: + Node* root; }; \ No newline at end of file diff --git a/vxheaven_parse.cpp b/vxheaven_parse.cpp index 03caa11..e5114ef 100644 --- a/vxheaven_parse.cpp +++ b/vxheaven_parse.cpp @@ -21,6 +21,34 @@ namespace vxorg { return res; } + std::string get_sample_name(VxHeavenTree::Node* node) { + if(node == nullptr) + return ""; + + if(!node->data().is_sample) + return node->data().name; + + std::string sample_name {}; + std::vector parent_list {}; + vxorg::VxHeavenTree::Node* parent = node->parent_node(); + + while(parent) { + if(parent->data().name.empty()) + break; + + parent_list.push_back(&parent->data()); + parent = parent->parent_node(); + } + + for(auto& item : std::views::reverse(parent_list)) { + sample_name += std::format("{}.", item->name); + } + + sample_name += node->data().name; + + return sample_name; + } + void parse_into_tree(VxHeavenTree& tree, std::istream& is) { std::string line {}; while(std::getline(is, line)) { diff --git a/vxheaven_parse.hpp b/vxheaven_parse.hpp index 6b1ce7d..75f0e16 100644 --- a/vxheaven_parse.hpp +++ b/vxheaven_parse.hpp @@ -1,16 +1,19 @@ #pragma once -#include "tree.hpp" #include +#include "tree.hpp" + namespace vxorg { - struct VxHeavenItem { - std::string name; - // True if this item is also a sample - bool is_sample; - }; + struct VxHeavenItem { + std::string name; + // True if this item is also a sample + bool is_sample; + }; - using VxHeavenTree = Tree; + using VxHeavenTree = Tree; - void parse_into_tree(VxHeavenTree& tree, std::istream& is); -} \ No newline at end of file + std::string get_sample_name(VxHeavenTree::Node* node); + + void parse_into_tree(VxHeavenTree& tree, std::istream& is); +} // namespace vxorg \ No newline at end of file diff --git a/vxorg.cpp b/vxorg.cpp index d327e33..9082c23 100644 --- a/vxorg.cpp +++ b/vxorg.cpp @@ -1,15 +1,12 @@ #include #include -#include #include -#include -#include #include "tree.hpp" #include "vxheaven_parse.hpp" int main() { - std::ifstream ifs("./samples.sort"); + std::ifstream ifs("./testdata/samples.sort"); vxorg::VxHeavenTree tree; vxorg::parse_into_tree(tree, ifs); @@ -26,26 +23,8 @@ int main() { std::printf("(root)\n"); } else { if(data.is_sample) { - std::string sample_name {}; - - std::vector parent_list {}; - vxorg::VxHeavenTree::Node* parent = node->parent_node(); - while(parent) { - if(parent->data().name.empty()) - break; - - parent_list.push_back(&parent->data()); - parent = parent->parent_node(); - } - - for(auto& item : std::views::reverse(parent_list)) { - sample_name += std::format("{}.", item->name); - } - - sample_name += data.name; - + std::string sample_name = vxorg::get_sample_name(node); std::printf("%s (sample %s)\n", data.name.c_str(), sample_name.c_str()); - } else { std::printf("%s\n", data.name.c_str()); }