I can't seem to get a vector output from exprTk. I figure it should be relatively simple but in the manual I can only find how to input a vector and not how to output one.
What I currently have is the following:
typedef double T; // numeric type (float, double, mpfr etc...)
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string expression_string = "var z[2] := { x, y };";
T x = T(5.3);
T y = T(2.3);
std::vector<T> z;
symbol_table_t symbol_table;
symbol_table.add_variable("x", x);
symbol_table.add_variable("y", y);
symbol_table.add_vector("z", z);
expression_t expression;
expression.register_symbol_table(symbol_table);
//Check if expression is valid
parser_t parser;
if (!parser.compile(expression_string, expression))
{
printf("Compilation error...\n");
return;
}
T result = expression.value();
std::cout << result << std::endl; \\returns: 5.3 as expected the first element of vector z.
std::cout << z[0] << std::endl; \\Crashes the program
What I want as output is just the vector z. How do I do this, or what am I doing wrong?
As per Section 20 - Expression Return Values of the readme, One can immediately exit an expression returning any number of variables of any type simply by using the return statement.
The example provided in the documentation is as follows:
std::string expression_string =
" if (x < y) "
" return [x + 1,'return-call 1']; "
" else if (x > y) "
" return [y / 2, y + 1, 'return-call 2']; "
" else if (equal(x,y)) "
" x + y; "
" return [x, y, x + y, x - y, 'return-call 3'] ";
using symbol_table_t = exprtk::symbol_table<double>;
using expression_t = exprtk::expression<double>;
using parser_t = exprtk::parser<double>;
symbol_table_t symbol_table;
expression_t expression;
parser_t parser;
double x = 0;
double y = 0;
symbol_table.add_variable("x",x);
symbol_table.add_variable("y",y);
expression.register_symbol_table(symbol_table);
parser.compile(expression_string,expression);
T result = expression.value();
if (expression.results().count())
{
using results_context_t = exprtk::results_context<T>;
using type_t = typename results_context_t::type_store_t;
using scalar_t = typename type_t::scalar_view;
using vector_t = typename type_t::vector_view;
using string_t = typename type_t::string_view;
const results_context_t& results = expression.results();
for (std::size_t i = 0; i < results.count(); ++i)
{
type_t t = results[i];
switch (t.type)
{
case type_t::e_scalar : ...
break;
case type_t::e_vector : ...
break;
case type_t::e_string : ...
break;
default : continue;
}
}
Note1: Your expression will become:
var z[2] := { x, y }; return [z];
Note2:
In order to have your "one-line" method you could write a simple free function that wraps the boiler plate code after the conditional and extracts the vector of your choosing (i'th result given it's of vector type) from the results list.
template <typename T>
bool get_vector(const std::size_t index,
const results_context_t& results,
std::vector<T>& v)
{
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With