C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
b6cdf0d2f9
commit
1d757d5718
1098
exprtk.hpp
1098
exprtk.hpp
File diff suppressed because it is too large
Load Diff
186
exprtk_test.cpp
186
exprtk_test.cpp
|
@ -1727,7 +1727,6 @@ inline bool run_test01()
|
||||||
|
|
||||||
const std::size_t expr_list_size = sizeof(expr_list) / sizeof(std::string);
|
const std::size_t expr_list_size = sizeof(expr_list) / sizeof(std::string);
|
||||||
|
|
||||||
|
|
||||||
const std::size_t rounds = 60;
|
const std::size_t rounds = 60;
|
||||||
|
|
||||||
for (std::size_t r = 0; r < rounds; ++r)
|
for (std::size_t r = 0; r < rounds; ++r)
|
||||||
|
@ -2055,7 +2054,39 @@ inline bool run_test02()
|
||||||
test_ab<T>("'123'[] + a[] == 7" ,"1234","" ,T(1.0)),
|
test_ab<T>("'123'[] + a[] == 7" ,"1234","" ,T(1.0)),
|
||||||
test_ab<T>("abs(a[] - '12345'[]) == 1" ,"1234","" ,T(1.0)),
|
test_ab<T>("abs(a[] - '12345'[]) == 1" ,"1234","" ,T(1.0)),
|
||||||
test_ab<T>("'1234'[] + '12345'[] == a[] + b[]" ,"1234","12345" ,T(1.0)),
|
test_ab<T>("'1234'[] + '12345'[] == a[] + b[]" ,"1234","12345" ,T(1.0)),
|
||||||
test_ab<T>("abs('123'[] - '1234'[]) == abs(a[] - b[])" ,"1234","12345",T(1.0))
|
test_ab<T>("abs('123'[] -'1234'[]) == abs(a[] - b[])" ,"1234","12345",T(1.0)),
|
||||||
|
test_ab<T>("(a + b) == 'abc123' ","abc","123" ,T(1.0)),
|
||||||
|
test_ab<T>("(a + '123') == 'abc123' ","abc","123" ,T(1.0)),
|
||||||
|
test_ab<T>("('abc' + b) == 'abc123' ","abc","123" ,T(1.0)),
|
||||||
|
test_ab<T>("(a + '1') == 'abc1' ","abc","123" ,T(1.0)),
|
||||||
|
test_ab<T>("('a' + b) == 'a123' ","abc","123" ,T(1.0)),
|
||||||
|
test_ab<T>("(a[2:7] + b) == 'cdefgh0123' ","abcdefghij","0123",T(1.0)),
|
||||||
|
test_ab<T>("(a + b[2:7]) == 'abc234567' ","abc","0123456789" ,T(1.0)),
|
||||||
|
test_ab<T>("(a[2:7] + '0123') == 'cdefgh0123' ","abcdefghij","0123",T(1.0)),
|
||||||
|
test_ab<T>("('abc' + b[2:7]) == 'abc234567' ","abc","0123456789" ,T(1.0)),
|
||||||
|
test_ab<T>("(a[2:2] + b[3:3]) == 'c3' ","abc","0123456789" ,T(1.0)),
|
||||||
|
test_ab<T>("(a[3:] + b) == 'defghij0123' ","abcdefghij","0123",T(1.0)),
|
||||||
|
test_ab<T>("('abc' + b[:7]) == 'abc01234567' ","abc","0123456789" ,T(1.0)),
|
||||||
|
test_ab<T>("a + '123' == 'abc'+ b ","abc" , "123" , T(1.0)),
|
||||||
|
test_ab<T>("a[0:2] + '123' == 'abc' + b[0:2] ","abcXYZ", "123XYZ", T(1.0)),
|
||||||
|
test_ab<T>("a[ :2] + '123' == 'abc' + b[ :2] ","abcXYZ", "123XYZ", T(1.0)),
|
||||||
|
test_ab<T>("a[3: ] + '123' == 'abc' + b[3: ]","XYZabc", "XYZ123", T(1.0)),
|
||||||
|
test_ab<T>("a[3:a[] - 1] + '123' == 'abc' + b[3:b[] - 1]","XYZabc", "XYZ123", T(1.0)),
|
||||||
|
test_ab<T>("(a[r0:r2] + b) == 'cdefgh0123' ","abcdefghij","0123",T(1.0)),
|
||||||
|
test_ab<T>("(a + b[r0:r2]) == 'abc234567' ","abc","0123456789" ,T(1.0)),
|
||||||
|
test_ab<T>("(a[r0:r2] + '0123') == 'cdefgh0123' ","abcdefghij","0123",T(1.0)),
|
||||||
|
test_ab<T>("('abc' + b[r0:r2]) == 'abc234567' ","abc","0123456789" ,T(1.0)),
|
||||||
|
test_ab<T>("(a[r0:r0] + b[r3:r3]) == 'c3' ","abc","0123456789" ,T(1.0)),
|
||||||
|
test_ab<T>("(a[r3:] + b) == 'defghij0123' ","abcdefghij","0123",T(1.0)),
|
||||||
|
test_ab<T>("('abc' + b[:r2]) == 'abc01234567' ","abc","0123456789" ,T(1.0)),
|
||||||
|
test_ab<T>("a[0:r0] + '123' == 'abc' + b[0:r0] ","abcXYZ", "123XYZ", T(1.0)),
|
||||||
|
test_ab<T>("a[ :r0] + '123' == 'abc' + b[ :r0] ","abcXYZ", "123XYZ", T(1.0)),
|
||||||
|
test_ab<T>("a[r3: ] + '123' == 'abc' + b[r3: ]","XYZabc", "XYZ123", T(1.0)),
|
||||||
|
test_ab<T>("a[r3:a[] - 1] + '123' == 'abc' + b[r3:b[] - 1]","XYZabc", "XYZ123", T(1.0)),
|
||||||
|
test_ab<T>("(a[r0:r0] + b[r3:r0+1]) == 'c3' ","abc","0123456789" ,T(1.0)),
|
||||||
|
test_ab<T>("(a[r0+1:] + b) == 'defghij0123' ","abcdefghij","0123",T(1.0)),
|
||||||
|
test_ab<T>("a[r0+1: ] + '123' == 'abc' + b[r0+1: ]","XYZabc", "XYZ123", T(1.0)),
|
||||||
|
test_ab<T>("a[r0+1:a[] - 1] + '123' == 'abc' + b[r0+1:b[] - 1]","XYZabc", "XYZ123", T(1.0))
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_ab<T>);
|
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_ab<T>);
|
||||||
|
@ -2074,6 +2105,8 @@ inline bool run_test02()
|
||||||
|
|
||||||
T r0 = T(2);
|
T r0 = T(2);
|
||||||
T r1 = T(6);
|
T r1 = T(6);
|
||||||
|
T r2 = T(7);
|
||||||
|
T r3 = T(3);
|
||||||
|
|
||||||
exprtk::symbol_table<T> symbol_table;
|
exprtk::symbol_table<T> symbol_table;
|
||||||
symbol_table.add_stringvar("a" ,str_a);
|
symbol_table.add_stringvar("a" ,str_a);
|
||||||
|
@ -2081,6 +2114,8 @@ inline bool run_test02()
|
||||||
symbol_table.add_stringvar("c" ,str_c);
|
symbol_table.add_stringvar("c" ,str_c);
|
||||||
symbol_table.add_variable ("r0", r0);
|
symbol_table.add_variable ("r0", r0);
|
||||||
symbol_table.add_variable ("r1", r1);
|
symbol_table.add_variable ("r1", r1);
|
||||||
|
symbol_table.add_variable ("r2", r2);
|
||||||
|
symbol_table.add_variable ("r3", r3);
|
||||||
|
|
||||||
exprtk::expression<T> expression;
|
exprtk::expression<T> expression;
|
||||||
expression.register_symbol_table(symbol_table);
|
expression.register_symbol_table(symbol_table);
|
||||||
|
@ -4490,7 +4525,7 @@ struct gen_func : public exprtk::igeneric_function<T>
|
||||||
string_count(0)
|
string_count(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline T operator()(parameter_list_t& params)
|
inline T operator()(parameter_list_t params)
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < params.size(); ++i)
|
for (std::size_t i = 0; i < params.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -4556,7 +4591,7 @@ struct inc_func : public exprtk::igeneric_function<T>
|
||||||
inc_func()
|
inc_func()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline T operator()(parameter_list_t& params)
|
inline T operator()(parameter_list_t params)
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < params.size(); ++i)
|
for (std::size_t i = 0; i < params.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -4596,6 +4631,35 @@ struct inc_func : public exprtk::igeneric_function<T>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct rem_space_and_uppercase : 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::string_view string_t;
|
||||||
|
|
||||||
|
rem_space_and_uppercase()
|
||||||
|
: exprtk::igeneric_function<T>("S")
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline T operator()(std::string& result, parameter_list_t params)
|
||||||
|
{
|
||||||
|
string_t string(params[0]);
|
||||||
|
|
||||||
|
result.reserve(string.size());
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
char c;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < string.size(); ++i)
|
||||||
|
{
|
||||||
|
if (' ' != (c = string[i]))
|
||||||
|
result += std::toupper(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return T(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool run_test18()
|
inline bool run_test18()
|
||||||
|
@ -4732,7 +4796,6 @@ inline bool run_test18()
|
||||||
|
|
||||||
static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
|
static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
|
||||||
|
|
||||||
|
|
||||||
bool failure = false;
|
bool failure = false;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < expression_list_size; ++i)
|
for (std::size_t i = 0; i < expression_list_size; ++i)
|
||||||
|
@ -4820,7 +4883,8 @@ inline bool run_test18()
|
||||||
"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(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(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('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');"
|
"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');",
|
||||||
|
"var z := 3; var w[3] := { 1/3, 1/5, 1/7 }; foo(s0[2:3]+s0[4: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);
|
static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
|
||||||
|
@ -4836,6 +4900,7 @@ inline bool run_test18()
|
||||||
"VSSVVT*" ,
|
"VSSVVT*" ,
|
||||||
"SSVVTTTTV",
|
"SSVVTTTTV",
|
||||||
"SVVTTTTVS",
|
"SVVTTTTVS",
|
||||||
|
"SVVTTTTVS",
|
||||||
};
|
};
|
||||||
|
|
||||||
bool failure = false;
|
bool failure = false;
|
||||||
|
@ -5001,6 +5066,110 @@ inline bool run_test18()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
bool failure = false;
|
||||||
|
|
||||||
|
rem_space_and_uppercase<T> rsauc;
|
||||||
|
|
||||||
|
std::string s0 = "XXXXXXXXXXXXXXX";
|
||||||
|
std::string s1 = "XXXXXXXXXXXXXXX";
|
||||||
|
std::string s2 = "XXXXXXXXXXXXXXX";
|
||||||
|
std::string s3 = "XXXXXXXXXXXXXXX";
|
||||||
|
std::string s4 = "XXXXXXXXXXXXXXX";
|
||||||
|
|
||||||
|
typedef exprtk::symbol_table<T> symbol_table_t;
|
||||||
|
typedef exprtk::expression<T> expression_t;
|
||||||
|
typedef exprtk::parser<T> parser_t;
|
||||||
|
|
||||||
|
symbol_table_t symbol_table;
|
||||||
|
|
||||||
|
symbol_table.add_constants();
|
||||||
|
|
||||||
|
symbol_table.add_stringvar("s0", s0);
|
||||||
|
symbol_table.add_stringvar("s1", s1);
|
||||||
|
symbol_table.add_stringvar("s2", s2);
|
||||||
|
symbol_table.add_stringvar("s3", s3);
|
||||||
|
symbol_table.add_stringvar("s4", s4);
|
||||||
|
|
||||||
|
symbol_table.add_function("remspc_uc",rsauc,symbol_table_t::e_ft_strfunc);
|
||||||
|
|
||||||
|
std::string program = " s0 := 'How now '; "
|
||||||
|
" s1 := 'brown cow?'; "
|
||||||
|
" s2 := remspc_uc(s0 + s1); "
|
||||||
|
" s3 := remspc_uc(s0) + s1; "
|
||||||
|
" s4 := s0 + remspc_uc(s1); "
|
||||||
|
" remspc_uc(s0 + s1) == remspc_uc(s0) + remspc_uc(s1);";
|
||||||
|
|
||||||
|
expression_t expression;
|
||||||
|
|
||||||
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
|
parser_t parser;
|
||||||
|
|
||||||
|
if (!parser.compile(program,expression))
|
||||||
|
{
|
||||||
|
printf("Error: %s\tExpression: %s\n",
|
||||||
|
parser.error().c_str(),
|
||||||
|
program.c_str());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
T result = expression.value();
|
||||||
|
|
||||||
|
if (result != T(1))
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (4) Expression: %s Result <> 1\n",
|
||||||
|
program.c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != T(1))
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (4) Expression: %s Check: s0\n",
|
||||||
|
program.c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("How now " != s0)
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (4) Expression: %s Check: s0\n",
|
||||||
|
program.c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("brown cow?" != s1)
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (4) Expression: %s Check: s1\n",
|
||||||
|
program.c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("HOWNOWBROWNCOW?" != s2)
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (4) Expression: %s Check: s2\n",
|
||||||
|
program.c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("HOWNOWbrown cow?" != s3)
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (4) Expression: %s Check: s3\n",
|
||||||
|
program.c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("How now BROWNCOW?" != s4)
|
||||||
|
{
|
||||||
|
printf("run_test18() - Error in evaluation! (4) Expression: %s Check: s4\n",
|
||||||
|
program.c_str());
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failure)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5139,9 +5308,9 @@ inline bool run_test19()
|
||||||
compositor
|
compositor
|
||||||
.add(
|
.add(
|
||||||
function_t("f6")
|
function_t("f6")
|
||||||
.expression("17 * (f5(x,y,z,w,u) + f5(y,z,w,u,v) + f5(z,w,u,v,x) + f5(w,u,v,x,y))")
|
|
||||||
.var("x").var("y").var("z")
|
.var("x").var("y").var("z")
|
||||||
.var("w").var("u").var("v"));
|
.var("w").var("u").var("v")
|
||||||
|
.expression("17 * (f5(x,y,z,w,u) + f5(y,z,w,u,v) + f5(z,w,u,v,x) + f5(w,u,v,x,y))"));
|
||||||
|
|
||||||
symbol_table_t& symbol_table = compositor.symbol_table();
|
symbol_table_t& symbol_table = compositor.symbol_table();
|
||||||
symbol_table.add_constants();
|
symbol_table.add_constants();
|
||||||
|
@ -5494,7 +5663,6 @@ inline bool run_test19()
|
||||||
" fibonacci5(x - 1) + fibonacci5(x - 2); ",
|
" fibonacci5(x - 1) + fibonacci5(x - 2); ",
|
||||||
"x");
|
"x");
|
||||||
|
|
||||||
|
|
||||||
symbol_table_t& symbol_table = compositor.symbol_table();
|
symbol_table_t& symbol_table = compositor.symbol_table();
|
||||||
symbol_table.add_constants();
|
symbol_table.add_constants();
|
||||||
symbol_table.add_variable("x",x);
|
symbol_table.add_variable("x",x);
|
||||||
|
|
104
readme.txt
104
readme.txt
|
@ -39,7 +39,7 @@ arithmetic operations, functions and processes:
|
||||||
(07) Assignment: :=, +=, -=, *=, /=, %=
|
(07) Assignment: :=, +=, -=, *=, /=, %=
|
||||||
|
|
||||||
(08) String
|
(08) String
|
||||||
processing: in, like, ilike
|
processing: in, like, ilike, concatenation
|
||||||
|
|
||||||
(09) Optimisations: constant-folding and simple strength reduction
|
(09) Optimisations: constant-folding and simple strength reduction
|
||||||
|
|
||||||
|
@ -409,6 +409,15 @@ of C++ compilers:
|
||||||
| | 5. x := '0123456789'[2i + 1:7] |
|
| | 5. x := '0123456789'[2i + 1:7] |
|
||||||
| | 6. x := (y := '0123456789'[2:7]) |
|
| | 6. x := (y := '0123456789'[2:7]) |
|
||||||
+----------+---------------------------------------------------------+
|
+----------+---------------------------------------------------------+
|
||||||
|
| + | Concatenation of x and y. Where x and y are strings or |
|
||||||
|
| | string ranges. eg |
|
||||||
|
| | 1. x + y |
|
||||||
|
| | 2. x + 'abc' |
|
||||||
|
| | 3. x + y[:i + j] |
|
||||||
|
| | 4. x[i:j] + y[2:3] + '0123456789'[2:7] |
|
||||||
|
| | 5. 'abc' + x + y |
|
||||||
|
| | 6. 'abc' + '1234567' |
|
||||||
|
+----------+---------------------------------------------------------+
|
||||||
| [] | The string size operator returns the size of the string |
|
| [] | The string size operator returns the size of the string |
|
||||||
| | being actioned. |
|
| | being actioned. |
|
||||||
| | eg: |
|
| | eg: |
|
||||||
|
@ -424,6 +433,8 @@ of C++ compilers:
|
||||||
| | eg: |
|
| | eg: |
|
||||||
| | 1. if(x, y, z) |
|
| | 1. if(x, y, z) |
|
||||||
| | 2. if((x + 1) > 2y, z + 1, w / v) |
|
| | 2. if((x + 1) > 2y, z + 1, w / v) |
|
||||||
|
| | 3. if(x > y) z; |
|
||||||
|
| | 4. if(x <= 2*y) { z + w }; |
|
||||||
+----------+---------------------------------------------------------+
|
+----------+---------------------------------------------------------+
|
||||||
| if-else | The if-else/else-if statement. Subject to the condition |
|
| if-else | The if-else/else-if statement. Subject to the condition |
|
||||||
| | branch the statement will return either the value of the|
|
| | branch the statement will return either the value of the|
|
||||||
|
@ -635,11 +646,13 @@ current values assigned to the variables will be used.
|
||||||
|
|
||||||
|
|
||||||
(2) Expression
|
(2) Expression
|
||||||
A structure that holds an AST for a specified expression and is used
|
A structure that holds an abstract syntax tree or AST for a specified
|
||||||
to evaluate said expression. If a compiled Expression uses variables
|
expression and is used to evaluate said expression. Evaluation of the
|
||||||
or user defined functions, it will then also have an associated Symbol
|
expression is accomplished by performing a post-order traversal of the
|
||||||
Table, which will contain references to said variables, functions et
|
AST. If a compiled Expression uses variables or user defined
|
||||||
al. An example AST structure for the denoted expression is as follows:
|
functions, it will have an associated Symbol Table, which will contain
|
||||||
|
references to said variables, functions or string. An example AST
|
||||||
|
structure for the denoted expression is as follows:
|
||||||
|
|
||||||
Expression: z := (x + y^-2.345) * sin(pi / min(w - 7.3,v))
|
Expression: z := (x + y^-2.345) * sin(pi / min(w - 7.3,v))
|
||||||
|
|
||||||
|
@ -1040,7 +1053,8 @@ There are two types of function interface:
|
||||||
(1) ifunction
|
(1) ifunction
|
||||||
(2) ivararg_function
|
(2) ivararg_function
|
||||||
(3) igeneric_function
|
(3) igeneric_function
|
||||||
(4) function_compositor
|
(4) igeneric_function II
|
||||||
|
(5) function_compositor
|
||||||
|
|
||||||
|
|
||||||
(1) ifunction
|
(1) ifunction
|
||||||
|
@ -1112,7 +1126,7 @@ called 'too':
|
||||||
too()
|
too()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline T operator()(parameter_list_t& parameters)
|
inline T operator()(parameter_list_t parameters)
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < parameters.size(); ++i)
|
for (std::size_t i = 0; i < parameters.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -1142,7 +1156,7 @@ are three type enumerations:
|
||||||
Each of the parameters can be accessed using its designated view. A
|
Each of the parameters can be accessed using its designated view. A
|
||||||
typical loop for processing the parameters is as follows:
|
typical loop for processing the parameters is as follows:
|
||||||
|
|
||||||
inline T operator()(parameter_list_t& parameters)
|
inline T operator()(parameter_list_t parameters)
|
||||||
{
|
{
|
||||||
typedef typename exprtk::igeneric_function<T>::generic_type
|
typedef typename exprtk::igeneric_function<T>::generic_type
|
||||||
generic_type;
|
generic_type;
|
||||||
|
@ -1199,7 +1213,7 @@ achieved:
|
||||||
: exprtk::igeneric_function<T>("SVTT")
|
: exprtk::igeneric_function<T>("SVTT")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline T operator()(parameter_list_t& parameters)
|
inline T operator()(parameter_list_t parameters)
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
@ -1230,7 +1244,7 @@ definition.
|
||||||
: exprtk::igeneric_function<T>("SVTTV*")
|
: exprtk::igeneric_function<T>("SVTTV*")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline T operator()(parameter_list_t& parameters)
|
inline T operator()(parameter_list_t parameters)
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
@ -1247,7 +1261,64 @@ parameters in the following sequence:
|
||||||
(e) One or more vectors
|
(e) One or more vectors
|
||||||
|
|
||||||
|
|
||||||
(4) function_compositor
|
(4) igeneric_function II
|
||||||
|
This interface is identical to the igeneric_function, in that in can
|
||||||
|
consume an arbitrary number of parameters of varying type, but the
|
||||||
|
difference being that the function returns a string and as such is
|
||||||
|
treated as a string when invoked within expressions. As a result the
|
||||||
|
function call can alias a string and interact with other strings in
|
||||||
|
situations such as concatenation and equality operations.
|
||||||
|
|
||||||
|
The following example defines an generic function named 'toupper' with
|
||||||
|
the string return type function operator being explicitly overriden:
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct toupper : public exprtk::igeneric_function<T>
|
||||||
|
{
|
||||||
|
typedef exprtk::igeneric_function<T> igenfunct_t
|
||||||
|
typedef typename igenfunct_t::generic_type generic_t;
|
||||||
|
typedef typename igenfunct_t::parameter_list_t parameter_list_t;
|
||||||
|
typedef typename generic_t::string_view string_t;
|
||||||
|
|
||||||
|
toupper()
|
||||||
|
: exprtk::igeneric_function<T>("S")
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline T operator()(std::string& result,
|
||||||
|
parameter_list_t parameters)
|
||||||
|
{
|
||||||
|
result.clear();
|
||||||
|
for (std::size_t i = 0; i < string.size(); ++i)
|
||||||
|
{
|
||||||
|
result += std::toupper(string[i]);
|
||||||
|
}
|
||||||
|
return T(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
In the example above the generic function 'toupper' expects only one
|
||||||
|
input parameter of type string, as noted by the parameter sequence
|
||||||
|
string passed during the constructor. When executed, the function will
|
||||||
|
return as a result a copy of the input string converted to uppercase
|
||||||
|
form.
|
||||||
|
|
||||||
|
When adding a string type returning generic function to a symbol
|
||||||
|
table, the 'add_function' is invoked with an extra parameter
|
||||||
|
(e_ft_strfunc) that denotes the function should be treated as a string
|
||||||
|
returning function type. The following example demonstrates how this
|
||||||
|
is done:
|
||||||
|
|
||||||
|
toupper<T> tu;
|
||||||
|
|
||||||
|
exprtk::symbol_table<T> symbol_table;
|
||||||
|
|
||||||
|
symbol_table.add_function("toupper",
|
||||||
|
tu,
|
||||||
|
symbol_table_t::e_ft_strfunc);
|
||||||
|
|
||||||
|
|
||||||
|
(5) 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.
|
||||||
|
@ -1296,6 +1367,7 @@ The following demonstrates how all the pieces are put together:
|
||||||
foo<double> f;
|
foo<double> f;
|
||||||
boo<double> b;
|
boo<double> b;
|
||||||
too<double> t;
|
too<double> t;
|
||||||
|
toupper<double> tu;
|
||||||
|
|
||||||
symbol_table_t symbol_table;
|
symbol_table_t symbol_table;
|
||||||
compositor_t compositor(symbol_table);
|
compositor_t compositor(symbol_table);
|
||||||
|
@ -1304,6 +1376,10 @@ The following demonstrates how all the pieces are put together:
|
||||||
symbol_table.add_function("boo",b);
|
symbol_table.add_function("boo",b);
|
||||||
symbol_table.add_function("too",t);
|
symbol_table.add_function("too",t);
|
||||||
|
|
||||||
|
symbol_table.add_function("toupper",
|
||||||
|
tu,
|
||||||
|
symbol_table_t::e_ft_strfunc);
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add(function_t()
|
.add(function_t()
|
||||||
.name("koo")
|
.name("koo")
|
||||||
|
@ -1523,8 +1599,8 @@ into account when using Exprtk:
|
||||||
eg: 'Frankly my dear, 1 do n0t give a damn!'
|
eg: 'Frankly my dear, 1 do n0t give a damn!'
|
||||||
|
|
||||||
(14) User defined normal functions can have up to 20 parameters,
|
(14) User defined normal functions can have up to 20 parameters,
|
||||||
where as user defined vararg-functions can have an unlimited
|
where as user defined generic-functions and vararg-functions
|
||||||
number of parameters.
|
can have an unlimited number of parameters.
|
||||||
|
|
||||||
(15) The inbuilt polynomial functions can be at most of degree 12.
|
(15) The inbuilt polynomial functions can be at most of degree 12.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue