From c5607d106449cc3c8680e95ec8595370996d5fb1 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Sun, 5 Nov 2023 19:24:20 +0100 Subject: core,tests: Fixed include file and implemented tree container --- c++/core/tree.h | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 c++/core/tree.h (limited to 'c++/core/tree.h') diff --git a/c++/core/tree.h b/c++/core/tree.h new file mode 100644 index 0000000..6ffd1f0 --- /dev/null +++ b/c++/core/tree.h @@ -0,0 +1,152 @@ +#pragma once + +#include +#include + +#include "error.h" + +namespace saw { +template +class tree_or; + +template +class tree final { +private: + std::vector> children_; +public: + tree() = default; + ~tree() = default; + + error_or add(T leaf) { + std::size_t index = size(); + try { + children_.push_back(std::move(leaf)); + }catch(const std::exception& e){ + (void)e; + + return make_error(); + } + + return index; + } + + error_or add() { + std::size_t index = size(); + try { + children_.push_back(tree{}); + }catch(const std::exception& e){ + (void)e; + + return make_error(); + } + + return index; + } + + std::size_t size() const { + return children_.size(); + } + + tree_or& at(std::size_t i){ + return children_.at(i); + } + + const tree_or& at(std::size_t i) const { + return children_.at(i); + } +}; + +template +class tree_or final { +private: + using type = std::variant,T>; + type tov_; + + friend class tree; +public: + tree_or():tov_{tree{}}{} + + tree_or(tree nd):tov_{std::move(nd)}{} + + tree_or(T val):tov_{std::move(val)}{} + + template + bool is() const { + return std::holds_alternative(tov_); + } + + bool is_tree() const { + return std::holds_alternative(tov_); + } + + bool is_value() const { + return std::holds_alternative(tov_); + } + + template + NT& get() { + return std::get(tov_); + } + + template + const NT& get() const { + return std::get(tov_); + } + + tree& get_tree(){ + return std::get(tov_); + } + + const tree& get_tree() const { + return std::get(tov_); + } + + T& get_value(){ + return std::get(tov_); + } + + const T& get_value() const { + return std::get(tov_); + } + + template + error_or extract(){ + if(!is()){ + return make_error(); + } + + NT nd = std::move(std::get(tov_)); + tov_ = tree{}; + + return nd; + } + + template + error_or replace(type nd){ + auto eon = extract(); + if(eon.is_error()){ + return eon; + } + + tov_ = std::move(nd); + + return eon; + } + + error_or> extract_tree() { + return extract>(); + } + + error_or> replace_tree(type nd){ + return replace>(std::move(nd)); + } + + error_or extract_value() { + return extract(); + } + + error_or replace_value(type nd){ + return replace(std::move(nd)); + } +}; +} -- cgit v1.2.3