C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html

This commit is contained in:
ArashPartow 2020-01-01 10:46:31 +11:00
parent e0e880c379
commit 5d7e5f21c2
25 changed files with 2108 additions and 1083 deletions

View File

@ -1,4 +1,4 @@
dist: xenial
dist: bionic
language: cpp

View File

@ -2,7 +2,7 @@
# **************************************************************
# * C++ Mathematical Expression Toolkit Library *
# * *
# * Author: Arash Partow (1999-2019) *
# * Author: Arash Partow (1999-2020) *
# * URL: http://www.partow.net/programming/exprtk/index.html *
# * *
# * Copyright notice: *

2434
exprtk.hpp

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* ExprTk vs Native Benchmarks *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 1 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -29,7 +29,8 @@ void trig_function()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string expression_string = "clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)";
const std::string expression_string =
"clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)";
T x;
@ -45,8 +46,8 @@ void trig_function()
for (x = T(-5); x <= T(+5); x += T(0.001))
{
T y = expression.value();
printf("%19.15f\t%19.15f\n",x,y);
const T y = expression.value();
printf("%19.15f\t%19.15f\n", x, y);
}
}

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 2 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -29,14 +29,15 @@ void square_wave()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string expr_string = "a*(4/pi)*"
"((1 /1)*sin( 2*pi*f*t)+(1 /3)*sin( 6*pi*f*t)+"
" (1 /5)*sin(10*pi*f*t)+(1 /7)*sin(14*pi*f*t)+"
" (1 /9)*sin(18*pi*f*t)+(1/11)*sin(22*pi*f*t)+"
" (1/13)*sin(26*pi*f*t)+(1/15)*sin(30*pi*f*t)+"
" (1/17)*sin(34*pi*f*t)+(1/19)*sin(38*pi*f*t)+"
" (1/21)*sin(42*pi*f*t)+(1/23)*sin(46*pi*f*t)+"
" (1/25)*sin(50*pi*f*t)+(1/27)*sin(54*pi*f*t))";
const std::string expr_string =
"a*(4/pi)*"
"((1 /1)*sin( 2*pi*f*t)+(1 /3)*sin( 6*pi*f*t)+"
" (1 /5)*sin(10*pi*f*t)+(1 /7)*sin(14*pi*f*t)+"
" (1 /9)*sin(18*pi*f*t)+(1/11)*sin(22*pi*f*t)+"
" (1/13)*sin(26*pi*f*t)+(1/15)*sin(30*pi*f*t)+"
" (1/17)*sin(34*pi*f*t)+(1/19)*sin(38*pi*f*t)+"
" (1/21)*sin(42*pi*f*t)+(1/23)*sin(46*pi*f*t)+"
" (1/25)*sin(50*pi*f*t)+(1/27)*sin(54*pi*f*t))";
static const T pi = T(3.141592653589793238462643383279502);
@ -60,8 +61,8 @@ void square_wave()
for (t = (T(-2) * pi); t <= (T(+2) * pi); t += delta)
{
T result = expression.value();
printf("%19.15f\t%19.15f\n",t,result);
const T result = expression.value();
printf("%19.15f\t%19.15f\n", t, result);
}
}

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 3 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -29,7 +29,8 @@ void polynomial()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string expression_string = "25x^5 - 35x^4 - 15x^3 + 40x^2 - 15x + 1";
const std::string expression_string =
"25x^5 - 35x^4 - 15x^3 + 40x^2 - 15x + 1";
const T r0 = T(0);
const T r1 = T(1);
@ -48,7 +49,7 @@ void polynomial()
for (x = r0; x <= r1; x += delta)
{
printf("%19.15f\t%19.15f\n",x,expression.value());
printf("%19.15f\t%19.15f\n", x, expression.value());
}
}

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 4 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -73,7 +73,7 @@ void fibonacci()
{
x = static_cast<T>(i);
T result = expression.value();
const T result = expression.value();
printf("fibonacci(%3d) = %10.0f\n",
static_cast<int>(i),

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 5 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -50,7 +50,7 @@ void custom_function()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string expression_string =
const std::string expression_string =
"myfunc(sin(x / pi), otherfunc(3 * y, x / 2, x * y))";
T x = T(1);
@ -70,7 +70,7 @@ void custom_function()
parser_t parser;
parser.compile(expression_string,expression);
T result = expression.value();
const T result = expression.value();
printf("Result: %10.5f\n",result);
}

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 6 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -29,7 +29,7 @@ void vector_function()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string expression_string =
const std::string expression_string =
" for (var i := 0; i < min(x[],y[],z[]); i += 1) "
" { "
" z[i] := 3sin(x[i]) + 2log(y[i]); "

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 7 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -29,7 +29,7 @@ void logic()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string expression_string = "not(A and B) or C";
const std::string expression_string = "not(A and B) or C";
symbol_table_t symbol_table;
symbol_table.create_variable("A");
@ -53,7 +53,7 @@ void logic()
symbol_table.get_variable("B")->ref() = T((i & 0x02) ? 1 : 0);
symbol_table.get_variable("C")->ref() = T((i & 0x04) ? 1 : 0);
int result = static_cast<int>(expression.value());
const int result = static_cast<int>(expression.value());
printf(" %d | %d | %d | %d | %d \n",
i,

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 8 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -65,7 +65,7 @@ void composite()
for (std::size_t i = 0; i < parser.error_count(); ++i)
{
err_t error = parser.get_error(i);
const err_t error = parser.get_error(i);
printf("Error: %02d Position: %02d Type: [%14s] Msg: %s\tExpression: %s\n",
static_cast<unsigned int>(i),
@ -78,7 +78,7 @@ void composite()
return;
}
T result = expression.value();
const T result = expression.value();
printf("%s = %e\n", expression_string.c_str(), result);
}

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 9 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -133,9 +133,9 @@ void primes()
{
x = static_cast<T>(i);
T result1 = expression1.value();
T result2 = expression2.value();
T result3 = expression3.value();
const T result1 = expression1.value();
const T result2 = expression2.value();
const T result3 = expression3.value();
printf("%03d Result1: %c Result2: %c Result3: %c\n",
static_cast<unsigned int>(i),

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 10 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -64,7 +64,7 @@ void newton_sqrt()
" } ",
"x"));
std::string expression_str = "newton_sqrt(x)";
const std::string expression_str = "newton_sqrt(x)";
expression_t expression;
expression.register_symbol_table(symbol_table);
@ -76,7 +76,7 @@ void newton_sqrt()
{
x = static_cast<T>(i);
T result = expression.value();
const T result = expression.value();
printf("sqrt(%03d) - Result: %15.13f\tReal: %15.13f\n",
static_cast<unsigned int>(i),

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 11 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -29,7 +29,7 @@ void square_wave2()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string wave_program =
const std::string wave_program =
" var r := 0; "
" for (var i := 0; i < 1000; i += 1) "
" { "
@ -59,8 +59,8 @@ void square_wave2()
for (t = (T(-2) * pi); t <= (T(+2) * pi); t += delta)
{
T result = expression.value();
printf("%19.15f\t%19.15f\n",t,result);
const T result = expression.value();
printf("%19.15f\t%19.15f\n", t, result);
}
}

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 12 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -29,7 +29,7 @@ void bubble_sort()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string bubblesort_program =
const std::string bubblesort_program =
" var upper_bound := v[]; "
" var swapped := false; "
" repeat "

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 13 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -31,7 +31,7 @@ void savitzky_golay_filter()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string sgfilter_program =
const std::string sgfilter_program =
" var weight[9] := "
" { "
" -21, 14, 39, "
@ -89,7 +89,7 @@ void savitzky_golay_filter()
for (std::size_t i = 0; i < v_out.size(); ++i)
{
printf("%10.6f\t%10.6f\n",v_in[i],v_out[i]);
printf("%10.6f\t%10.6f\n", v_in[i], v_out[i]);
}
}

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 14 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -28,7 +28,7 @@ void stddev_example()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string stddev_program =
const std::string stddev_program =
" var x[25] := { "
" 1, 2, 3, 4, 5, "
" 6, 7, 8, 9, 10, "
@ -44,7 +44,7 @@ void stddev_example()
parser_t parser;
parser.compile(stddev_program,expression);
T stddev = expression.value();
const T stddev = expression.value();
printf("stddev(1..25) = %10.6f\n",stddev);
}

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 15 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -29,7 +29,7 @@ void black_scholes_merton_model()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string bsm_model_program =
const std::string bsm_model_program =
" var d1 := (log(s / x) + (r + v^2 / 2) * t) / (v * sqrt(t)); "
" var d2 := d1 - v * sqrt(t); "
" "
@ -71,7 +71,7 @@ void black_scholes_merton_model()
printf("BSM(%s,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f) = %10.6f\n",
callput_flag.c_str(),
s,x,t,r,v,
s, x, t, r, v,
bsm);
}
@ -82,7 +82,7 @@ void black_scholes_merton_model()
printf("BSM(%s,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f) = %10.6f\n",
callput_flag.c_str(),
s,x,t,r,v,
s, x, t, r, v,
bsm);
}
}

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 16 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -30,7 +30,7 @@ void linear_least_squares()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string linear_least_squares_program =
const std::string linear_least_squares_program =
" if (x[] == y[]) "
" { "
" beta := (sum(x * y) - sum(x) * sum(y) / x[]) / "

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 17 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -47,7 +47,7 @@ void monte_carlo_pi()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string monte_carlo_pi_program =
const std::string monte_carlo_pi_program =
" var experiments[5 * 10^7] := [(rnd_01^2 + rnd_01^2) <= 1]; "
" 4 * sum(experiments) / experiments[]; ";

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 18 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -29,7 +29,7 @@ void file_io()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string fileio_program =
const std::string fileio_program =
" var file_name := 'file.txt'; "
" var stream := null; "
" "

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 19 *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -55,7 +55,7 @@ public:
if (
(1 == ps_index) &&
!exprtk::rtl::vecops::helper::
load_vector_range<T>::process(parameters,r0,r1,1,2,0)
load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
)
return T(0);
@ -84,7 +84,7 @@ void vector_randu()
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::string vecrandu_program =
const std::string vecrandu_program =
" var noise[6] := [0]; "
" "
" if (randu(noise,0,5) == false) "

View File

@ -3,7 +3,7 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Examples and Unit-Tests *
* Author: Arash Partow (1999-2019) *
* Author: Arash Partow (1999-2020) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@ -23,6 +23,7 @@
#include <deque>
#include <fstream>
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
@ -2839,7 +2840,14 @@ inline bool run_test03()
"1+-+-+",
"1===",
"1====",
"[*][*][*][*][*]"
"[*][*][*][*][*]",
"var v[1] := {}; var s0appe0 := false; repeat s0appe0 false for(){(){}}",
"var v[2] := {}; repeat var s0appe0 := false; s0appe0 false for(){(){}}",
"var v[3] := {}; repeat var s0appe0 := false; for(){(){}} s0appe0 false",
"var v[4] := {}; repeat var s0appe0 := false; s0appe0 for(){(){}} false",
"var v[5] := {}; repeat for(){(){}} var s0appe0 := false; s0appe0 false",
"var v{};v ;v 60;v 60;v o5"
};
const std::size_t invalid_expr_size = sizeof(invalid_expr) / sizeof(std::string);
@ -4242,6 +4250,62 @@ inline bool run_test10()
}
}
{
const std::string expression =
"for (var i := 0; i < min(x[],y[],z[]); i += 1)"
"{ z[i] := 3sin(x[i]) + 2log(y[i]); }";
std::vector<std::string> var_symbol_list;
std::vector<std::string> func_symbol_list;
if (!exprtk::collect_variables(expression, var_symbol_list))
{
printf("run_test10() - Failed to collect variables.\n");
return false;
}
if (!exprtk::collect_functions(expression, func_symbol_list))
{
printf("run_test10() - Failed to collect functions.\n");
return false;
}
std::sort(var_symbol_list .begin(), var_symbol_list .end());
std::sort(func_symbol_list.begin(), func_symbol_list.end());
std::vector<std::string> expected_var_symbol_list;
std::vector<std::string> expected_func_symbol_list;
expected_var_symbol_list.push_back("i");
expected_var_symbol_list.push_back("x");
expected_var_symbol_list.push_back("y");
expected_var_symbol_list.push_back("z");
expected_func_symbol_list.push_back("log");
expected_func_symbol_list.push_back("min");
expected_func_symbol_list.push_back("sin");
const bool var_result = (var_symbol_list.size() == expected_var_symbol_list.size()) &&
std::equal(var_symbol_list.begin(),
var_symbol_list.end(),
expected_var_symbol_list.begin());
if (!var_result)
{
printf("run_test10() - Failed collected variable comparison between recieved and expected variables\n");
return false;
}
const bool func_result = (func_symbol_list.size() == expected_func_symbol_list.size()) &&
std::equal(func_symbol_list.begin(),
func_symbol_list.end(),
expected_func_symbol_list.begin());
if (!func_result)
{
printf("run_test10() - Failed collected fuctions comparison between recieved and expected functions\n");
return false;
}
}
{
std::string expression_list[] =
{
@ -5746,6 +5810,109 @@ struct vararg_func : public exprtk::igeneric_function<T>
}
};
template <typename T>
struct vecrebase_func : public exprtk::igeneric_function<T>
{
typedef typename exprtk::igeneric_function<T>::parameter_list_t
parameter_list_t;
typedef typename exprtk::igeneric_function<T>::generic_type
generic_type;
typedef typename generic_type::vector_view vector_t;
using exprtk::igeneric_function<T>::operator();
vecrebase_func()
: exprtk::igeneric_function<T>("V")
{}
inline T operator()(parameter_list_t params)
{
vector_t v(params[0]);
return std::accumulate(v.begin(), v.end(), T(0));
}
};
template <typename T>
struct overload_func : exprtk::igeneric_function<T>
{
typedef typename exprtk::igeneric_function<T> igfun_t;
typedef typename igfun_t::parameter_list_t parameter_list_t;
typedef typename igfun_t::generic_type generic_type;
typedef typename generic_type::vector_view vector_t;
using exprtk::igeneric_function<T>::operator();
overload_func(const std::string& param_seq_list)
: exprtk::igeneric_function<T>(param_seq_list, igfun_t::e_rtrn_overload),
current_ps_index(std::numeric_limits<std::size_t>::max())
{
clear();
}
void clear()
{
current_ps_index = std::numeric_limits<std::size_t>::max();
current_param_seq = "";
}
inline T operator()(const std::size_t& ps_index,
parameter_list_t parameters)
{
current_ps_index = ps_index;
determine_param_seq(parameters);
return T(1);
}
inline T operator()(const std::size_t& ps_index,
std::string& result,
parameter_list_t parameters)
{
current_ps_index = ps_index;
determine_param_seq(parameters);
result = "string result";
return T(1);
}
void determine_param_seq(parameter_list_t parameters)
{
current_param_seq = "";
for (std::size_t i = 0; i < parameters.size(); ++i)
{
generic_type& gt = parameters[i];
switch (gt.type)
{
case generic_type::e_scalar : current_param_seq += "T";
break;
case generic_type::e_vector : current_param_seq += "V";
break;
case generic_type::e_string : current_param_seq += "S";
break;
default : continue;
}
}
}
std::size_t current_ps_index;
std::string current_param_seq;
struct test_result_t
{
test_result_t(const std::size_t psi, const std::string& ps)
: ps_index(psi),
param_seq(ps)
{}
std::size_t ps_index;
std::string param_seq;
};
};
template <typename T>
inline bool run_test18()
@ -6684,6 +6851,68 @@ inline bool run_test18()
return false;
}
{
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
T v0[] = { T(0), T(1), T(2), T(3), T(4) };
T v1[] = { T(5), T(6), T(7), T(8), T(9) };
const std::size_t v0_size = sizeof(v0) / sizeof (T);
const std::size_t v1_size = sizeof(v1) / sizeof (T);
exprtk::vector_view<T> v = exprtk::make_vector_view(v0, v0_size);
vecrebase_func<T> vec_sum;
symbol_table_t symbol_table;
symbol_table.add_vector("v",v);
symbol_table.add_function("vec_sum",vec_sum);
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
const std::string expr_string = "vec_sum(v)";
if (!parser.compile(expr_string,expression))
{
printf("run_test18() - Error: %s\tExpression: %s\n",
parser.error().c_str(),
expr_string.c_str());
return false;
}
const T expected_result0 = std::accumulate(v0, v0 + v0_size,T(0));
if (expression.value() != expected_result0)
{
printf("run_test18() - Error in evaluation! (10.1) Expression: %s Expected: %5.3f Computed: %5.3f\n",
expr_string.c_str(),
expected_result0,
expression.value());
return false;
}
v.rebase(v1);
const T expected_result1 = std::accumulate(v1, v1 + v1_size,T(0));
if (expression.value() != expected_result1)
{
printf("run_test18() - Error in evaluation! (10.2) Expression: %s Expected: %5.3f Computed: %5.3f\n",
expr_string.c_str(),
expected_result1,
expression.value());
return false;
}
}
{
bool failure = false;
@ -6816,7 +7045,7 @@ inline bool run_test18()
if (result != T(1))
{
printf("run_test18() - Error in evaluation! (10) Expression: %s\n",
printf("run_test18() - Error in evaluation! (11) Expression: %s\n",
expr_str_list[i].c_str());
failure = true;
@ -6827,6 +7056,295 @@ inline bool run_test18()
return false;
}
{
typedef exprtk::expression<T> expression_t;
std::string a = "a";
std::string b = "b";
std::string c = "c";
std::string d = "d";
T x = T(1.1);
T y = T(2.2);
T z = T(3.3);
T w = T(4.4);
overload_func<T> ovrld_func
(
"T:T|T:TT|T:TTT|T:TTTT|"
"T:S|T:SS|T:SSS|T:SSSS|"
"T:ST|T:STS|T:STST|"
"T:TS|T:TST|T:TSTS|"
"T:TTSS|T:SSTT|T:STTS|T:TSST"
);
exprtk::symbol_table<T> symbol_table;
symbol_table.add_constants();
symbol_table.add_variable ("x",x);
symbol_table.add_variable ("y",y);
symbol_table.add_variable ("z",z);
symbol_table.add_variable ("w",w);
symbol_table.add_stringvar("a",a);
symbol_table.add_stringvar("b",b);
symbol_table.add_stringvar("c",c);
symbol_table.add_stringvar("d",d);
symbol_table.add_function("foo",ovrld_func);
typedef typename overload_func<T>::test_result_t test_result_t;
typedef std::pair<std::string, typename overload_func<T>::test_result_t> test_pack_t;
static const test_pack_t test_pack_list[] =
{
test_pack_t("foo(x)" , test_result_t( 0, "T" )),
test_pack_t("foo(x, y)" , test_result_t( 1, "TT" )),
test_pack_t("foo(x, y, z)" , test_result_t( 2, "TTT" )),
test_pack_t("foo(x, y, z, w)" , test_result_t( 3, "TTTT")),
test_pack_t("foo(x + y)" , test_result_t( 0, "T" )),
test_pack_t("foo(x + y, y + z)" , test_result_t( 1, "TT" )),
test_pack_t("foo(x + y, y + z, z + w)" , test_result_t( 2, "TTT" )),
test_pack_t("foo(x + y, y + z, z + w, w)" , test_result_t( 3, "TTTT")),
test_pack_t("foo(a)" , test_result_t( 4, "S" )),
test_pack_t("foo(a, b)" , test_result_t( 5, "SS" )),
test_pack_t("foo(a, b, c)" , test_result_t( 6, "SSS" )),
test_pack_t("foo(a, b, c, d)" , test_result_t( 7, "SSSS")),
test_pack_t("foo(a + b)" , test_result_t( 4, "S" )),
test_pack_t("foo(a + b, b + c)" , test_result_t( 5, "SS" )),
test_pack_t("foo(a + b, b + c, c + d)" , test_result_t( 6, "SSS" )),
test_pack_t("foo(a + b, b + c, c + d, d)" , test_result_t( 7, "SSSS")),
test_pack_t("foo(a, x)" , test_result_t( 8, "ST" )),
test_pack_t("foo(a, x, b)" , test_result_t( 9, "STS" )),
test_pack_t("foo(a, x, b, y)" , test_result_t(10, "STST")),
test_pack_t("foo(a + b, x + y)" , test_result_t( 8, "ST" )),
test_pack_t("foo(a + b, x + y, b + c)" , test_result_t( 9, "STS" )),
test_pack_t("foo(a + b, x + y, b + c, y + z)" , test_result_t(10, "STST")),
test_pack_t("foo(x, a)" , test_result_t(11, "TS" )),
test_pack_t("foo(x, a, y)" , test_result_t(12, "TST" )),
test_pack_t("foo(x, a, y, b)" , test_result_t(13, "TSTS")),
test_pack_t("foo(x + y, a + b)" , test_result_t(11, "TS" )),
test_pack_t("foo(x + y, a + b, y + z)" , test_result_t(12, "TST" )),
test_pack_t("foo(x + y, a + b, y + z, b + c)" , test_result_t(13, "TSTS")),
test_pack_t("foo(x, y, a, b)" , test_result_t(14, "TTSS")),
test_pack_t("foo(a, b, x, y)" , test_result_t(15, "SSTT")),
test_pack_t("foo(a, x, y, b)" , test_result_t(16, "STTS")),
test_pack_t("foo(x, a, b, y)" , test_result_t(17, "TSST")),
test_pack_t("foo(x + y, y + z, a + b, b + c)" , test_result_t(14, "TTSS")),
test_pack_t("foo(a + b, b + c, x + y, y + z)" , test_result_t(15, "SSTT")),
test_pack_t("foo(a + b, x + y, y + z, b + c)" , test_result_t(16, "STTS")),
test_pack_t("foo(x + y, a + b, b + c, y + z)" , test_result_t(17, "TSST"))
};
static const std::size_t test_pack_list_size = sizeof(test_pack_list) / sizeof(test_pack_t);
std::deque<expression_t> expression_list;
for (std::size_t i = 0; i < test_pack_list_size; ++i)
{
expression_t expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
if (!parser.compile(test_pack_list[i].first, expression))
{
printf("run_test18() - (12) Overload VarArg Error: %s Expression: %s\n",
parser.error().c_str(),
test_pack_list[i].first.c_str());
return false;
}
else
expression_list.push_back(expression);
}
bool failure = false;
for (std::size_t i = 0; i < expression_list.size(); ++i)
{
ovrld_func.clear();
if (T(1) != expression_list[i].value())
{
printf("run_test18() - Error in evaluation! (12) Expression: %s\n",
test_pack_list[i].first.c_str());
failure = true;
}
if (ovrld_func.current_ps_index != test_pack_list[i].second.ps_index)
{
printf("run_test18() - Error with ps_index (12) Expression: %s Expected: %d Got: %d\n",
test_pack_list[i].first.c_str(),
static_cast<int>(test_pack_list[i].second.ps_index),
static_cast<int>(ovrld_func.current_ps_index));
failure = true;
}
if (ovrld_func.current_param_seq != test_pack_list[i].second.param_seq)
{
printf("run_test18() - Error with parameter seq (12) Expression: %s Expected: %s Got: %s\n",
test_pack_list[i].first.c_str(),
test_pack_list[i].second.param_seq.c_str(),
ovrld_func.current_param_seq.c_str());
failure = true;
}
::fflush(stdout);
}
if (failure)
return false;
}
{
typedef exprtk::expression<T> expression_t;
std::string a = "a";
std::string b = "b";
std::string c = "c";
std::string d = "d";
std::string result = "";
T x = T(1.1);
T y = T(2.2);
T z = T(3.3);
T w = T(4.4);
overload_func<T> ovrld_func
(
"S:T|S:TT|S:TTT|S:TTTT|"
"S:S|S:SS|S:SSS|S:SSSS|"
"S:ST|S:STS|S:STST|"
"S:TS|S:TST|S:TSTS|"
"S:TTSS|S:SSTT|S:STTS|S:TSST"
);
exprtk::symbol_table<T> symbol_table;
symbol_table.add_constants();
symbol_table.add_variable ("x",x);
symbol_table.add_variable ("y",y);
symbol_table.add_variable ("z",z);
symbol_table.add_variable ("w",w);
symbol_table.add_stringvar("a",a);
symbol_table.add_stringvar("b",b);
symbol_table.add_stringvar("c",c);
symbol_table.add_stringvar("d",d);
symbol_table.add_stringvar("result",result);
symbol_table.add_function("foo",ovrld_func);
typedef typename overload_func<T>::test_result_t test_result_t;
typedef std::pair<std::string, typename overload_func<T>::test_result_t> test_pack_t;
static const test_pack_t test_pack_list[] =
{
test_pack_t("result := foo(x)" , test_result_t( 0, "T" )),
test_pack_t("result := foo(x, y)" , test_result_t( 1, "TT" )),
test_pack_t("result := foo(x, y, z)" , test_result_t( 2, "TTT" )),
test_pack_t("result := foo(x, y, z, w)" , test_result_t( 3, "TTTT")),
test_pack_t("result := foo(x + y)" , test_result_t( 0, "T" )),
test_pack_t("result := foo(x + y, y + z)" , test_result_t( 1, "TT" )),
test_pack_t("result := foo(x + y, y + z, z + w)" , test_result_t( 2, "TTT" )),
test_pack_t("result := foo(x + y, y + z, z + w, w)" , test_result_t( 3, "TTTT")),
test_pack_t("result := foo(a)" , test_result_t( 4, "S" )),
test_pack_t("result := foo(a, b)" , test_result_t( 5, "SS" )),
test_pack_t("result := foo(a, b, c)" , test_result_t( 6, "SSS" )),
test_pack_t("result := foo(a, b, c, d)" , test_result_t( 7, "SSSS")),
test_pack_t("result := foo(a + b)" , test_result_t( 4, "S" )),
test_pack_t("result := foo(a + b, b + c)" , test_result_t( 5, "SS" )),
test_pack_t("result := foo(a + b, b + c, c + d)" , test_result_t( 6, "SSS" )),
test_pack_t("result := foo(a + b, b + c, c + d, d)" , test_result_t( 7, "SSSS")),
test_pack_t("result := foo(a, x)" , test_result_t( 8, "ST" )),
test_pack_t("result := foo(a, x, b)" , test_result_t( 9, "STS" )),
test_pack_t("result := foo(a, x, b, y)" , test_result_t(10, "STST")),
test_pack_t("result := foo(a + b, x + y)" , test_result_t( 8, "ST" )),
test_pack_t("result := foo(a + b, x + y, b + c)" , test_result_t( 9, "STS" )),
test_pack_t("result := foo(a + b, x + y, b + c, y + z)" , test_result_t(10, "STST")),
test_pack_t("result := foo(x, a)" , test_result_t(11, "TS" )),
test_pack_t("result := foo(x, a, y)" , test_result_t(12, "TST" )),
test_pack_t("result := foo(x, a, y, b)" , test_result_t(13, "TSTS")),
test_pack_t("result := foo(x + y, a + b)" , test_result_t(11, "TS" )),
test_pack_t("result := foo(x + y, a + b, y + z)" , test_result_t(12, "TST" )),
test_pack_t("result := foo(x + y, a + b, y + z, b + c)" , test_result_t(13, "TSTS")),
test_pack_t("result := foo(x, y, a, b)" , test_result_t(14, "TTSS")),
test_pack_t("result := foo(a, b, x, y)" , test_result_t(15, "SSTT")),
test_pack_t("result := foo(a, x, y, b)" , test_result_t(16, "STTS")),
test_pack_t("result := foo(x, a, b, y)" , test_result_t(17, "TSST")),
test_pack_t("result := foo(x + y, y + z, a + b, b + c)" , test_result_t(14, "TTSS")),
test_pack_t("result := foo(a + b, b + c, x + y, y + z)" , test_result_t(15, "SSTT")),
test_pack_t("result := foo(a + b, x + y, y + z, b + c)" , test_result_t(16, "STTS")),
test_pack_t("result := foo(x + y, a + b, b + c, y + z)" , test_result_t(17, "TSST"))
};
static const std::size_t test_pack_list_size = sizeof(test_pack_list) / sizeof(test_pack_t);
std::deque<expression_t> expression_list;
for (std::size_t i = 0; i < test_pack_list_size; ++i)
{
expression_t expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
if (!parser.compile(test_pack_list[i].first, expression))
{
printf("run_test18() - (13) Overload VarArg Error: %s Expression: %s\n",
parser.error().c_str(),
test_pack_list[i].first.c_str());
return false;
}
else
expression_list.push_back(expression);
}
bool failure = false;
for (std::size_t i = 0; i < expression_list.size(); ++i)
{
ovrld_func.clear();
result = "";
expression_list[i].value();
if (result != "string result")
{
printf("run_test18() - Error in evaluation! (13) Expression: %s\n",
test_pack_list[i].first.c_str());
failure = true;
}
if (ovrld_func.current_ps_index != test_pack_list[i].second.ps_index)
{
printf("run_test18() - Error with ps_index (13) Expression: %s Expected: %d Got: %d\n",
test_pack_list[i].first.c_str(),
static_cast<int>(test_pack_list[i].second.ps_index),
static_cast<int>(ovrld_func.current_ps_index));
failure = true;
}
if (ovrld_func.current_param_seq != test_pack_list[i].second.param_seq)
{
printf("run_test18() - Error with parameter seq (13) Expression: %s Expected: %s Got: %s\n",
test_pack_list[i].first.c_str(),
test_pack_list[i].second.param_seq.c_str(),
ovrld_func.current_param_seq.c_str());
failure = true;
}
}
if (failure)
return false;
}
return true;
}

View File

@ -428,8 +428,8 @@ of C++ compilers:
| [r0:r1] | The closed interval [r0,r1] of the specified string. |
| | eg: Given a string x with a value of 'abcdefgh' then: |
| | 1. x[1:4] == 'bcde' |
| | 2. x[ :5] == x[:5] == 'abcdef' |
| | 3. x[3: ] == x[3:] =='cdefgh' |
| | 2. x[ :5] == x[:10 / 2] == 'abcdef' |
| | 3. x[2 + 1: ] == x[3:] =='defgh' |
| | 4. x[ : ] == x[:] == 'abcdefgh' |
| | 5. x[4/2:3+2] == x[2:5] == 'cdef' |
| | |
@ -920,7 +920,7 @@ The above denoted AST will be evaluated in the following order:
Generally an expression in ExprTk can be thought of as a free function
similar to those found in imperative languages. This form of pseudo
function will have a name, it may have a set of one or more inputs and
will return at least one value as its result. Futhermore the function
will return at least one value as its result. Furthermore the function
when invoked, may cause a side-effect that changes the state of the
host program.
@ -1023,7 +1023,7 @@ copied, it will then result in two or more identical expressions
utilizing the exact same references for variables. This obviously is
not the default assumed scenario and will give rise to non-obvious
behaviours when using the expressions in various contexts such as
muli-threading et al.
multi-threading et al.
The prescribed method for cloning an expression is to compile it from
its string form. Doing so will allow the 'user' to properly consider
@ -1315,7 +1315,7 @@ in a statement will cause it to have a side-effect:
(b) Invoking a user-defined function that has side-effects
The following are examples of expressions where the side-effect status
of the statements (or sub-exressions) within the expressions have been
of the statements (sub-expressions) within the expressions have been
noted:
+-+----------------------+------------------------------+
@ -1869,15 +1869,16 @@ embedded into the expression.
There are five types of function interface:
+---+----------------------+-------------+----------------------+
| # | Name | Return Type | Input Types |
+---+----------------------+-------------+----------------------+
| 1 | ifunction | Scalar | Scalar |
| 2 | ivararg_function | Scalar | Scalar |
| 3 | igeneric_function | Scalar | Scalar,Vector,String |
| 4 | igeneric_function II | String | Scalar,Vector,String |
| 5 | function_compositor | Scalar | Scalar |
+---+----------------------+-------------+----------------------+
+---+----------------------+--------------+----------------------+
| # | Name | Return Type | Input Types |
+---+----------------------+--------------+----------------------+
| 1 | ifunction | Scalar | Scalar |
| 2 | ivararg_function | Scalar | Scalar |
| 3 | igeneric_function | Scalar | Scalar,Vector,String |
| 4 | igeneric_function II | String | Scalar,Vector,String |
| 5 | igeneric_function III| String/Scalar| Scalar,Vector,String |
| 6 | function_compositor | Scalar | Scalar |
+---+----------------------+--------------+----------------------+
(1) ifunction
This interface supports zero to 20 input parameters of only the scalar
@ -2253,7 +2254,60 @@ as follows:
(4) Scalar (4) String
(5) function_compositor
(5) igeneric_function III
In this section we will discuss an extension of the igeneric_function
interface that will allow for the overloading of a user defined custom
function, where by it can return either a scalar or string value type
depending on the input parameter sequence with which the function is
invoked.
template <typename T>
struct foo : public exprtk::igeneric_function<T>
{
typedef typename exprtk::igeneric_function<T>::parameter_list_t
parameter_list_t;
foo()
: exprtk::igeneric_function<T>
(
"T:T|S:TS",
igfun_t::e_rtrn_overload
)
{}
// Scalar value returning invocations
inline T operator()(const std::size_t& ps_index,
parameter_list_t parameters)
{
...
}
// String value returning invocations
inline T operator()(const std::size_t& ps_index,
std::string& result,
parameter_list_t& parameters)
{
...
}
};
In the example above the custom user defined function "foo" can be
invoked by using either one of two input parameter sequences, which
are defined as follows:
Sequence-0 Sequence-1
'T' -> T 'TS' -> S
(1) Scalar (1) Scalar
(2) String
The parameter sequence definitions are identical to the previously
define igeneric_function, with the exception of the inclusion of the
return type - which can only be either a scalar T or a string S.
(6) function_compositor
The function compositor is a factory that allows one to define and
construct a function using ExprTk syntax. The functions are limited to
returning a single scalar value and consuming up to six parameters as
@ -2770,7 +2824,7 @@ expression being compiled.
This can become problematic, as in the default scenario it is assumed
the symbol_table that is registered with the expression instance will
already posses the externally available variables, functions and
already possess the externally available variables, functions and
constants needed during the compilation of the expression.
In the event there are symbols in the expression that can't be mapped
@ -2893,7 +2947,7 @@ after which the expression itself can be evaluated.
for (auto& var_name : variable_list)
{
T& v = symbol_table.variable_ref(var_name);
T& v = unknown_var_symbol_table.variable_ref(var_name);
v = ...;
}
@ -3789,7 +3843,7 @@ follows:
}
}
else
printf("An error occured.");
printf("An error occurred.");
(b) collect_functions
@ -3813,7 +3867,7 @@ follows:
}
}
else
printf("An error occured.");
printf("An error occurred.");
Note: When either the 'collect_variables' or 'collect_functions' free
@ -3825,10 +3879,10 @@ true.
Note: The default interface provided for both the collect_variables
and collect_functions free_functions, assumes that expressions will
only be utilising the ExprTk reserved funnctions (eg: abs, cos, min
only be utilising the ExprTk reserved functions (eg: abs, cos, min
etc). When user defined functions are to be used in an expression, a
symbol_table instance containing said functions can be passed to
either routine, and will be incorparated during the compilation and
either routine, and will be incorporated during the compilation and
Dependent Entity Collection processes. In the following example, a
user defined free function named 'foo' is registered with a
symbol_table. Finally the symbol_table instance and associated
@ -3858,7 +3912,7 @@ expression string are passed to the exprtk::collect_functions routine.
}
}
else
printf("An error occured.");
printf("An error occurred.");
(c) compute