Expressionist
Header-only C++20 evaluator of algebraic expressions embedded in JSON fields
Loading...
Searching...
No Matches
Expressionist::Expressionist Class Reference

#include <expressionist.hpp>

Public Member Functions

 Expressionist (json o, EvalMethod method=EvalMethod::RECURSIVE)
 Construct from a JSON object, to be mutated/copied by evaluate()/produce().
 
 Expressionist (std::string s, EvalMethod method=EvalMethod::RECURSIVE)
 
 Expressionist (const char *s, EvalMethod method=EvalMethod::RECURSIVE)
 Same as the std::string overload; disambiguates string-literal calls.
 
 Expressionist (EvalMethod method=EvalMethod::RECURSIVE)
 
void evaluate ()
 
void evaluate (json &object) const
 
json produce () const
 
json produce (json object) const
 
void setEvalMethod (EvalMethod method)
 
EvalMethod getEvalMethod () const
 The currently selected resolution strategy.
 
void setTag (const std::string &tag)
 
std::string tag () const
 The currently configured expression tag.
 
void setDisableKey (const std::string &key)
 
std::string disableKey () const
 The currently configured disable key.
 
const json & object () const
 Access the (possibly evaluated) stored object.
 
void addConstant (const std::string &name, double value)
 
void addUnaryFunction (const std::string &name, detail::UnaryFn fn)
 
void addBinaryFunction (const std::string &name, detail::BinaryFn fn)
 

Detailed Description

Evaluates algebraic expressions embedded in nlohmann::json string fields, replacing them in place with their computed values. Variables in an expression are simply other keys of the same JSON tree, resolved lexically and in any definition order.

#include <expressionist.hpp>
#include <iostream>
int main() {
nlohmann::json data = nlohmann::json::parse(R"({
"a": 1,
"b": 2,
"c": "$a + b",
"f": "$pi / 3",
"g": "$sin(f) * b"
})");
ex.evaluate(); // mutate the stored object in place
std::cout << ex.object().dump(2) << '\n';
}
Definition expressionist.hpp:1047

See the project README (this documentation's main page) for the full guide: nesting and scoping, the range operator, disabling evaluation for a subtree, the command-line tool, and the C/Python bindings.

Examples
main.cpp.

Constructor & Destructor Documentation

◆ Expressionist() [1/2]

Expressionist::Expressionist::Expressionist ( std::string  s,
EvalMethod  method = EvalMethod::RECURSIVE 
)
inline

Construct by parsing a JSON string. Throws ExpressionistException if s is not valid JSON.

◆ Expressionist() [2/2]

Expressionist::Expressionist::Expressionist ( EvalMethod  method = EvalMethod::RECURSIVE)
inline

Construct with an empty stored object, for use with the evaluate(json&)/produce(json) overloads below.

Member Function Documentation

◆ evaluate() [1/2]

void Expressionist::Expressionist::evaluate ( )
inline

Evaluate the stored object in place. Throws ExpressionistException (with context: the offending field's path and expression) on any failure – a malformed expression, an undefined variable or constant, or a circular dependency.

◆ evaluate() [2/2]

void Expressionist::Expressionist::evaluate ( json &  object) const
inline

Like evaluate(), but evaluates and mutates object instead of the engine's own stored object – lets one configured engine (tag, disable key, symbol table) be reused across many JSON documents:

Expressionist::Expressionist ex(EvalMethod::RECURSIVE);
ex.addConstant("g0", 9.80665);
nlohmann::json a = nlohmann::json::parse(R"({"m": 2, "w": "$m * g0"})");
ex.evaluate(a); // mutates `a` in place

◆ produce() [1/2]

json Expressionist::Expressionist::produce ( ) const
inline

Like evaluate(), but returns a new object and leaves the stored object intact:

nlohmann::json result = ex.produce(); // `data` is left unchanged
Examples
main.cpp.

◆ produce() [2/2]

json Expressionist::Expressionist::produce ( json  object) const
inline

Like evaluate(json&), but returns a new object and leaves object intact.

◆ setEvalMethod()

void Expressionist::Expressionist::setEvalMethod ( EvalMethod  method)
inline

Select the resolution strategy; may be changed at any time between evaluations.

Examples
main.cpp.

◆ setTag()

void Expressionist::Expressionist::setTag ( const std::string &  tag)
inline

Change the prefix that marks a JSON string as an expression (default "$"):

ex.setTag("@"); // now "@a + 1" is an expression, "$a + 1" a literal

◆ setDisableKey()

void Expressionist::Expressionist::setDisableKey ( const std::string &  key)
inline

Change the key that, set to the literal JSON false on an object, opts that object and its whole subtree out of evaluation (default "expressionist"). Pass "" to turn the mechanism off entirely.

// {"expressionist": false, "b": "$a + 1"} is left untouched, recursively.
ex.setDisableKey("skipEval"); // now "skipEval": false is the opt-out

◆ addConstant()

void Expressionist::Expressionist::addConstant ( const std::string &  name,
double  value 
)
inline

Register a named constant usable in expressions, alongside the built-in pi, e and tau.

◆ addUnaryFunction()

void Expressionist::Expressionist::addUnaryFunction ( const std::string &  name,
detail::UnaryFn  fn 
)
inline

Register a named single-argument function usable in expressions.

ex.addUnaryFunction("double", [](double x) { return 2.0 * x; });

◆ addBinaryFunction()

void Expressionist::Expressionist::addBinaryFunction ( const std::string &  name,
detail::BinaryFn  fn 
)
inline

Register a named two-argument function usable in expressions.

ex.addBinaryFunction("clampmax",
[](double x, double m) { return std::min(x, m); });

The documentation for this class was generated from the following file: