diff options
Diffstat (limited to 'c++/core/tree.h')
-rw-r--r-- | c++/core/tree.h | 248 |
1 files changed, 0 insertions, 248 deletions
diff --git a/c++/core/tree.h b/c++/core/tree.h deleted file mode 100644 index 68fa20a..0000000 --- a/c++/core/tree.h +++ /dev/null @@ -1,248 +0,0 @@ -#pragma once - -#include <variant> -#include <vector> - -#include "error.h" - -namespace saw { -/** - * Container with a simplistic approach to a branch - */ -template<typename T, typename Tree> -class branch; - -/** - * Tree object holding branches. - * - * The name comes from the fact a tree is acting as a node while the branch class is the - * edge to a leaf or other nodes. A tree holds the branches while the branch either has - * a leaf or another sub tree. - */ -template<typename T, typename Tree> -class tree_container final { -private: - /** - * Object holding the treeed branch instances - */ - std::vector<branch<T,Tree>> children_; -public: - /** - * Default constructor - */ - tree_container() = default; - - /** - * Destructor - */ - ~tree_container() = default; - - SAW_FORBID_COPY(tree_container); - SAW_DEFAULT_MOVE(tree_container); - - /** - * Reserve space for siz elements - */ - error_or<void> reserve(std::size_t siz){ - try{ - children_.reserve(siz); - }catch(const std::exception& e){ - (void) e; - - return make_error<err::out_of_memory>(); - } - - return void_t{}; - } - - /** - * Add a branch with a leaf attached to the tree - */ - error_or<std::size_t> add(T leaf) { - std::size_t index = size(); - try { - /** - * Technically we're adding a leaf on a branch - */ - children_.emplace_back(std::move(leaf)); - }catch(const std::exception& e){ - (void)e; - - return make_error<err::critical>(); - } - - return index; - } - - /** - * Add a branch to the tree with a tree attached - */ - error_or<std::size_t> add() { - std::size_t index = size(); - try { - - children_.emplace_back(Tree{}); - }catch(const std::exception& e){ - (void)e; - - return make_error<err::critical>(); - } - - return index; - } - - /** - * Returns the amount of branches contained within this tree level - */ - std::size_t size() const { - return children_.size(); - } - - /** - * Returns the branch at i - */ - branch<T,Tree>& at(std::size_t i){ - return children_.at(i); - } - - /** - * Returns the branch at i - */ - const branch<T,Tree>& at(std::size_t i) const { - return children_.at(i); - } -}; - -template<typename T, typename Tree> -class branch final { -private: - using type = std::variant<Tree,T>; - type tov_; - - /** - * We're friend classing the tree since it's way easier this way and the branch and tree - * class are intertwined heavily anyway. - */ -public: - /** - * - */ - branch():tov_{Tree{}}{} - - branch(Tree nd):tov_{std::move(nd)}{} - - branch(T val):tov_{std::move(val)}{} - - SAW_FORBID_COPY(branch); - SAW_DEFAULT_MOVE(branch); - - template<typename NT> - bool is() const { - return std::holds_alternative<NT>(tov_); - } - - bool is_tree() const { - return std::holds_alternative<Tree>(tov_); - } - - bool is_value() const { - return std::holds_alternative<T>(tov_); - } - - template<typename NT> - NT& get() { - return std::get<NT>(tov_); - } - - template<typename NT> - const NT& get() const { - return std::get<NT>(tov_); - } - - Tree& get_tree(){ - return std::get<Tree>(tov_); - } - - const Tree& get_tree() const { - return std::get<Tree>(tov_); - } - - T& get_value(){ - return std::get<T>(tov_); - } - - const T& get_value() const { - return std::get<T>(tov_); - } - - template<typename NT> - error_or<NT> extract(){ - if(!is<NT>()){ - return make_error<err::invalid_state>(); - } - - NT nd = std::move(std::get<NT>(tov_)); - tov_ = Tree{}; - - return nd; - } - - template<typename NT> - error_or<NT> replace(type nd){ - auto eon = extract<NT>(); - if(eon.is_error()){ - return eon; - } - - tov_ = std::move(nd); - - return eon; - } - - error_or<Tree> extract_tree() { - return extract<Tree>(); - } - - error_or<Tree> replace_tree(type nd){ - return replace<Tree>(std::move(nd)); - } - - error_or<T> extract_value() { - return extract<T>(); - } - - error_or<T> replace_value(type nd){ - return replace<T>(std::move(nd)); - } -}; - -template<typename T> -class tree { - private: - tree_container<T,tree<T>> data_; - public: - error_or<void> reserve(std::size_t size){ - return data_.reserve(size); - } - - size_t size() const { - return data_.size(); - } - - error_or<size_t> add() { - return data_.add(); - } - - error_or<size_t> add(T leaf){ - return data_.add(std::move(leaf)); - } - - branch<T, tree<T>>& at(size_t i){ - return data_.at(i); - } - - const branch<T, tree<T>>& at(size_t i) const { - return data_.at(i); - } -}; -} |