#pragma once #include #include // Forward declaration so tinyexpr.h stays out of this header. struct te_expr; // Compiled single-variable expression. The bound variable is named x. // Compile once at config load; evaluate many times at simulation time. // tinyexpr bakes the address of the bound variable into the compiled tree, so // we keep x on the heap to preserve that pointer across moves. class Formula { public: Formula() = default; Formula(const Formula&) = delete; Formula& operator=(const Formula&) = delete; Formula(Formula&& other) noexcept; Formula& operator=(Formula&& other) noexcept; ~Formula(); // Parses source and returns a ready-to-evaluate Formula. // Throws std::runtime_error with the source and error position on failure. static Formula compile(const std::string& source); // Evaluates the expression at the given x. Requires a compiled formula. double evaluate(double x) const; const std::string& source() const { return m_source; } bool isValid() const { return m_expr != nullptr; } private: std::string m_source; std::unique_ptr m_x; te_expr* m_expr = nullptr; };