#pragma once #include extern "C" { #include "tree.h" #include "parser.h" } class Expression { std::string m_expr_str; struct parser m_parser; struct expr_node* m_root; public: Expression(const std::string& expr_str) { m_root = nullptr; SetExpression(expr_str); } Expression() : Expression("") {} Expression(const Expression&) = delete; Expression& operator=(const Expression&) = delete; Expression(Expression&& other) { m_expr_str = std::move(other.m_expr_str); m_parser = other.m_parser; m_root = other.m_root; other.m_root = nullptr; } Expression& operator=(Expression&& other) { if (this != &other) { if (m_root) { node_free(m_root); } m_expr_str = std::move(other.m_expr_str); m_parser = other.m_parser; m_root = other.m_root; other.m_root = nullptr; } return *this; } void SetExpression(const std::string& expr_str) { if (expr_str == m_expr_str) { return; } m_expr_str = expr_str; if (m_root) { node_free(m_root); m_root = nullptr; } if (m_expr_str.empty()) { return; } m_root = parser_parse(&m_parser, m_expr_str.c_str(), "x"); } bool Evaluate(double x, double& y) const { if (!m_root) { return false; } return node_eval(m_root, x, &y) == EVAL_OK; } bool IsValid() const { return m_root != nullptr; } const char* GetErrorText() const { if (parser_get_error(&m_parser) == ERR_NO_ERR) { return nullptr; } if (m_expr_str.empty()) { return nullptr; } return parser_get_error_text(&m_parser); } ~Expression() { if (m_root) { node_free(m_root); } } };