C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
b6cdf0d2f9
commit
1d757d5718
1110
exprtk.hpp
1110
exprtk.hpp
File diff suppressed because it is too large
Load Diff
202
exprtk_test.cpp
202
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 rounds = 60;
|
||||
|
||||
for (std::size_t r = 0; r < rounds; ++r)
|
||||
|
@ -2047,15 +2046,47 @@ inline bool run_test02()
|
|||
test_ab<T>("{[('!@#$%^&*([{}])-=')]} == [{('!@#$%^&*([{}])-=')}]","","",T(1.0)),
|
||||
test_ab<T>("'1234\\\\abc\nxyz\r890\tqaz\\'567' == a","1234\\abc\nxyz\r890\tqaz'567","",T(1.0)),
|
||||
test_ab<T>("a == '1234\\\\abc\nxyz\r890\tqaz\\'567'","1234\\abc\nxyz\r890\tqaz'567","",T(1.0)),
|
||||
test_ab<T>("'123'[] == 3" ,"","",T(1.0)),
|
||||
test_ab<T>("3 == '123'[]" ,"","",T(1.0)),
|
||||
test_ab<T>("'123'[] + '1234'[] == 7" ,"","",T(1.0)),
|
||||
test_ab<T>("abs('123'[] - '1234'[]) == 1" ,"","",T(1.0)),
|
||||
test_ab<T>("'1234'[] == a[]" ,"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>("'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>("'123'[] == 3" ,"","" ,T(1.0)),
|
||||
test_ab<T>("3 == '123'[]" ,"","" ,T(1.0)),
|
||||
test_ab<T>("'123'[] + '1234'[] == 7" ,"","" ,T(1.0)),
|
||||
test_ab<T>("abs('123'[] - '1234'[]) == 1" ,"","" ,T(1.0)),
|
||||
test_ab<T>("'1234'[] == a[]" ,"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>("'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>("(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>);
|
||||
|
@ -2074,6 +2105,8 @@ inline bool run_test02()
|
|||
|
||||
T r0 = T(2);
|
||||
T r1 = T(6);
|
||||
T r2 = T(7);
|
||||
T r3 = T(3);
|
||||
|
||||
exprtk::symbol_table<T> symbol_table;
|
||||
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_variable ("r0", r0);
|
||||
symbol_table.add_variable ("r1", r1);
|
||||
symbol_table.add_variable ("r2", r2);
|
||||
symbol_table.add_variable ("r3", r3);
|
||||
|
||||
exprtk::expression<T> expression;
|
||||
expression.register_symbol_table(symbol_table);
|
||||
|
@ -4490,7 +4525,7 @@ struct gen_func : public exprtk::igeneric_function<T>
|
|||
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)
|
||||
{
|
||||
|
@ -4556,7 +4591,7 @@ struct inc_func : public exprtk::igeneric_function<T>
|
|||
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)
|
||||
{
|
||||
|
@ -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>
|
||||
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);
|
||||
|
||||
|
||||
bool failure = false;
|
||||
|
||||
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(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');"
|
||||
"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);
|
||||
|
@ -4836,6 +4900,7 @@ inline bool run_test18()
|
|||
"VSSVVT*" ,
|
||||
"SSVVTTTTV",
|
||||
"SVVTTTTVS",
|
||||
"SVVTTTTVS",
|
||||
};
|
||||
|
||||
bool failure = false;
|
||||
|
@ -5001,6 +5066,110 @@ inline bool run_test18()
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -5139,9 +5308,9 @@ inline bool run_test19()
|
|||
compositor
|
||||
.add(
|
||||
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("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.add_constants();
|
||||
|
@ -5494,7 +5663,6 @@ inline bool run_test19()
|
|||
" fibonacci5(x - 1) + fibonacci5(x - 2); ",
|
||||
"x");
|
||||
|
||||
|
||||
symbol_table_t& symbol_table = compositor.symbol_table();
|
||||
symbol_table.add_constants();
|
||||
symbol_table.add_variable("x",x);
|
||||
|
|
104
readme.txt
104
readme.txt
|
@ -39,7 +39,7 @@ arithmetic operations, functions and processes:
|
|||
(07) Assignment: :=, +=, -=, *=, /=, %=
|
||||
|
||||
(08) String
|
||||
processing: in, like, ilike
|
||||
processing: in, like, ilike, concatenation
|
||||
|
||||
(09) Optimisations: constant-folding and simple strength reduction
|
||||
|
||||
|
@ -409,6 +409,15 @@ of C++ compilers:
|
|||
| | 5. x := '0123456789'[2i + 1: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 |
|
||||
| | being actioned. |
|
||||
| | eg: |
|
||||
|
@ -424,6 +433,8 @@ of C++ compilers:
|
|||
| | eg: |
|
||||
| | 1. if(x, y, z) |
|
||||
| | 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 |
|
||||
| | 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
|
||||
A structure that holds an AST for a specified expression and is used
|
||||
to evaluate said expression. If a compiled Expression uses variables
|
||||
or user defined functions, it will then also have an associated Symbol
|
||||
Table, which will contain references to said variables, functions et
|
||||
al. An example AST structure for the denoted expression is as follows:
|
||||
A structure that holds an abstract syntax tree or AST for a specified
|
||||
expression and is used to evaluate said expression. Evaluation of the
|
||||
expression is accomplished by performing a post-order traversal of the
|
||||
AST. If a compiled Expression uses variables or user defined
|
||||
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))
|
||||
|
||||
|
@ -1040,7 +1053,8 @@ There are two types of function interface:
|
|||
(1) ifunction
|
||||
(2) ivararg_function
|
||||
(3) igeneric_function
|
||||
(4) function_compositor
|
||||
(4) igeneric_function II
|
||||
(5) function_compositor
|
||||
|
||||
|
||||
(1) ifunction
|
||||
|
@ -1112,7 +1126,7 @@ called '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)
|
||||
{
|
||||
|
@ -1142,7 +1156,7 @@ are three type enumerations:
|
|||
Each of the parameters can be accessed using its designated view. A
|
||||
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
|
||||
generic_type;
|
||||
|
@ -1199,7 +1213,7 @@ achieved:
|
|||
: 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*")
|
||||
{}
|
||||
|
||||
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
|
||||
|
||||
|
||||
(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
|
||||
using ExprTk syntax. The functions are limited to returning a single
|
||||
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;
|
||||
boo<double> b;
|
||||
too<double> t;
|
||||
toupper<double> tu;
|
||||
|
||||
symbol_table_t 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("too",t);
|
||||
|
||||
symbol_table.add_function("toupper",
|
||||
tu,
|
||||
symbol_table_t::e_ft_strfunc);
|
||||
|
||||
compositor
|
||||
.add(function_t()
|
||||
.name("koo")
|
||||
|
@ -1523,8 +1599,8 @@ into account when using Exprtk:
|
|||
eg: 'Frankly my dear, 1 do n0t give a damn!'
|
||||
|
||||
(14) User defined normal functions can have up to 20 parameters,
|
||||
where as user defined vararg-functions can have an unlimited
|
||||
number of parameters.
|
||||
where as user defined generic-functions and vararg-functions
|
||||
can have an unlimited number of parameters.
|
||||
|
||||
(15) The inbuilt polynomial functions can be at most of degree 12.
|
||||
|
||||
|
|
Loading…
Reference in New Issue