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

This commit is contained in:
Arash Partow 2013-12-09 09:30:01 +11:00
parent 20cf7c23e0
commit 3c933cd8cf
4 changed files with 297 additions and 174 deletions

View File

@ -20,7 +20,7 @@ COMPILER = -c++
OPTIMIZATION_OPT = -O1 OPTIMIZATION_OPT = -O1
BASE_OPTIONS = -ansi -pedantic-errors -Wall -Wextra -Werror -Wno-long-long BASE_OPTIONS = -ansi -pedantic-errors -Wall -Wextra -Werror -Wno-long-long
OPTIONS = $(BASE_OPTIONS) $(OPTIMIZATION_OPT) -o OPTIONS = $(BASE_OPTIONS) $(OPTIMIZATION_OPT) -o
LINKER_OPT = -L/usr/lib -lstdc++ LINKER_OPT = -L/usr/lib -lstdc++ -lm
BUILD_LIST+=exprtk_test BUILD_LIST+=exprtk_test
BUILD_LIST+=exprtk_benchmark BUILD_LIST+=exprtk_benchmark

View File

@ -38,6 +38,7 @@
#include <cctype> #include <cctype>
#include <cmath> #include <cmath>
#include <cstdio> #include <cstdio>
#include <cstdlib>
#include <deque> #include <deque>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
@ -439,10 +440,10 @@ namespace exprtk
struct number_type { typedef unknown_type_tag type; }; struct number_type { typedef unknown_type_tag type; };
#define exprtk_register_real_type_tag(T) \ #define exprtk_register_real_type_tag(T) \
template<> struct number_type<T> { typedef real_type_tag type; }; template<> struct number_type<T> { typedef real_type_tag type; }; \
#define exprtk_register_int_type_tag(T) \ #define exprtk_register_int_type_tag(T) \
template<> struct number_type<T> { typedef int_type_tag type; }; template<> struct number_type<T> { typedef int_type_tag type; }; \
exprtk_register_real_type_tag(double) exprtk_register_real_type_tag(double)
exprtk_register_real_type_tag(long double) exprtk_register_real_type_tag(long double)
@ -609,6 +610,9 @@ namespace exprtk
{ {
const int index = std::max<int>(0, std::min<int>(pow10_size - 1, (int)std::floor(v1))); const int index = std::max<int>(0, std::min<int>(pow10_size - 1, (int)std::floor(v1)));
const T p10 = T(pow10[index]); const T p10 = T(pow10[index]);
if (v0 < T(0))
return T(std::ceil ((v0 * p10) - T(0.5)) / p10);
else
return T(std::floor((v0 * p10) + T(0.5)) / p10); return T(std::floor((v0 * p10) + T(0.5)) / p10);
} }
@ -1055,7 +1059,7 @@ namespace exprtk
{ \ { \
typename details::number_type<T>::type num_type; \ typename details::number_type<T>::type num_type; \
return details:: FunctionName##_impl(v,num_type); \ return details:: FunctionName##_impl(v,num_type); \
} } \
exprtk_define_unary_function(abs ) exprtk_define_unary_function(abs )
exprtk_define_unary_function(acos ) exprtk_define_unary_function(acos )
@ -5156,7 +5160,7 @@ namespace exprtk
mutable std::vector<T> value_list_; mutable std::vector<T> value_list_;
}; };
#define exprtk_def_unary_op(OpName) \ #define exprtk_define_unary_op(OpName) \
template <typename T> \ template <typename T> \
struct OpName##_op \ struct OpName##_op \
{ \ { \
@ -5164,44 +5168,44 @@ namespace exprtk
static inline T process(Type v) { return numeric:: OpName (v); } \ static inline T process(Type v) { return numeric:: OpName (v); } \
static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_##OpName; } \ static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_##OpName; } \
static inline details::operator_type operation() { return details::e_##OpName; } \ static inline details::operator_type operation() { return details::e_##OpName; } \
}; }; \
exprtk_def_unary_op(abs ) exprtk_define_unary_op(abs )
exprtk_def_unary_op(acos ) exprtk_define_unary_op(acos )
exprtk_def_unary_op(asin ) exprtk_define_unary_op(asin )
exprtk_def_unary_op(atan ) exprtk_define_unary_op(atan )
exprtk_def_unary_op(ceil ) exprtk_define_unary_op(ceil )
exprtk_def_unary_op(cos ) exprtk_define_unary_op(cos )
exprtk_def_unary_op(cosh ) exprtk_define_unary_op(cosh )
exprtk_def_unary_op(cot ) exprtk_define_unary_op(cot )
exprtk_def_unary_op(csc ) exprtk_define_unary_op(csc )
exprtk_def_unary_op(d2g ) exprtk_define_unary_op(d2g )
exprtk_def_unary_op(d2r ) exprtk_define_unary_op(d2r )
exprtk_def_unary_op(erf ) exprtk_define_unary_op(erf )
exprtk_def_unary_op(erfc ) exprtk_define_unary_op(erfc )
exprtk_def_unary_op(exp ) exprtk_define_unary_op(exp )
exprtk_def_unary_op(expm1) exprtk_define_unary_op(expm1)
exprtk_def_unary_op(floor) exprtk_define_unary_op(floor)
exprtk_def_unary_op(frac ) exprtk_define_unary_op(frac )
exprtk_def_unary_op(g2d ) exprtk_define_unary_op(g2d )
exprtk_def_unary_op(log ) exprtk_define_unary_op(log )
exprtk_def_unary_op(log10) exprtk_define_unary_op(log10)
exprtk_def_unary_op(log2 ) exprtk_define_unary_op(log2 )
exprtk_def_unary_op(log1p) exprtk_define_unary_op(log1p)
exprtk_def_unary_op(neg ) exprtk_define_unary_op(neg )
exprtk_def_unary_op(notl ) exprtk_define_unary_op(notl )
exprtk_def_unary_op(pos ) exprtk_define_unary_op(pos )
exprtk_def_unary_op(r2d ) exprtk_define_unary_op(r2d )
exprtk_def_unary_op(round) exprtk_define_unary_op(round)
exprtk_def_unary_op(sec ) exprtk_define_unary_op(sec )
exprtk_def_unary_op(sgn ) exprtk_define_unary_op(sgn )
exprtk_def_unary_op(sin ) exprtk_define_unary_op(sin )
exprtk_def_unary_op(sinh ) exprtk_define_unary_op(sinh )
exprtk_def_unary_op(sqrt ) exprtk_define_unary_op(sqrt )
exprtk_def_unary_op(tan ) exprtk_define_unary_op(tan )
exprtk_def_unary_op(tanh ) exprtk_define_unary_op(tanh )
exprtk_def_unary_op(trunc) exprtk_define_unary_op(trunc)
#undef exprtk_def_unary_op #undef exprtk_define_unary_op
template<typename T> template<typename T>
struct opr_base struct opr_base
@ -6520,73 +6524,73 @@ namespace exprtk
template <typename T, typename T0, typename T1> template <typename T, typename T0, typename T1>
const typename expression_node<T>::node_type nodetype_T0oT1<T,T0,T1>::result = expression_node<T>::e_none; const typename expression_node<T>::node_type nodetype_T0oT1<T,T0,T1>::result = expression_node<T>::e_none;
#define synthnode_type_def(T0_,T1_,v_) \ #define synthnode_type_define(T0_,T1_,v_) \
template <typename T, typename T0, typename T1> \ template <typename T, typename T0, typename T1> \
struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; }; \ struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; }; \
template <typename T, typename T0, typename T1> \ template <typename T, typename T0, typename T1> \
const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \ const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
synthnode_type_def(const T0&,const T1&, e_vov) synthnode_type_define(const T0&,const T1&, e_vov)
synthnode_type_def(const T0&,const T1 , e_voc) synthnode_type_define(const T0&,const T1 , e_voc)
synthnode_type_def(const T0 ,const T1&, e_cov) synthnode_type_define(const T0 ,const T1&, e_cov)
synthnode_type_def( T0&, T1&,e_none) synthnode_type_define( T0&, T1&,e_none)
synthnode_type_def(const T0 ,const T1 ,e_none) synthnode_type_define(const T0 ,const T1 ,e_none)
synthnode_type_def( T0&,const T1 ,e_none) synthnode_type_define( T0&,const T1 ,e_none)
synthnode_type_def(const T0 , T1&,e_none) synthnode_type_define(const T0 , T1&,e_none)
synthnode_type_def(const T0&, T1&,e_none) synthnode_type_define(const T0&, T1&,e_none)
synthnode_type_def( T0&,const T1&,e_none) synthnode_type_define( T0&,const T1&,e_none)
#undef synthnode_type_def #undef synthnode_type_define
template <typename T, typename T0, typename T1, typename T2> template <typename T, typename T0, typename T1, typename T2>
struct nodetype_T0oT1oT2 { static const typename expression_node<T>::node_type result; }; struct nodetype_T0oT1oT2 { static const typename expression_node<T>::node_type result; };
template <typename T, typename T0, typename T1, typename T2> template <typename T, typename T0, typename T1, typename T2>
const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0,T1,T2>::result = expression_node<T>::e_none; const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0,T1,T2>::result = expression_node<T>::e_none;
#define synthnode_type_def(T0_,T1_,T2_,v_) \ #define synthnode_type_define(T0_,T1_,T2_,v_) \
template <typename T, typename T0, typename T1, typename T2> \ template <typename T, typename T0, typename T1, typename T2> \
struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; }; \ struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; }; \
template <typename T, typename T0, typename T1, typename T2> \ template <typename T, typename T0, typename T1, typename T2> \
const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \ const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \
synthnode_type_def(const T0&,const T1&,const T2&, e_vovov) synthnode_type_define(const T0&,const T1&,const T2&, e_vovov)
synthnode_type_def(const T0&,const T1&,const T2 , e_vovoc) synthnode_type_define(const T0&,const T1&,const T2 , e_vovoc)
synthnode_type_def(const T0&,const T1 ,const T2&, e_vocov) synthnode_type_define(const T0&,const T1 ,const T2&, e_vocov)
synthnode_type_def(const T0 ,const T1&,const T2&, e_covov) synthnode_type_define(const T0 ,const T1&,const T2&, e_covov)
synthnode_type_def(const T0 ,const T1&,const T2 , e_covoc) synthnode_type_define(const T0 ,const T1&,const T2 , e_covoc)
synthnode_type_def(const T0 ,const T1 ,const T2 , e_none ) synthnode_type_define(const T0 ,const T1 ,const T2 , e_none )
synthnode_type_def(const T0 ,const T1 ,const T2&, e_none ) synthnode_type_define(const T0 ,const T1 ,const T2&, e_none )
synthnode_type_def(const T0&,const T1 ,const T2 , e_none ) synthnode_type_define(const T0&,const T1 ,const T2 , e_none )
synthnode_type_def( T0&, T1&, T2&, e_none ) synthnode_type_define( T0&, T1&, T2&, e_none )
#undef synthnode_type_def #undef synthnode_type_define
template <typename T, typename T0, typename T1, typename T2, typename T3> template <typename T, typename T0, typename T1, typename T2, typename T3>
struct nodetype_T0oT1oT2oT3 { static const typename expression_node<T>::node_type result; }; struct nodetype_T0oT1oT2oT3 { static const typename expression_node<T>::node_type result; };
template <typename T, typename T0, typename T1, typename T2, typename T3> template <typename T, typename T0, typename T1, typename T2, typename T3>
const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result = expression_node<T>::e_none; const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result = expression_node<T>::e_none;
#define synthnode_type_def(T0_,T1_,T2_,T3_,v_) \ #define synthnode_type_define(T0_,T1_,T2_,T3_,v_) \
template <typename T, typename T0, typename T1, typename T2, typename T3> \ template <typename T, typename T0, typename T1, typename T2, typename T3> \
struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; }; \ struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; }; \
template <typename T, typename T0, typename T1, typename T2, typename T3> \ template <typename T, typename T0, typename T1, typename T2, typename T3> \
const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \ const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \
synthnode_type_def(const T0&,const T1&,const T2&, const T3&,e_vovovov) synthnode_type_define(const T0&,const T1&,const T2&, const T3&,e_vovovov)
synthnode_type_def(const T0&,const T1&,const T2&, const T3 ,e_vovovoc) synthnode_type_define(const T0&,const T1&,const T2&, const T3 ,e_vovovoc)
synthnode_type_def(const T0&,const T1&,const T2 , const T3&,e_vovocov) synthnode_type_define(const T0&,const T1&,const T2 , const T3&,e_vovocov)
synthnode_type_def(const T0&,const T1 ,const T2&, const T3&,e_vocovov) synthnode_type_define(const T0&,const T1 ,const T2&, const T3&,e_vocovov)
synthnode_type_def(const T0 ,const T1&,const T2&, const T3&,e_covovov) synthnode_type_define(const T0 ,const T1&,const T2&, const T3&,e_covovov)
synthnode_type_def(const T0 ,const T1&,const T2 , const T3&,e_covocov) synthnode_type_define(const T0 ,const T1&,const T2 , const T3&,e_covocov)
synthnode_type_def(const T0&,const T1 ,const T2&, const T3 ,e_vocovoc) synthnode_type_define(const T0&,const T1 ,const T2&, const T3 ,e_vocovoc)
synthnode_type_def(const T0 ,const T1&,const T2&, const T3 ,e_covovoc) synthnode_type_define(const T0 ,const T1&,const T2&, const T3 ,e_covovoc)
synthnode_type_def(const T0&,const T1 ,const T2 , const T3&,e_vococov) synthnode_type_define(const T0&,const T1 ,const T2 , const T3&,e_vococov)
synthnode_type_def(const T0 ,const T1 ,const T2 , const T3 ,e_none ) synthnode_type_define(const T0 ,const T1 ,const T2 , const T3 ,e_none )
synthnode_type_def(const T0 ,const T1 ,const T2 , const T3&,e_none ) synthnode_type_define(const T0 ,const T1 ,const T2 , const T3&,e_none )
synthnode_type_def(const T0 ,const T1 ,const T2&, const T3 ,e_none ) synthnode_type_define(const T0 ,const T1 ,const T2&, const T3 ,e_none )
synthnode_type_def(const T0 ,const T1&,const T2 , const T3 ,e_none ) synthnode_type_define(const T0 ,const T1&,const T2 , const T3 ,e_none )
synthnode_type_def(const T0&,const T1 ,const T2 , const T3 ,e_none ) synthnode_type_define(const T0&,const T1 ,const T2 , const T3 ,e_none )
synthnode_type_def(const T0 ,const T1 ,const T2&, const T3&,e_none ) synthnode_type_define(const T0 ,const T1 ,const T2&, const T3&,e_none )
synthnode_type_def(const T0&,const T1&,const T2 , const T3 ,e_none ) synthnode_type_define(const T0&,const T1&,const T2 , const T3 ,e_none )
#undef synthnode_type_def #undef synthnode_type_define
template <typename T, typename T0, typename T1> template <typename T, typename T0, typename T1>
class T0oT1 : public expression_node<T> class T0oT1 : public expression_node<T>
@ -8326,7 +8330,9 @@ namespace exprtk
inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m) inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m)
{ {
#define register_op(Symbol,Type,Args) m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); #define register_op(Symbol,Type,Args) \
m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \
register_op( "abs",e_abs , 1) register_op( "abs",e_abs , 1)
register_op( "acos",e_acos , 1) register_op( "acos",e_acos , 1)
register_op( "asin",e_asin , 1) register_op( "asin",e_asin , 1)
@ -12727,23 +12733,25 @@ namespace exprtk
if ((0 == result) && details::is_true(condition)) if ((0 == result) && details::is_true(condition))
{ {
result = consequent; result = consequent;
free_node(*node_allocator_,arglist[2 * i]);
break; break;
} }
else
{
free_node(*node_allocator_,arglist[(2 * i) ]);
free_node(*node_allocator_,arglist[(2 * i) + 1]);
}
} }
if (result) if (0 == result)
{ {
free_node(*node_allocator_,arglist.back()); result = arglist.back();
return result;
} }
else
return arglist.back(); for (std::size_t i = 0; i < arglist.size(); ++i)
{
expression_node_ptr current_expr = arglist[i];
if (current_expr && (current_expr != result))
{
free_node(*node_allocator_,current_expr);
}
}
return result;
} }
template <typename Allocator, template <typename Allocator,
@ -12803,7 +12811,10 @@ namespace exprtk
T& v = dynamic_cast<details::variable_node<T>*>(branch[0])->ref(); T& v = dynamic_cast<details::variable_node<T>*>(branch[0])->ref();
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<typename details::unary_variable_node<Type,op1<Type> > >(v); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate<typename details::unary_variable_node<Type,op1<Type> > >(v); \
unary_opr_switch_statements unary_opr_switch_statements
#undef case_stmt #undef case_stmt
default : return error_node(); default : return error_node();
@ -12814,7 +12825,10 @@ namespace exprtk
{ {
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]); \
unary_opr_switch_statements unary_opr_switch_statements
#undef case_stmt #undef case_stmt
default : return error_node(); default : return error_node();
@ -12826,7 +12840,12 @@ namespace exprtk
expression_node_ptr temp_node = error_node(); expression_node_ptr temp_node = error_node();
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : temp_node = node_allocator_->allocate<details::sf3_node<Type,op1<Type> > >(operation,branch); break; #define case_stmt(op0,op1) \
case op0 : temp_node = node_allocator_-> \
allocate<details::sf3_node<Type,op1<Type> > > \
(operation,branch); \
break; \
case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op) case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op)
case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op) case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op)
case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op) case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op)
@ -12867,7 +12886,11 @@ namespace exprtk
const Type& v2 = dynamic_cast<details::variable_node<Type>*>(branch[2])->ref(); const Type& v2 = dynamic_cast<details::variable_node<Type>*>(branch[2])->ref();
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rrr<details::sf3_var_node<Type,op1<Type> > >(v0,v1,v2); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate_rrr<details::sf3_var_node<Type,op1<Type> > > \
(v0,v1,v2); \
case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op) case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op)
case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op) case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op)
case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op) case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op)
@ -12909,7 +12932,10 @@ namespace exprtk
{ {
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<details::sf3_node<Type,op1<Type> > >(operation,branch); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate<details::sf3_node<Type,op1<Type> > >(operation,branch); \
case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op) case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op)
case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op) case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op)
case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op) case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op)
@ -12945,7 +12971,11 @@ namespace exprtk
expression_node_ptr temp_node = error_node(); expression_node_ptr temp_node = error_node();
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : temp_node = node_allocator_->allocate<details::sf4_node<Type,op1<Type> > >(operation,branch); break; #define case_stmt(op0,op1) \
case op0 : temp_node = node_allocator_-> \
allocate<details::sf4_node<Type,op1<Type> > >(operation,branch); \
break; \
case_stmt(details::e_sf47,details::sf47_op) case_stmt(details::e_sf48,details::sf48_op) case_stmt(details::e_sf47,details::sf47_op) case_stmt(details::e_sf48,details::sf48_op)
case_stmt(details::e_sf49,details::sf49_op) case_stmt(details::e_sf50,details::sf50_op) case_stmt(details::e_sf49,details::sf49_op) case_stmt(details::e_sf50,details::sf50_op)
case_stmt(details::e_sf51,details::sf51_op) case_stmt(details::e_sf52,details::sf52_op) case_stmt(details::e_sf51,details::sf51_op) case_stmt(details::e_sf52,details::sf52_op)
@ -12988,7 +13018,10 @@ namespace exprtk
const Type& v3 = dynamic_cast<details::variable_node<Type>*>(branch[3])->ref(); const Type& v3 = dynamic_cast<details::variable_node<Type>*>(branch[3])->ref();
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rrrr<details::sf4_var_node<Type,op1<Type> > >(v0,v1,v2,v3); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate_rrrr<details::sf4_var_node<Type,op1<Type> > >(v0,v1,v2,v3); \
case_stmt(details::e_sf47,details::sf47_op) case_stmt(details::e_sf48,details::sf48_op) case_stmt(details::e_sf47,details::sf47_op) case_stmt(details::e_sf48,details::sf48_op)
case_stmt(details::e_sf49,details::sf49_op) case_stmt(details::e_sf50,details::sf50_op) case_stmt(details::e_sf49,details::sf49_op) case_stmt(details::e_sf50,details::sf50_op)
case_stmt(details::e_sf51,details::sf51_op) case_stmt(details::e_sf52,details::sf52_op) case_stmt(details::e_sf51,details::sf51_op) case_stmt(details::e_sf52,details::sf52_op)
@ -13030,7 +13063,10 @@ namespace exprtk
return varnode_optimize_sf4(operation,branch); return varnode_optimize_sf4(operation,branch);
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<details::sf4_node<Type,op1<Type> > >(operation,branch); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate<details::sf4_node<Type,op1<Type> > >(operation,branch); \
case_stmt(details::e_sf47,details::sf47_op) case_stmt(details::e_sf48,details::sf48_op) case_stmt(details::e_sf47,details::sf47_op) case_stmt(details::e_sf48,details::sf48_op)
case_stmt(details::e_sf49,details::sf49_op) case_stmt(details::e_sf50,details::sf50_op) case_stmt(details::e_sf49,details::sf49_op) case_stmt(details::e_sf50,details::sf50_op)
case_stmt(details::e_sf51,details::sf51_op) case_stmt(details::e_sf52,details::sf52_op) case_stmt(details::e_sf51,details::sf51_op) case_stmt(details::e_sf52,details::sf52_op)
@ -13069,7 +13105,12 @@ namespace exprtk
expression_node_ptr temp_node = error_node(); expression_node_ptr temp_node = error_node();
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : temp_node = node_allocator_->allocate<details::vararg_node<Type,op1<Type> > >(arglist); break; #define case_stmt(op0,op1) \
case op0 : temp_node = node_allocator_-> \
allocate<details::vararg_node<Type,op1<Type> > > \
(arglist); \
break; \
case_stmt(details::e_sum, details::vararg_add_op ) case_stmt(details::e_sum, details::vararg_add_op )
case_stmt(details::e_prod, details::vararg_mul_op ) case_stmt(details::e_prod, details::vararg_mul_op )
case_stmt(details::e_avg, details::vararg_avg_op ) case_stmt(details::e_avg, details::vararg_avg_op )
@ -13092,7 +13133,10 @@ namespace exprtk
{ {
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<details::vararg_varnode<Type,op1<Type> > >(arglist); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate<details::vararg_varnode<Type,op1<Type> > >(arglist); \
case_stmt(details::e_sum, details::vararg_add_op ) case_stmt(details::e_sum, details::vararg_add_op )
case_stmt(details::e_prod, details::vararg_mul_op ) case_stmt(details::e_prod, details::vararg_mul_op )
case_stmt(details::e_avg, details::vararg_avg_op ) case_stmt(details::e_avg, details::vararg_avg_op )
@ -13121,7 +13165,10 @@ namespace exprtk
return varnode_optimize_varargfunc(operation,arglist); return varnode_optimize_varargfunc(operation,arglist);
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<details::vararg_node<Type,op1<Type> > >(arglist); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate<details::vararg_node<Type,op1<Type> > >(arglist); \
case_stmt(details::e_sum, details::vararg_add_op ) case_stmt(details::e_sum, details::vararg_add_op )
case_stmt(details::e_prod, details::vararg_mul_op ) case_stmt(details::e_prod, details::vararg_mul_op )
case_stmt(details::e_avg, details::vararg_avg_op ) case_stmt(details::e_avg, details::vararg_avg_op )
@ -13305,7 +13352,10 @@ namespace exprtk
{ {
switch (p) switch (p)
{ {
#define case_stmt(cp) case cp : return node_allocator_->allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); #define case_stmt(cp) \
case cp : return node_allocator_-> \
allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \
case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4) case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4)
case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8) case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8)
case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12) case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12)
@ -13365,7 +13415,11 @@ namespace exprtk
{ {
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate<typename details::binary_ext_node<Type,op1<Type> > >(branch[0],branch[1]); #define case_stmt(op0,op1) \
case op0 : return expr_gen.node_allocator_-> \
template allocate<typename details::binary_ext_node<Type,op1<Type> > > \
(branch[0],branch[1]); \
basic_opr_switch_statements basic_opr_switch_statements
extended_opr_switch_statements extended_opr_switch_statements
#undef case_stmt #undef case_stmt
@ -13392,7 +13446,11 @@ namespace exprtk
} }
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_rc<typename details::vob_node<Type,op1<Type> > >(v,branch[1]); #define case_stmt(op0,op1) \
case op0 : return expr_gen.node_allocator_-> \
template allocate_rc<typename details::vob_node<Type,op1<Type> > > \
(v,branch[1]); \
basic_opr_switch_statements basic_opr_switch_statements
extended_opr_switch_statements extended_opr_switch_statements
#undef case_stmt #undef case_stmt
@ -13419,7 +13477,11 @@ namespace exprtk
} }
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_cr<typename details::bov_node<Type,op1<Type> > >(branch[0],v); #define case_stmt(op0,op1) \
case op0 : return expr_gen.node_allocator_-> \
template allocate_cr<typename details::bov_node<Type,op1<Type> > > \
(branch[0],v); \
basic_opr_switch_statements basic_opr_switch_statements
extended_opr_switch_statements extended_opr_switch_statements
#undef case_stmt #undef case_stmt
@ -13470,7 +13532,11 @@ namespace exprtk
} }
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_rc<typename details::cob_node<Type,op1<Type> > >(c,branch[1]); #define case_stmt(op0,op1) \
case op0 : return expr_gen.node_allocator_-> \
template allocate_rc<typename details::cob_node<Type,op1<Type> > > \
(c,branch[1]); \
basic_opr_switch_statements basic_opr_switch_statements
extended_opr_switch_statements extended_opr_switch_statements
#undef case_stmt #undef case_stmt
@ -13521,7 +13587,11 @@ namespace exprtk
} }
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_cr<typename details::boc_node<Type,op1<Type> > >(branch[0],c); #define case_stmt(op0,op1) \
case op0 : return expr_gen.node_allocator_-> \
template allocate_cr<typename details::boc_node<Type,op1<Type> > > \
(branch[0],c); \
basic_opr_switch_statements basic_opr_switch_statements
extended_opr_switch_statements extended_opr_switch_statements
#undef case_stmt #undef case_stmt
@ -13556,7 +13626,11 @@ namespace exprtk
const Type& v2 = dynamic_cast<details::variable_node<Type>*>(branch[1])->ref(); const Type& v2 = dynamic_cast<details::variable_node<Type>*>(branch[1])->ref();
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_rr<typename details::vov_node<Type,op1<Type> > >(v1,v2); #define case_stmt(op0,op1) \
case op0 : return expr_gen.node_allocator_-> \
template allocate_rr<typename details::vov_node<Type,op1<Type> > > \
(v1,v2); \
basic_opr_switch_statements basic_opr_switch_statements
extended_opr_switch_statements extended_opr_switch_statements
#undef case_stmt #undef case_stmt
@ -13576,7 +13650,11 @@ namespace exprtk
details::free_node(*(expr_gen.node_allocator_),branch[0]); details::free_node(*(expr_gen.node_allocator_),branch[0]);
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_cr<typename details::cov_node<Type,op1<Type> > >(c,v); #define case_stmt(op0,op1) \
case op0 : return expr_gen.node_allocator_-> \
template allocate_cr<typename details::cov_node<Type,op1<Type> > > \
(c,v); \
basic_opr_switch_statements basic_opr_switch_statements
extended_opr_switch_statements extended_opr_switch_statements
#undef case_stmt #undef case_stmt
@ -13600,7 +13678,11 @@ namespace exprtk
} }
switch (operation) switch (operation)
{ {
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_rc<typename details::voc_node<Type,op1<Type> > >(v,c); #define case_stmt(op0,op1) \
case op0 : return expr_gen.node_allocator_-> \
template allocate_rc<typename details::voc_node<Type,op1<Type> > > \
(v,c); \
basic_opr_switch_statements basic_opr_switch_statements
extended_opr_switch_statements extended_opr_switch_statements
#undef case_stmt #undef case_stmt
@ -13618,7 +13700,10 @@ namespace exprtk
{ {
switch (sf3opr) switch (sf3opr)
{ {
#define case_stmt(op0,op1) case op0 : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,op1<Type> >::allocate(*(expr_gen.node_allocator_),t0,t1,t2); #define case_stmt(op0,op1) \
case op0 : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,op1<Type> >:: \
allocate(*(expr_gen.node_allocator_),t0,t1,t2); \
case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op) case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op)
case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op) case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op)
case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op) case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op)
@ -13663,7 +13748,10 @@ namespace exprtk
{ {
switch (sf4opr) switch (sf4opr)
{ {
#define case_stmt(op0,op1) case op0 : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,op1<Type> >::allocate(*(expr_gen.node_allocator_),t0,t1,t2,t3); #define case_stmt(op0,op1) \
case op0 : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,op1<Type> >:: \
allocate(*(expr_gen.node_allocator_),t0,t1,t2,t3); \
case_stmt(details::e_sf47,details::sf47_op) case_stmt(details::e_sf48,details::sf48_op) case_stmt(details::e_sf47,details::sf47_op) case_stmt(details::e_sf48,details::sf48_op)
case_stmt(details::e_sf49,details::sf49_op) case_stmt(details::e_sf50,details::sf50_op) case_stmt(details::e_sf49,details::sf49_op) case_stmt(details::e_sf50,details::sf50_op)
case_stmt(details::e_sf51,details::sf51_op) case_stmt(details::e_sf52,details::sf52_op) case_stmt(details::e_sf51,details::sf51_op) case_stmt(details::e_sf52,details::sf52_op)
@ -16231,7 +16319,11 @@ namespace exprtk
{ {
switch (opr) switch (opr)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_pack,op1<Type> >,T0,T1>(s0,s1,rp0); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_pack,op1<Type> >,T0,T1> \
(s0,s1,rp0); \
string_opr_switch_statements string_opr_switch_statements
#undef case_stmt #undef case_stmt
default : return error_node(); default : return error_node();
@ -16243,7 +16335,11 @@ namespace exprtk
{ {
switch (opr) switch (opr)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_pack,op1<Type> >,T0,T1>(s0,s1,rp1); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_pack,op1<Type> >,T0,T1> \
(s0,s1,rp1); \
string_opr_switch_statements string_opr_switch_statements
#undef case_stmt #undef case_stmt
default : return error_node(); default : return error_node();
@ -16255,7 +16351,11 @@ namespace exprtk
{ {
switch (opr) switch (opr)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_pack,op1<Type> >,T0,T1>(s0,s1,rp0,rp1); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_pack,op1<Type> >,T0,T1> \
(s0,s1,rp0,rp1); \
string_opr_switch_statements string_opr_switch_statements
#undef case_stmt #undef case_stmt
default : return error_node(); default : return error_node();
@ -16267,7 +16367,10 @@ namespace exprtk
{ {
switch (opr) switch (opr)
{ {
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0,s1); #define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0,s1); \
string_opr_switch_statements string_opr_switch_statements
#undef case_stmt #undef case_stmt
default : return error_node(); default : return error_node();
@ -16737,7 +16840,9 @@ namespace exprtk
inline void load_unary_operations_map(unary_op_map_t& m) inline void load_unary_operations_map(unary_op_map_t& m)
{ {
#define register_unary_op(Op,UnaryFunctor) m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); #define register_unary_op(Op,UnaryFunctor) \
m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \
register_unary_op(details:: e_abs,details:: abs_op) register_unary_op(details:: e_abs,details:: abs_op)
register_unary_op(details:: e_acos,details:: acos_op) register_unary_op(details:: e_acos,details:: acos_op)
register_unary_op(details:: e_asin,details:: asin_op) register_unary_op(details:: e_asin,details:: asin_op)
@ -16778,7 +16883,9 @@ namespace exprtk
inline void load_binary_operations_map(binary_op_map_t& m) inline void load_binary_operations_map(binary_op_map_t& m)
{ {
#define register_binary_op(Op,BinaryFunctor) m.insert(typename binary_op_map_t::value_type(Op,BinaryFunctor<T>::process)); #define register_binary_op(Op,BinaryFunctor) \
m.insert(typename binary_op_map_t::value_type(Op,BinaryFunctor<T>::process)); \
register_binary_op(details:: e_add,details:: add_op) register_binary_op(details:: e_add,details:: add_op)
register_binary_op(details:: e_sub,details:: sub_op) register_binary_op(details:: e_sub,details:: sub_op)
register_binary_op(details:: e_mul,details:: mul_op) register_binary_op(details:: e_mul,details:: mul_op)
@ -16802,7 +16909,9 @@ namespace exprtk
inline void load_inv_binary_operations_map(inv_binary_op_map_t& m) inline void load_inv_binary_operations_map(inv_binary_op_map_t& m)
{ {
#define register_binary_op(Op,BinaryFunctor) m.insert(typename inv_binary_op_map_t::value_type(BinaryFunctor<T>::process,Op)); #define register_binary_op(Op,BinaryFunctor) \
m.insert(typename inv_binary_op_map_t::value_type(BinaryFunctor<T>::process,Op)); \
register_binary_op(details:: e_add,details:: add_op) register_binary_op(details:: e_add,details:: add_op)
register_binary_op(details:: e_sub,details:: sub_op) register_binary_op(details:: e_sub,details:: sub_op)
register_binary_op(details:: e_mul,details:: mul_op) register_binary_op(details:: e_mul,details:: mul_op)
@ -16827,7 +16936,10 @@ namespace exprtk
inline void load_sf3_map(sf3_map_t& sf3_map) inline void load_sf3_map(sf3_map_t& sf3_map)
{ {
typedef std::pair<trinary_functor_t,details::operator_type> pair_t; typedef std::pair<trinary_functor_t,details::operator_type> pair_t;
#define register_sf3(Op) sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op);
#define register_sf3(Op) \
sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
register_sf3(00) register_sf3(01) register_sf3(02) register_sf3(03) register_sf3(00) register_sf3(01) register_sf3(02) register_sf3(03)
register_sf3(04) register_sf3(05) register_sf3(06) register_sf3(07) register_sf3(04) register_sf3(05) register_sf3(06) register_sf3(07)
register_sf3(08) register_sf3(09) register_sf3(10) register_sf3(11) register_sf3(08) register_sf3(09) register_sf3(10) register_sf3(11)
@ -16842,7 +16954,10 @@ namespace exprtk
inline void load_sf4_map(sf4_map_t& sf4_map) inline void load_sf4_map(sf4_map_t& sf4_map)
{ {
typedef std::pair<quaternary_functor_t,details::operator_type> pair_t; typedef std::pair<quaternary_functor_t,details::operator_type> pair_t;
#define register_sf4(Op) sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op);
#define register_sf4(Op) \
sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
register_sf4(47) register_sf4(48) register_sf4(49) register_sf4(50) register_sf4(47) register_sf4(48) register_sf4(49) register_sf4(50)
register_sf4(51) register_sf4(52) register_sf4(53) register_sf4(54) register_sf4(51) register_sf4(52) register_sf4(53) register_sf4(54)
register_sf4(55) register_sf4(56) register_sf4(57) register_sf4(58) register_sf4(55) register_sf4(56) register_sf4(57) register_sf4(58)
@ -16854,8 +16969,9 @@ namespace exprtk
register_sf4(79) register_sf4(80) register_sf4(81) register_sf4(82) register_sf4(79) register_sf4(80) register_sf4(81) register_sf4(82)
#undef register_sf4 #undef register_sf4
typedef std::pair<quaternary_functor_t,details::operator_type> pair_t; #define register_sf4ext(Op) \
#define register_sf4ext(Op) sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \
register_sf4ext(00) register_sf4ext(01) register_sf4ext(02) register_sf4ext(03) register_sf4ext(00) register_sf4ext(01) register_sf4ext(02) register_sf4ext(03)
register_sf4ext(04) register_sf4ext(05) register_sf4ext(06) register_sf4ext(07) register_sf4ext(04) register_sf4ext(05) register_sf4ext(06) register_sf4ext(07)
register_sf4ext(08) register_sf4ext(09) register_sf4ext(10) register_sf4ext(11) register_sf4ext(08) register_sf4ext(09) register_sf4ext(10) register_sf4ext(11)

View File

@ -15,10 +15,10 @@ operations, functions and processes:
(0) Basic operators: +, -, *, /, %, ^ (0) Basic operators: +, -, *, /, %, ^
(1) Functions: abs, avg, ceil, clamp, erf, erfc, exp, expm1, (1) Functions: abs, avg, ceil, clamp, equal, erf, erfc, exp,
floor, frac, inrange, log, log10, log1p, log2, expm1, floor, frac, log, log10, log1p, log2,
logn, max, min, root, round, roundn, sgn, sqrt, logn, max, min, mul, nequal, root, round,
sum, trunc roundn, sgn, sqrt, sum, trunc
(2) Trigonometry: acos, asin, atan, atan2, cos, cosh, cot, csc, (2) Trigonometry: acos, asin, atan, atan2, cos, cosh, cot, csc,
deg2grad, deg2rad, grad2deg, hypot, rad2deg, deg2grad, deg2rad, grad2deg, hypot, rad2deg,
@ -557,7 +557,14 @@ correctly optimize such expressions for a given architecture.
(18) Recursive calls made from within composited functions will have (18) Recursive calls made from within composited functions will have
a stack size bound by the stack of the executing architecture. a stack size bound by the stack of the executing architecture.
(19) Expressions may contain any of the following comment styles: (19) The following are examples of floating point value represenations
that are supported:
(a) 12345 (b) -123.456
(c) +123.456e+12 (d) 123.456E-12
(c) +012.045e+07 (e) .1234
(f) 123.456f (f) -321.654E+3L
(20) Expressions may contain any of the following comment styles:
1. // .... \n 1. // .... \n
2. # .... \n 2. # .... \n
3. /* .... */ 3. /* .... */