C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
ce23204895
commit
334953ee4d
1474
exprtk.hpp
1474
exprtk.hpp
File diff suppressed because it is too large
Load Diff
453
exprtk_test.cpp
453
exprtk_test.cpp
|
@ -4419,8 +4419,132 @@ struct va_func : public exprtk::ivararg_function<T>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct gen_func : public exprtk::igeneric_function<T>
|
||||||
|
{
|
||||||
|
typedef typename exprtk::igeneric_function<T>::generic_type generic_type;
|
||||||
|
typedef typename exprtk::igeneric_function<T>::parameter_list_t parameter_list_t;
|
||||||
|
|
||||||
|
typedef typename generic_type::scalar_view scalar_t;
|
||||||
|
typedef typename generic_type::vector_view vector_t;
|
||||||
|
typedef typename generic_type::string_view string_t;
|
||||||
|
|
||||||
|
gen_func()
|
||||||
|
: scalar_count(0),
|
||||||
|
vector_count(0),
|
||||||
|
string_count(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline T operator()(parameter_list_t& params)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < params.size(); ++i)
|
||||||
|
{
|
||||||
|
generic_type& gt = params[i];
|
||||||
|
|
||||||
|
switch (gt.type)
|
||||||
|
{
|
||||||
|
case generic_type::e_scalar : scalar_count++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case generic_type::e_vector : vector_count++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case generic_type::e_string : {
|
||||||
|
if (
|
||||||
|
("CdEf" != exprtk::to_str(string_t(gt))) &&
|
||||||
|
("abc123" != exprtk::to_str(string_t(gt)))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
string_count++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default : return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return T(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t scalar_count;
|
||||||
|
std::size_t vector_count;
|
||||||
|
std::size_t string_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct gen_func2 : public exprtk::igeneric_function<T>
|
||||||
|
{
|
||||||
|
typedef typename exprtk::igeneric_function<T>::parameter_list_t parameter_list_t;
|
||||||
|
|
||||||
|
gen_func2()
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline T operator()(parameter_list_t&)
|
||||||
|
{
|
||||||
|
return T(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct inc_func : public exprtk::igeneric_function<T>
|
||||||
|
{
|
||||||
|
typedef typename exprtk::igeneric_function<T>::generic_type generic_type;
|
||||||
|
typedef typename exprtk::igeneric_function<T>::parameter_list_t parameter_list_t;
|
||||||
|
|
||||||
|
typedef typename generic_type::scalar_view scalar_t;
|
||||||
|
typedef typename generic_type::vector_view vector_t;
|
||||||
|
typedef typename generic_type::string_view string_t;
|
||||||
|
|
||||||
|
inc_func()
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline T operator()(parameter_list_t& params)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < params.size(); ++i)
|
||||||
|
{
|
||||||
|
generic_type& gt = params[i];
|
||||||
|
|
||||||
|
switch (gt.type)
|
||||||
|
{
|
||||||
|
case generic_type::e_scalar : {
|
||||||
|
scalar_t scalar(gt);
|
||||||
|
scalar() += T(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case generic_type::e_vector : {
|
||||||
|
vector_t vector(gt);
|
||||||
|
for (std::size_t x = 0; x < vector.size(); ++x)
|
||||||
|
{
|
||||||
|
vector[x] += T(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case generic_type::e_string : {
|
||||||
|
string_t string(gt);
|
||||||
|
for (std::size_t x = 0; x < string.size(); ++x)
|
||||||
|
{
|
||||||
|
string[x] += static_cast<typename string_t::value_t>(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default : return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return T(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool run_test18()
|
inline bool run_test18()
|
||||||
|
{
|
||||||
{
|
{
|
||||||
typedef exprtk::expression<T> expression_t;
|
typedef exprtk::expression<T> expression_t;
|
||||||
|
|
||||||
|
@ -4443,7 +4567,7 @@ inline bool run_test18()
|
||||||
symbol_table.add_variable("u",u);
|
symbol_table.add_variable("u",u);
|
||||||
symbol_table.add_variable("v",v);
|
symbol_table.add_variable("v",v);
|
||||||
symbol_table.add_variable("t",t);
|
symbol_table.add_variable("t",t);
|
||||||
symbol_table.add_vararg_function("va_func",vaf);
|
symbol_table.add_function("va_func",vaf);
|
||||||
|
|
||||||
static const std::string expr_str_list[] =
|
static const std::string expr_str_list[] =
|
||||||
{
|
{
|
||||||
|
@ -4476,7 +4600,7 @@ inline bool run_test18()
|
||||||
|
|
||||||
if (!parser.compile(expr_str_list[i],expression))
|
if (!parser.compile(expr_str_list[i],expression))
|
||||||
{
|
{
|
||||||
printf("run_test18() - Error: %s Expression: %s\n",
|
printf("run_test18() - VarArg Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
|
@ -4499,7 +4623,330 @@ inline bool run_test18()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !failure;
|
if (failure)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
typedef exprtk::symbol_table<T> symbol_table_t;
|
||||||
|
typedef exprtk::expression<T> expression_t;
|
||||||
|
typedef exprtk::parser<T> parser_t;
|
||||||
|
|
||||||
|
T x = T(33);
|
||||||
|
T y = T(77);
|
||||||
|
|
||||||
|
T v0[] = { T(1), T(1), T(1), T(1) };
|
||||||
|
T v1[] = { T(1), T(2), T(3), T(4) };
|
||||||
|
|
||||||
|
std::vector<T> v2;
|
||||||
|
|
||||||
|
v2.push_back(T(5));
|
||||||
|
v2.push_back(T(6));
|
||||||
|
v2.push_back(T(7));
|
||||||
|
v2.push_back(T(8));
|
||||||
|
|
||||||
|
std::string s0 = "AbCdEfGhIj";
|
||||||
|
|
||||||
|
gen_func<T> f;
|
||||||
|
|
||||||
|
symbol_table_t symbol_table;
|
||||||
|
|
||||||
|
symbol_table.add_constants();
|
||||||
|
|
||||||
|
symbol_table.add_variable ("x" , x);
|
||||||
|
symbol_table.add_variable ("y" , y);
|
||||||
|
symbol_table.add_vector ("v0" ,v0);
|
||||||
|
symbol_table.add_vector ("v1" ,v1);
|
||||||
|
symbol_table.add_vector ("v2" ,v2);
|
||||||
|
symbol_table.add_stringvar("s0", s0);
|
||||||
|
symbol_table.add_function ("gen_func", f);
|
||||||
|
|
||||||
|
std::string expression_list[] =
|
||||||
|
{
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; gen_func(v0,v1 + v2, v0[2], x, 2x + y, z, 2w / 3, 'abc123',s0[2:5]);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; gen_func(v0,v1 + v2, v0[2], x, 2x + y, z, 2w / 3, 'abc123',s0[2:5]);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; gen_func(v1 + v2, v0[2], x, 2x + y, z, 2w / 3, 'abc123',s0[2:5],v0);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; gen_func(v0[2], x, 2x + y, z, 2w / 3, 'abc123',s0[2:5],v0, v1 + v2);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; gen_func(x, 2x + y, z, 2w / 3, 'abc123',s0[2:5],v0, v1 + v2, v0[2]);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; gen_func(2x + y, z, 2w / 3, 'abc123',s0[2:5],v0, v1 + v2, v0[2], x);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; gen_func(z, 2w / 3, 'abc123',s0[2:5],v0, v1 + v2, v0[2], x, 2x + y);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; gen_func(2w / 3, 'abc123',s0[2:5],v0, v1 + v2, v0[2], x, 2x + y, z);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; gen_func('abc123', s0[2:5],v0, v1 + v2, v0[2], x, 2x + y, z,2w / 3);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; gen_func(s0[2:5],v0, v1 + v2, v0[2], x, 2x + y, z,2w / 3, 'abc123');"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
|
||||||
|
|
||||||
|
|
||||||
|
bool failure = false;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < expression_list_size; ++i)
|
||||||
|
{
|
||||||
|
expression_t expression;
|
||||||
|
|
||||||
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
|
parser_t parser;
|
||||||
|
|
||||||
|
if (!parser.compile(expression_list[i],expression))
|
||||||
|
{
|
||||||
|
printf("run_test18() - GenFunc Error: %s Expression: %s\n",
|
||||||
|
parser.error().c_str(),
|
||||||
|
expression_list[i].c_str());
|
||||||
|
|
||||||
|
failure = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.scalar_count = 0;
|
||||||
|
f.vector_count = 0;
|
||||||
|
f.string_count = 0;
|
||||||
|
|
||||||
|
expression.value();
|
||||||
|
|
||||||
|
if (
|
||||||
|
(4 != f.scalar_count) ||
|
||||||
|
(3 != f.vector_count) ||
|
||||||
|
(2 != f.string_count)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (2) Expression: %s "
|
||||||
|
"sc_count = %d "
|
||||||
|
"vr_count = %d "
|
||||||
|
"st_count = %d\n",
|
||||||
|
expression_list[i].c_str(),
|
||||||
|
static_cast<int>(f.scalar_count),
|
||||||
|
static_cast<int>(f.vector_count),
|
||||||
|
static_cast<int>(f.string_count));
|
||||||
|
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failure)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
typedef exprtk::symbol_table<T> symbol_table_t;
|
||||||
|
typedef exprtk::expression<T> expression_t;
|
||||||
|
typedef exprtk::parser<T> parser_t;
|
||||||
|
|
||||||
|
T x = T(33);
|
||||||
|
T y = T(77);
|
||||||
|
|
||||||
|
T v0[] = { T(1), T(1), T(1), T(1) };
|
||||||
|
T v1[] = { T(1), T(2), T(3), T(4) };
|
||||||
|
T v2[] = { T(5), T(6), T(7), T(8) };
|
||||||
|
|
||||||
|
std::string s0 = "AbCdEfGhIj";
|
||||||
|
|
||||||
|
gen_func2<T> f;
|
||||||
|
|
||||||
|
symbol_table_t symbol_table;
|
||||||
|
|
||||||
|
symbol_table.add_constants();
|
||||||
|
|
||||||
|
symbol_table.add_variable ("x" , x);
|
||||||
|
symbol_table.add_variable ("y" , y);
|
||||||
|
symbol_table.add_vector ("v0" ,v0);
|
||||||
|
symbol_table.add_vector ("v1" ,v1);
|
||||||
|
symbol_table.add_vector ("v2" ,v2);
|
||||||
|
symbol_table.add_stringvar("s0", s0);
|
||||||
|
symbol_table.add_function ("foo", f);
|
||||||
|
|
||||||
|
std::string expression_list[] =
|
||||||
|
{
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; foo(v0,v1 + v2, v0[2], x, 2x + y, z, 2w / 3, 'abc123',s0[2:5]);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; foo(v1 + v2, v0[2], x, 2x + y, z, 2w / 3, 'abc123',s0[2:5],v0);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; foo(v0[2], x, 2x + y, z, 2w / 3, 'abc123',s0[2:5],v0, v1 + v2);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; foo(x, 2x + y, z, 2w / 3, 'abc123',s0[2:5],v0, v1 + v2, v0[2]);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; foo(2x + y, z, 2w / 3, 'abc123',s0[2:5],v0, v1 + v2, v0[2], x);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; foo(z, 2w / 3, 'abc123',s0[2:5],v0, v1 + v2, v0[2], x, 2x + y);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; foo(2w / 3, 'abc123',s0[2:5],v0, v1 + v2, v0[2], x, 2x + y, z);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; foo('abc123', s0[2:5],v0, v1 + v2, v0[2], x, 2x + y, z,2w / 3);",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; foo(s0[2:5],v0, v1 + v2, v0[2], x, 2x + y, z,2w / 3, 'abc123');"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
|
||||||
|
|
||||||
|
std::string parameter_type_list[] =
|
||||||
|
{
|
||||||
|
"VVTTTTVSS",
|
||||||
|
"VTTTTVSSV",
|
||||||
|
"TTTTVSSVV",
|
||||||
|
"TTTVSSVVT",
|
||||||
|
"TTVSSVVT*",
|
||||||
|
"TVSSVVT*" ,
|
||||||
|
"VSSVVT*" ,
|
||||||
|
"SSVVTTTTV",
|
||||||
|
"SVVTTTTVS",
|
||||||
|
};
|
||||||
|
|
||||||
|
bool failure = false;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < expression_list_size; ++i)
|
||||||
|
{
|
||||||
|
expression_t expression;
|
||||||
|
|
||||||
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
|
parser_t parser;
|
||||||
|
|
||||||
|
f.parameter_sequence = parameter_type_list[i];
|
||||||
|
|
||||||
|
if (!parser.compile(expression_list[i],expression))
|
||||||
|
{
|
||||||
|
printf("run_test18() - GenFunc2 Error: %s Expression: %s Parameter Sequence: %s\n",
|
||||||
|
parser.error().c_str(),
|
||||||
|
expression_list[i].c_str(),
|
||||||
|
parameter_type_list[i].c_str());
|
||||||
|
|
||||||
|
failure = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
expression.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failure)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
bool failure = false;
|
||||||
|
|
||||||
|
std::string expression_list[] =
|
||||||
|
{
|
||||||
|
"foo(v0,v1,v2,x,y,s0);",
|
||||||
|
"foo(v1,v2,x,y,s0,v0);",
|
||||||
|
"foo(v2,x,y,s0,v0,v1);",
|
||||||
|
"foo(x,y,s0,v0,v1,v2);",
|
||||||
|
"foo(y,s0,v0,v1,v2,x);",
|
||||||
|
"foo(s0,v0,v1,v2,x,y);"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
|
||||||
|
|
||||||
|
std::string parameter_type_list[] =
|
||||||
|
{
|
||||||
|
"VVVTTS",
|
||||||
|
"VVTTSV",
|
||||||
|
"VTTSVV",
|
||||||
|
"TTSVVV",
|
||||||
|
"TSVVVT",
|
||||||
|
"SVVVTT"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < expression_list_size; ++i)
|
||||||
|
{
|
||||||
|
typedef exprtk::symbol_table<T> symbol_table_t;
|
||||||
|
typedef exprtk::expression<T> expression_t;
|
||||||
|
typedef exprtk::parser<T> parser_t;
|
||||||
|
|
||||||
|
T x = T(33);
|
||||||
|
T y = T(77);
|
||||||
|
|
||||||
|
T v0[] = { T(1), T(1), T(1), T(1) };
|
||||||
|
T v1[] = { T(1), T(2), T(3), T(4) };
|
||||||
|
T v2[] = { T(5), T(6), T(7), T(8) };
|
||||||
|
|
||||||
|
std::string s0 = "AbCdEfGhIj";
|
||||||
|
|
||||||
|
T x_inc = T(34);
|
||||||
|
T y_inc = T(78);
|
||||||
|
|
||||||
|
T v0_inc[] = { T(2), T(2), T(2), T(2) };
|
||||||
|
T v1_inc[] = { T(2), T(3), T(4), T(5) };
|
||||||
|
T v2_inc[] = { T(6), T(7), T(8), T(9) };
|
||||||
|
|
||||||
|
std::size_t sizeof_vec = sizeof(v0) / sizeof(T);
|
||||||
|
|
||||||
|
std::string s0_inc = "BcDeFgHiJk";
|
||||||
|
|
||||||
|
inc_func<T> f;
|
||||||
|
|
||||||
|
symbol_table_t symbol_table;
|
||||||
|
|
||||||
|
symbol_table.add_constants();
|
||||||
|
|
||||||
|
symbol_table.add_variable ("x" , x);
|
||||||
|
symbol_table.add_variable ("y" , y);
|
||||||
|
symbol_table.add_vector ("v0" ,v0);
|
||||||
|
symbol_table.add_vector ("v1" ,v1);
|
||||||
|
symbol_table.add_vector ("v2" ,v2);
|
||||||
|
symbol_table.add_stringvar("s0", s0);
|
||||||
|
symbol_table.add_function ("foo", f);
|
||||||
|
|
||||||
|
expression_t expression;
|
||||||
|
|
||||||
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
|
parser_t parser;
|
||||||
|
|
||||||
|
f.parameter_sequence = parameter_type_list[i];
|
||||||
|
|
||||||
|
if (!parser.compile(expression_list[i],expression))
|
||||||
|
{
|
||||||
|
printf("run_test18() - IncFunc Error: %s Expression: %s Parameter Sequence: %s\n",
|
||||||
|
parser.error().c_str(),
|
||||||
|
expression_list[i].c_str(),
|
||||||
|
parameter_type_list[i].c_str());
|
||||||
|
|
||||||
|
failure = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
expression.value();
|
||||||
|
|
||||||
|
if (x != x_inc)
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (3) Expression: %s Check: x\n",
|
||||||
|
expression_list[i].c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y != y_inc)
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (3) Expression: %s Check: y\n",
|
||||||
|
expression_list[i].c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s0 != s0_inc)
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (3) Expression: %s Check: y\n",
|
||||||
|
expression_list[i].c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::equal(v0,v0 + sizeof_vec,v0_inc))
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (3) Expression: %s Check: v0\n",
|
||||||
|
expression_list[i].c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::equal(v1,v1 + sizeof_vec,v1_inc))
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (3) Expression: %s Check: v1\n",
|
||||||
|
expression_list[i].c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::equal(v2,v2 + sizeof_vec,v2_inc))
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (3) Expression: %s Check: v2\n",
|
||||||
|
expression_list[i].c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failure)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
83
readme.txt
83
readme.txt
|
@ -618,7 +618,7 @@ current values assigned to the variables will be used.
|
||||||
y = -9.0;
|
y = -9.0;
|
||||||
expression.value(); // 3.7 * -9 + 3
|
expression.value(); // 3.7 * -9 + 3
|
||||||
|
|
||||||
// 'x * -9 + 3' for x in range of [0,100] in steps of 0.0001
|
// 'x * -9 + 3' for x in range of [0,100) in steps of 0.0001
|
||||||
for (var x = 0; x < 100; x += 0.0001)
|
for (var x = 0; x < 100; x += 0.0001)
|
||||||
{
|
{
|
||||||
expression.value(); // x * -9 + 3
|
expression.value(); // x * -9 + 3
|
||||||
|
@ -1029,7 +1029,8 @@ There are two types of function interface:
|
||||||
|
|
||||||
(1) ifunction
|
(1) ifunction
|
||||||
(2) ivararg_function
|
(2) ivararg_function
|
||||||
(3) function_compositor
|
(3) igeneric_function
|
||||||
|
(4) function_compositor
|
||||||
|
|
||||||
|
|
||||||
(1) ifunction
|
(1) ifunction
|
||||||
|
@ -1075,7 +1076,56 @@ example defines a vararg function called 'boo':
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
(3) function_compositor
|
(3) igeneric_function
|
||||||
|
This interface supports a variable number of arguments and types as
|
||||||
|
input into the function. The function operator interface uses a
|
||||||
|
std::vector specialized upon the type_store type to facilitate
|
||||||
|
parameter passing.
|
||||||
|
|
||||||
|
The fundamental types that can be passed into the function as
|
||||||
|
parameters and their views are as follows:
|
||||||
|
|
||||||
|
(1) scalar - scalar_view
|
||||||
|
(2) vector - vector_view
|
||||||
|
(3) string - string_view
|
||||||
|
|
||||||
|
The following example defines a generic function called 'too':
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct too : public exprtk::igeneric_function<T>
|
||||||
|
{
|
||||||
|
typedef typename exprtk::igeneric_function<T>::parameter_list_t
|
||||||
|
parameter_list_t;
|
||||||
|
|
||||||
|
too()
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline T operator()(parameter_list_t& parameters)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < parameters.size(); ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return T(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
In the above example, the parameter_list_t type is a type of
|
||||||
|
std::vector of type_store. Each type_store instance has a member
|
||||||
|
called 'type' which holds the enumeration pertaining the underlying
|
||||||
|
type of the type_store. There are three type enumerations:
|
||||||
|
|
||||||
|
(1) e_scalar - variables, vector elements, general expressions
|
||||||
|
eg: x, y, z, vec[3x + 1], 2x + 3
|
||||||
|
|
||||||
|
(2) e_vector - vectors, vector expressions
|
||||||
|
eg: vec1, 2 * vec1 + vec2 / 3
|
||||||
|
|
||||||
|
(3) e_string - string, string literal and range variants of both
|
||||||
|
eg: 'AString', s0, 'AString'[x:y], s1[1+x:]
|
||||||
|
|
||||||
|
|
||||||
|
(4) function_compositor
|
||||||
The function compositor interface allows a user to define a function
|
The function compositor interface allows a user to define a function
|
||||||
using ExprTk syntax. The functions are limited to returning a single
|
using ExprTk syntax. The functions are limited to returning a single
|
||||||
scalar value and consuming up to six parameters as input.
|
scalar value and consuming up to six parameters as input.
|
||||||
|
@ -1126,7 +1176,7 @@ The following demonstrates how all the pieces are put together:
|
||||||
|
|
||||||
symbol_table_t symbol_table;
|
symbol_table_t symbol_table;
|
||||||
symbol_table.add_function("foo",f);
|
symbol_table.add_function("foo",f);
|
||||||
symbol_table.add_vararg_function("boo",b);
|
symbol_table.add_function("boo",b);
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add(function_t()
|
.add(function_t()
|
||||||
|
@ -1330,11 +1380,11 @@ into account when using Exprtk:
|
||||||
epsilons of 0.0000000001 and 0.000001 for double and float
|
epsilons of 0.0000000001 and 0.000001 for double and float
|
||||||
types respectively.
|
types respectively.
|
||||||
|
|
||||||
(11) All trigonometric functions assume radian input unless
|
(11) All trigonometric functions assume radian input unless stated
|
||||||
stated otherwise.
|
otherwise.
|
||||||
|
|
||||||
(12) Expressions may contain white-space characters such as
|
(12) Expressions may contain white-space characters such as space,
|
||||||
space, tabs, new-lines, control-feed et al.
|
tabs, new-lines, control-feed et al.
|
||||||
('\n', '\r', '\t', '\b', '\v', '\f')
|
('\n', '\r', '\t', '\b', '\v', '\f')
|
||||||
|
|
||||||
(13) Strings may be comprised of any combination of letters, digits
|
(13) Strings may be comprised of any combination of letters, digits
|
||||||
|
@ -1355,9 +1405,9 @@ into account when using Exprtk:
|
||||||
then where applicable strength reduction optimisations may be
|
then where applicable strength reduction optimisations may be
|
||||||
applied.
|
applied.
|
||||||
|
|
||||||
(18) String processing capabilities are available by default.
|
(18) String processing capabilities are available by default. To
|
||||||
To turn them off, the following needs to be defined at
|
turn them off, the following needs to be defined at compile
|
||||||
compile time: exprtk_disable_string_capabilities
|
time: exprtk_disable_string_capabilities
|
||||||
|
|
||||||
(19) Composited functions can call themselves or any other functions
|
(19) Composited functions can call themselves or any other functions
|
||||||
that have been defined prior to their own definition.
|
that have been defined prior to their own definition.
|
||||||
|
@ -1396,9 +1446,10 @@ into account when using Exprtk:
|
||||||
3. /* .... */
|
3. /* .... */
|
||||||
|
|
||||||
(26) The 'null' value type is a special non-zero type that
|
(26) The 'null' value type is a special non-zero type that
|
||||||
incorporates specific semantics when undergoing operations
|
incorporates specific semantics when undergoing operations with
|
||||||
with the standard numeric type. The following is a list of
|
the standard numeric type. The following is a list of type and
|
||||||
type and boolean results associated with the use of 'null':
|
boolean results associated with the use of 'null':
|
||||||
|
|
||||||
1. null +,-,*,/,% x --> x
|
1. null +,-,*,/,% x --> x
|
||||||
2. x +,-,*,/,% null --> x
|
2. x +,-,*,/,% null --> x
|
||||||
3. null +,-,*,/,% null --> null
|
3. null +,-,*,/,% null --> null
|
||||||
|
@ -1411,8 +1462,8 @@ into account when using Exprtk:
|
||||||
|
|
||||||
(27) The following is a list of reserved words and symbols used by
|
(27) The following is a list of reserved words and symbols used by
|
||||||
ExprTk. Attempting to add a variable or custom function to a
|
ExprTk. Attempting to add a variable or custom function to a
|
||||||
symbol table using any of the reserved words will result in
|
symbol table using any of the reserved words will result in a
|
||||||
a failure.
|
failure.
|
||||||
|
|
||||||
abs, acos, acosh, and, asin, asinh, atan, atan2, atanh, avg,
|
abs, acos, acosh, and, asin, asinh, atan, atan2, atanh, avg,
|
||||||
break, case, ceil, clamp, continue, cosh, cos, cot, csc,
|
break, case, ceil, clamp, continue, cosh, cos, cot, csc,
|
||||||
|
|
Loading…
Reference in New Issue