From ce2320489562192e2e81489d8978b9871bd1a4b2 Mon Sep 17 00:00:00 2001 From: Arash Partow Date: Mon, 17 Nov 2014 22:03:10 +1100 Subject: [PATCH] C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html --- exprtk.hpp | 817 +++++++++++++++++++++++-------------------- exprtk_benchmark.cpp | 33 ++ exprtk_test.cpp | 89 ++++- readme.txt | 308 ++++++++++++---- 4 files changed, 788 insertions(+), 459 deletions(-) diff --git a/exprtk.hpp b/exprtk.hpp index 2583631..22bce3d 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -150,8 +151,10 @@ namespace exprtk return false; } } + return true; } + return false; } @@ -169,17 +172,22 @@ namespace exprtk { if (0 == i) return std::string("0"); + std::string result; bool negative = (i < 0); + if (negative) i *= -1; + while (i) { char digit = '0' + char(i % 10); result = (digit + result); i /= 10; } + if (negative) result = "-" + result; + return result; } @@ -321,6 +329,7 @@ namespace exprtk return true; } } + return false; } @@ -335,17 +344,23 @@ namespace exprtk const typename std::iterator_traits::value_type& zero_or_more, const typename std::iterator_traits::value_type& zero_or_one) { - if (0 == std::distance(data_begin,data_end)) return false; + if (0 == std::distance(data_begin,data_end)) + { + return false; + } + Iterator d_itr = data_begin; Iterator p_itr = pattern_begin; Iterator c_itr = data_begin; Iterator m_itr = data_begin; + while ((data_end != d_itr) && (zero_or_more != (*p_itr))) { if ((!Compare::cmp((*p_itr),(*d_itr))) && (zero_or_one != (*p_itr))) { return false; } + ++p_itr; ++d_itr; } @@ -358,6 +373,7 @@ namespace exprtk { return true; } + m_itr = p_itr; c_itr = d_itr; ++c_itr; @@ -374,6 +390,7 @@ namespace exprtk } } while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) ++p_itr; + return (p_itr == pattern_end); } @@ -487,7 +504,7 @@ namespace exprtk template inline bool is_nan_impl(const T v, real_type_tag) { - return (v != v); + return std::not_equal_to()(v,v); } template @@ -505,13 +522,13 @@ namespace exprtk template inline bool is_true_impl(const T v) { - return (v != T(0)); + return std::not_equal_to()(T(0),v); } template inline bool is_false_impl(const T v) { - return (T(0) == v); + return std::equal_to()(T(0),v); } template @@ -935,7 +952,7 @@ namespace exprtk template inline T d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180)); } template inline T d2g_impl(const T v, real_type_tag) { return (v * T(20.0/9.0)); } template inline T g2d_impl(const T v, real_type_tag) { return (v * T(9.0/20.0)); } - template inline T notl_impl(const T v, real_type_tag) { return (v != T(0) ? T(0) : T(1)); } + template inline T notl_impl(const T v, real_type_tag) { return (std::not_equal_to()(T(0),v) ? T(0) : T(1)); } template inline T frac_impl(const T v, real_type_tag) { return (v - static_cast(v)); } template inline T trunc_impl(const T v, real_type_tag) { return T(static_cast(v)); } @@ -972,7 +989,7 @@ namespace exprtk template inline bool is_integer_impl(const T& v, real_type_tag) { - return (T(0) == std::fmod(v,T(1))); + return std::equal_to()(T(0),std::fmod(v,T(1))); } template @@ -980,7 +997,6 @@ namespace exprtk { return true; } - } template @@ -2066,7 +2082,7 @@ namespace exprtk inline void scan_symbol() { - const char* begin = s_itr_; + const char* initial_itr = s_itr_; while ( (!is_end(s_itr_)) && @@ -2077,7 +2093,7 @@ namespace exprtk } token_t t; - t.set_symbol(begin,s_itr_,base_itr_); + t.set_symbol(initial_itr,s_itr_,base_itr_); token_list_.push_back(t); } @@ -2094,7 +2110,7 @@ namespace exprtk 7. 123.456e-3 8. 123.456E-3 */ - const char* begin = s_itr_; + const char* initial_itr = s_itr_; bool dot_found = false; bool e_found = false; bool post_e_sign_found = false; @@ -2106,7 +2122,7 @@ namespace exprtk { if (dot_found) { - t.set_error(token::e_err_number,begin,s_itr_,base_itr_); + t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_); token_list_.push_back(t); return; } @@ -2122,7 +2138,7 @@ namespace exprtk if (is_end(s_itr_ + 1)) { - t.set_error(token::e_err_number,begin,s_itr_,base_itr_); + t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_); token_list_.push_back(t); return; @@ -2133,7 +2149,7 @@ namespace exprtk !details::is_digit(c) ) { - t.set_error(token::e_err_number,begin,s_itr_,base_itr_); + t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_); token_list_.push_back(t); return; @@ -2147,7 +2163,7 @@ namespace exprtk { if (post_e_sign_found) { - t.set_error(token::e_err_number,begin,s_itr_,base_itr_); + t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_); token_list_.push_back(t); return; @@ -2163,7 +2179,7 @@ namespace exprtk ++s_itr_; } - t.set_numeric(begin,s_itr_,base_itr_); + t.set_numeric(initial_itr,s_itr_,base_itr_); token_list_.push_back(t); return; @@ -2171,13 +2187,13 @@ namespace exprtk inline void scan_special_function() { - const char* begin = s_itr_; + const char* initial_itr = s_itr_; token_t t; // $fdd(x,x,x) = at least 11 chars if (std::distance(s_itr_,s_end_) < 11) { - t.set_error(token::e_err_sfunc,begin,s_itr_,base_itr_); + t.set_error(token::e_err_sfunc,initial_itr,s_itr_,base_itr_); token_list_.push_back(t); return; @@ -2190,7 +2206,7 @@ namespace exprtk (details::is_digit(*(s_itr_ + 3)))) ) { - t.set_error(token::e_err_sfunc,begin,s_itr_,base_itr_); + t.set_error(token::e_err_sfunc,initial_itr,s_itr_,base_itr_); token_list_.push_back(t); return; @@ -2198,7 +2214,7 @@ namespace exprtk s_itr_ += 4; // $fdd = 4chars - t.set_symbol(begin,s_itr_,base_itr_); + t.set_symbol(initial_itr,s_itr_,base_itr_); token_list_.push_back(t); return; @@ -2207,7 +2223,7 @@ namespace exprtk #ifndef exprtk_disable_string_capabilities inline void scan_string() { - const char* begin = s_itr_ + 1; + const char* initial_itr = s_itr_ + 1; token_t t; if (std::distance(s_itr_,s_end_) < 2) @@ -2245,23 +2261,24 @@ namespace exprtk if (is_end(s_itr_)) { - t.set_error(token::e_err_string,begin,s_itr_,base_itr_); + t.set_error(token::e_err_string,initial_itr,s_itr_,base_itr_); token_list_.push_back(t); return; } if (!escaped_found) - t.set_string(begin,s_itr_,base_itr_); + t.set_string(initial_itr,s_itr_,base_itr_); else { - std::string parsed_string(begin,s_itr_); + std::string parsed_string(initial_itr,s_itr_); details::cleanup_escapes(parsed_string); - t.set_string(parsed_string, std::distance(base_itr_,begin)); + t.set_string(parsed_string, std::distance(base_itr_,initial_itr)); } token_list_.push_back(t); ++s_itr_; + return; } #endif @@ -2834,12 +2851,14 @@ namespace exprtk { state_ = false; error_token_ = t; + return false; } else if (c != stack_.top().first) { state_ = false; error_token_ = t; + return false; } else @@ -2974,6 +2993,7 @@ namespace exprtk { t.value = itr->second.first; t.type = itr->second.second; + return true; } } @@ -3154,7 +3174,6 @@ namespace exprtk set_t invalid_comb_; std::vector > error_list_; - }; struct helper_assembly @@ -3465,8 +3484,8 @@ namespace exprtk case e_logn : return logn(arg0,arg1); case e_lt : return (arg0 < arg1) ? T(1) : T(0); case e_lte : return (arg0 <= arg1) ? T(1) : T(0); - case e_eq : return (arg0 == arg1) ? T(1) : T(0); - case e_ne : return (arg0 != arg1) ? T(1) : T(0); + case e_eq : return std::equal_to()(arg0,arg1) ? T(1) : T(0); + case e_ne : return std::not_equal_to()(arg0,arg1) ? T(1) : T(0); case e_gte : return (arg0 >= arg1) ? T(1) : T(0); case e_gt : return (arg0 > arg1) ? T(1) : T(0); case e_and : return and_opr (arg0,arg1); @@ -3590,11 +3609,6 @@ namespace exprtk return std::numeric_limits::quiet_NaN(); } - virtual inline bool result() const - { - return (T(0) != value()); - } - virtual inline expression_node* branch(const std::size_t& index = 0) const { return reinterpret_cast(index * 0); @@ -3608,29 +3622,29 @@ namespace exprtk inline bool is_true(const double v) { - return (0.0 != v); + return std::not_equal_to()(0.0,v); } inline bool is_true(const long double v) { - return (0.0L != v); + return std::not_equal_to()(0.0L,v); } inline bool is_true(const float v) { - return (0.0f != v); + return std::not_equal_to()(0.0f,v); } template inline bool is_true(const expression_node* node) { - return (T(0) != node->value()); + return std::not_equal_to()(T(0),node->value()); } template inline bool is_false(const expression_node* node) { - return (T(0) == node->value()); + return std::equal_to()(T(0),node->value()); } template @@ -3997,8 +4011,8 @@ namespace exprtk typedef expression_node* expression_ptr; - null_eq_node(expression_ptr branch, const bool equality = true) - : branch_(branch), + null_eq_node(expression_ptr brnch, const bool equality = true) + : branch_(brnch), branch_deletable_(branch_deletable(branch_)), equality_(equality) {} @@ -4014,8 +4028,8 @@ namespace exprtk inline T value() const { - const T value = branch_->value(); - const bool result = details::numeric::is_nan(value); + const T v = branch_->value(); + const bool result = details::numeric::is_nan(v); if (result) return (equality_) ? T(1) : T(0); @@ -4050,8 +4064,8 @@ namespace exprtk { public: - explicit literal_node(const T& value) - : value_(value) + explicit literal_node(const T& v) + : value_(v) {} inline T value() const @@ -4088,8 +4102,8 @@ namespace exprtk { public: - explicit string_literal_node(const std::string& value) - : value_(value) + explicit string_literal_node(const std::string& v) + : value_(v) {} inline T value() const @@ -4127,10 +4141,10 @@ namespace exprtk typedef expression_node* expression_ptr; - unary_node(const operator_type& operation, - expression_ptr branch) - : operation_(operation), - branch_(branch), + unary_node(const operator_type& opr, + expression_ptr brnch) + : operation_(opr), + branch_(brnch), branch_deletable_(branch_deletable(branch_)) {} @@ -4246,10 +4260,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef std::pair branch_t; - binary_node(const operator_type& operation, + binary_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : operation_(operation) + : operation_(opr) { init_branches<2>(branch_,branch0,branch1); } @@ -4350,11 +4364,11 @@ namespace exprtk typedef expression_node* expression_ptr; typedef std::pair branch_t; - trinary_node(const operator_type& operation, + trinary_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2) - : operation_(operation) + : operation_(opr) { init_branches<3>(branch_,branch0,branch1,branch2); } @@ -4403,12 +4417,12 @@ namespace exprtk typedef expression_node* expression_ptr; typedef std::pair branch_t; - quaternary_node(const operator_type& operation, + quaternary_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2, expression_ptr branch3) - : operation_(operation) + : operation_(opr) { init_branches<4>(branch_,branch0,branch1,branch2,branch3); } @@ -4452,13 +4466,13 @@ namespace exprtk typedef expression_node* expression_ptr; typedef std::pair branch_t; - quinary_node(const operator_type& operation, + quinary_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2, expression_ptr branch3, expression_ptr branch4) - : operation_(operation) + : operation_(opr) { init_branches<5>(branch_,branch0,branch1,branch2,branch3,branch4); } @@ -4503,14 +4517,14 @@ namespace exprtk typedef expression_node* expression_ptr; typedef std::pair branch_t; - senary_node(const operator_type& operation, + senary_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2, expression_ptr branch3, expression_ptr branch4, expression_ptr branch5) - : operation_(operation) + : operation_(opr) { init_branches<6>(branch_,branch0,branch1,branch2,branch3,branch4,branch5); } @@ -5318,8 +5332,8 @@ namespace exprtk delete_value_(false) {} - variable_node(T& value) - : value_(&value), + variable_node(T& v) + : value_(&v), delete_value_(false) {} @@ -5657,11 +5671,11 @@ namespace exprtk inline T value() const { - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); - if (vec0_node_ptr_ && vec1_node_ptr_) { + binary_node::branch_[0].first->value(); + binary_node::branch_[1].first->value(); + vector_holder& vec0 = vec0_node_ptr_->ref(); vector_holder& vec1 = vec1_node_ptr_->ref(); @@ -5711,8 +5725,8 @@ namespace exprtk : value_(&null_value) {} - explicit stringvar_node(std::string& value) - : value_(&value) + explicit stringvar_node(std::string& v) + : value_(&v) {} inline bool operator <(const stringvar_node& v) const @@ -5760,8 +5774,8 @@ namespace exprtk static std::string null_value; - explicit string_range_node(std::string& value, RangePack rp) - : value_(&value), + explicit string_range_node(std::string& v, RangePack rp) + : value_(&v), rp_(rp) {} @@ -5829,8 +5843,8 @@ namespace exprtk { public: - explicit const_string_range_node(const std::string& value, RangePack rp) - : value_(value), + explicit const_string_range_node(const std::string& v, RangePack rp) + : value_(v), rp_(rp) {} @@ -5874,7 +5888,7 @@ namespace exprtk const_string_range_node& operator=(const const_string_range_node&); const std::string value_; - RangePack rp_; + RangePack rp_; }; template @@ -5888,8 +5902,8 @@ namespace exprtk : value_(&null_value) {} - explicit stringsize_node(std::string& value) - : value_(&value) + explicit stringsize_node(std::string& v) + : value_(&v) {} inline T value() const @@ -6137,11 +6151,11 @@ namespace exprtk typedef expression_node* expression_ptr; - sf3_node(const operator_type& operation, + sf3_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2) - : trinary_node(operation,branch0,branch1,branch2) + : trinary_node(opr,branch0,branch1,branch2) {} inline T value() const @@ -6161,12 +6175,12 @@ namespace exprtk typedef expression_node* expression_ptr; - sf4_node(const operator_type& operation, + sf4_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2, expression_ptr branch3) - : quaternary_node(operation,branch0,branch1,branch2,branch3) + : quaternary_node(opr,branch0,branch1,branch2,branch3) {} inline T value() const @@ -6413,10 +6427,10 @@ namespace exprtk typedef expression_node* expression_ptr; - assignment_node(const operator_type& operation, + assignment_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), var_node_ptr_(0) { if (is_variable_node(binary_node::branch_[0].first)) @@ -6431,6 +6445,7 @@ namespace exprtk { T& result = var_node_ptr_->ref(); result = binary_node::branch_[1].first->value(); + return result; } else @@ -6449,10 +6464,10 @@ namespace exprtk typedef expression_node* expression_ptr; - assignment_vec_elem_node(const operator_type& operation, + assignment_vec_elem_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec_node_ptr_(0) { if (is_vector_elem_node(binary_node::branch_[0].first)) @@ -6467,6 +6482,7 @@ namespace exprtk { T& result = vec_node_ptr_->ref(); result = binary_node::branch_[1].first->value(); + return result; } else @@ -6487,10 +6503,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - assignment_vec_node(const operator_type& operation, + assignment_vec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec_node_ptr_(0) { if (is_vector_node(binary_node::branch_[0].first)) @@ -6503,12 +6519,12 @@ namespace exprtk { if (vec_node_ptr_) { - vector_holder& vec = vec_node_ptr_->ref(); + vector_holder& vec_hldr = vec_node_ptr_->ref(); const T v = binary_node::branch_[1].first->value(); - for (std::size_t i = 0; i < vec.size(); ++i) + for (std::size_t i = 0; i < vec_hldr.size(); ++i) { - (*vec[i]) = v; + (*vec_hldr[i]) = v; } return vec_node_ptr_->value(); @@ -6546,10 +6562,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - assignment_vecvec_node(const operator_type& operation, + assignment_vecvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec0_node_ptr_(0), vec1_node_ptr_(0) { @@ -6623,10 +6639,10 @@ namespace exprtk typedef expression_node* expression_ptr; - assignment_op_node(const operator_type& operation, + assignment_op_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), var_node_ptr_(0) { if (is_variable_node(binary_node::branch_[0].first)) @@ -6641,6 +6657,7 @@ namespace exprtk { T& v = var_node_ptr_->ref(); v = Operation::process(v,binary_node::branch_[1].first->value()); + return v; } else @@ -6659,10 +6676,10 @@ namespace exprtk typedef expression_node* expression_ptr; - assignment_vec_elem_op_node(const operator_type& operation, + assignment_vec_elem_op_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec_node_ptr_(0) { if (is_vector_elem_node(binary_node::branch_[0].first)) @@ -6698,10 +6715,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - assignment_vec_op_node(const operator_type& operation, + assignment_vec_op_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec_node_ptr_(0) { if (is_vector_node(binary_node::branch_[0].first)) @@ -6714,12 +6731,12 @@ namespace exprtk { if (vec_node_ptr_) { - vector_holder& vec = vec_node_ptr_->ref(); + vector_holder& vec_hldr = vec_node_ptr_->ref(); const T v = binary_node::branch_[1].first->value(); - for (std::size_t i = 0; i < vec.size(); ++i) + for (std::size_t i = 0; i < vec_hldr.size(); ++i) { - T& vec_i = *vec[i]; + T& vec_i = *vec_hldr[i]; vec_i = Operation::process(vec_i,v); } @@ -6758,10 +6775,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - assignment_vecvec_op_node(const operator_type& operation, + assignment_vecvec_op_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec0_node_ptr_(0), vec1_node_ptr_(0) { @@ -6787,11 +6804,11 @@ namespace exprtk inline T value() const { - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); - if (vec0_node_ptr_ && vec1_node_ptr_) { + binary_node::branch_[0].first->value(); + binary_node::branch_[1].first->value(); + vector_holder& vec0 = vec0_node_ptr_->ref(); vector_holder& vec1 = vec1_node_ptr_->ref(); @@ -6840,10 +6857,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - eqineq_vecvec_node(const operator_type& operation, + eqineq_vecvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec0_node_ptr_(0), vec1_node_ptr_(0) { @@ -6879,11 +6896,11 @@ namespace exprtk inline T value() const { - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); - if (vec0_node_ptr_ && vec1_node_ptr_) { + binary_node::branch_[0].first->value(); + binary_node::branch_[1].first->value(); + vector_holder& vec0 = vec0_node_ptr_->ref(); vector_holder& vec1 = vec1_node_ptr_->ref(); @@ -6891,7 +6908,7 @@ namespace exprtk for (std::size_t i = 0; i < vec_size; ++i) { - if (T(0) == Operation::process(*vec0[i],*vec1[i])) + if (std::equal_to()(T(0),Operation::process(*vec0[i],*vec1[i]))) { return T(0); } @@ -6933,10 +6950,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - eqineq_vecval_node(const operator_type& operation, + eqineq_vecval_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec_node_ptr_(0) { if (is_vector_node(binary_node::branch_[0].first)) @@ -6956,18 +6973,18 @@ namespace exprtk inline T value() const { - binary_node::branch_[0].first->value(); - T v = binary_node::branch_[1].first->value(); - if (vec_node_ptr_) { - vector_holder& vec = vec_node_ptr_->ref(); + binary_node::branch_[0].first->value(); + T v = binary_node::branch_[1].first->value(); - std::size_t vec_size = vec.size(); + vector_holder& vec_hldr = vec_node_ptr_->ref(); + + std::size_t vec_size = vec_hldr.size(); for (std::size_t i = 0; i < vec_size; ++i) { - if (T(0) == Operation::process(*vec[i],v)) + if (std::equal_to()(T(0),Operation::process(*vec_hldr[i],v))) { return T(0); } @@ -7008,10 +7025,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - eqineq_valvec_node(const operator_type& operation, + eqineq_valvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec_node_ptr_(0) { if (is_vector_node(binary_node::branch_[1].first)) @@ -7031,18 +7048,18 @@ namespace exprtk inline T value() const { - T v = binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); - if (vec_node_ptr_) { - vector_holder& vec = vec_node_ptr_->ref(); + T v = binary_node::branch_[0].first->value(); + binary_node::branch_[1].first->value(); - std::size_t vec_size = vec.size(); + vector_holder& vec_hldr = vec_node_ptr_->ref(); + + std::size_t vec_size = vec_hldr.size(); for (std::size_t i = 0; i < vec_size; ++i) { - if (T(0) == Operation::process(v,*vec[i])) + if (std::equal_to()(T(0),Operation::process(v,*vec_hldr[i]))) { return T(0); } @@ -7084,10 +7101,10 @@ namespace exprtk typedef vector_node* vector_node_ptr; typedef vector_holder* vector_holder_ptr; - vecarith_vecvec_node(const operator_type& operation, + vecarith_vecvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec0_node_ptr_(0), vec1_node_ptr_(0), vec_size_ (0), @@ -7144,11 +7161,11 @@ namespace exprtk inline T value() const { - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); - if (vec0_node_ptr_ && vec1_node_ptr_) { + binary_node::branch_[0].first->value(); + binary_node::branch_[1].first->value(); + vector_holder& vec0 = vec0_node_ptr_->ref(); vector_holder& vec1 = vec1_node_ptr_->ref(); vector_holder& vec2 = *temp_; @@ -7204,10 +7221,10 @@ namespace exprtk typedef vector_node* vector_node_ptr; typedef vector_holder* vector_holder_ptr; - vecarith_vecval_node(const operator_type& operation, + vecarith_vecval_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec0_node_ptr_(0), vec_size_ (0), data_ (0), @@ -7248,11 +7265,11 @@ namespace exprtk inline T value() const { - binary_node::branch_[0].first->value(); - const T v = binary_node::branch_[1].first->value(); - if (vec0_node_ptr_) { + binary_node::branch_[0].first->value(); + const T v = binary_node::branch_[1].first->value(); + vector_holder& vec0 = vec0_node_ptr_->ref(); vector_holder& vec1 = *temp_; @@ -7304,10 +7321,10 @@ namespace exprtk typedef vector_node* vector_node_ptr; typedef vector_holder* vector_holder_ptr; - vecarith_valvec_node(const operator_type& operation, + vecarith_valvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1), + : binary_node(opr,branch0,branch1), vec1_node_ptr_(0), vec_size_ (0), data_ (0), @@ -7348,11 +7365,11 @@ namespace exprtk inline T value() const { - const T v = binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); - if (vec1_node_ptr_) { + const T v = binary_node::branch_[0].first->value(); + binary_node::branch_[1].first->value(); + vector_holder& vec1 = vec1_node_ptr_->ref(); vector_holder& vec2 = *temp_; @@ -7404,8 +7421,8 @@ namespace exprtk typedef vector_node* vector_node_ptr; typedef vector_holder* vector_holder_ptr; - unary_vector_node(const operator_type& operation, expression_ptr branch0) - : unary_node(operation,branch0), + unary_vector_node(const operator_type& opr, expression_ptr branch0) + : unary_node(opr,branch0), vec0_node_ptr_(0), vec_size_ (0), data_ (0), @@ -7498,17 +7515,19 @@ namespace exprtk typedef expression_node* expression_ptr; - scand_node(const operator_type& operation, + scand_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1) + : binary_node(opr,branch0,branch1) {} inline T value() const { return ( - (T(0) != binary_node::branch_[0].first->value()) && - (T(0) != binary_node::branch_[1].first->value()) + std::not_equal_to() + (T(0),binary_node::branch_[0].first->value()) && + std::not_equal_to() + (T(0),binary_node::branch_[1].first->value()) ) ? T(1) : T(0); } }; @@ -7520,17 +7539,19 @@ namespace exprtk typedef expression_node* expression_ptr; - scor_node(const operator_type& operation, + scor_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) - : binary_node(operation,branch0,branch1) + : binary_node(opr,branch0,branch1) {} inline T value() const { return ( - (T(0) != binary_node::branch_[0].first->value()) || - (T(0) != binary_node::branch_[1].first->value()) + std::not_equal_to() + (T(0),binary_node::branch_[0].first->value()) || + std::not_equal_to() + (T(0),binary_node::branch_[1].first->value()) ) ? T(1) : T(0); } }; @@ -8091,7 +8112,7 @@ namespace exprtk struct eq_op : public opr_base { typedef typename opr_base::Type Type; - static inline T process(Type t1, Type t2) { return ((t1 == t2) ? T(1) : T(0)); } + static inline T process(Type t1, Type t2) { return (std::equal_to()(t1,t2) ? T(1) : T(0)); } static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); } static inline typename expression_node::node_type type() { return expression_node::e_eq; } static inline details::operator_type operation() { return details::e_eq; } @@ -8101,7 +8122,7 @@ namespace exprtk struct ne_op : public opr_base { typedef typename opr_base::Type Type; - static inline T process(Type t1, Type t2) { return ((t1 != t2) ? T(1) : T(0)); } + static inline T process(Type t1, Type t2) { return (std::not_equal_to()(t1,t2) ? T(1) : T(0)); } static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); } static inline typename expression_node::node_type type() { return expression_node::e_ne; } static inline details::operator_type operation() { return details::e_ne; } @@ -8568,7 +8589,7 @@ namespace exprtk { for (std::size_t i = 0; i < arg_list.size(); ++i) { - if (T(0) == value(arg_list[i])) + if (std::equal_to()(T(0),value(arg_list[i]))) return T(0); } @@ -8580,15 +8601,16 @@ namespace exprtk template static inline T process_1(const Sequence& arg_list) { - return (T(0) != value(arg_list[0])) ? T(1) : T(0); + return std::not_equal_to() + (T(0),value(arg_list[0])) ? T(1) : T(0); } template static inline T process_2(const Sequence& arg_list) { return ( - (T(0) != value(arg_list[0])) && - (T(0) != value(arg_list[1])) + std::not_equal_to()(T(0),value(arg_list[0])) && + std::not_equal_to()(T(0),value(arg_list[1])) ) ? T(1) : T(0); } @@ -8596,9 +8618,9 @@ namespace exprtk static inline T process_3(const Sequence& arg_list) { return ( - (T(0) != value(arg_list[0])) && - (T(0) != value(arg_list[1])) && - (T(0) != value(arg_list[2])) + std::not_equal_to()(T(0),value(arg_list[0])) && + std::not_equal_to()(T(0),value(arg_list[1])) && + std::not_equal_to()(T(0),value(arg_list[2])) ) ? T(1) : T(0); } @@ -8606,10 +8628,10 @@ namespace exprtk static inline T process_4(const Sequence& arg_list) { return ( - (T(0) != value(arg_list[0])) && - (T(0) != value(arg_list[1])) && - (T(0) != value(arg_list[2])) && - (T(0) != value(arg_list[3])) + std::not_equal_to()(T(0),value(arg_list[0])) && + std::not_equal_to()(T(0),value(arg_list[1])) && + std::not_equal_to()(T(0),value(arg_list[2])) && + std::not_equal_to()(T(0),value(arg_list[3])) ) ? T(1) : T(0); } @@ -8617,11 +8639,11 @@ namespace exprtk static inline T process_5(const Sequence& arg_list) { return ( - (T(0) != value(arg_list[0])) && - (T(0) != value(arg_list[1])) && - (T(0) != value(arg_list[2])) && - (T(0) != value(arg_list[3])) && - (T(0) != value(arg_list[4])) + std::not_equal_to()(T(0),value(arg_list[0])) && + std::not_equal_to()(T(0),value(arg_list[1])) && + std::not_equal_to()(T(0),value(arg_list[2])) && + std::not_equal_to()(T(0),value(arg_list[3])) && + std::not_equal_to()(T(0),value(arg_list[4])) ) ? T(1) : T(0); } }; @@ -8647,7 +8669,7 @@ namespace exprtk { for (std::size_t i = 0; i < arg_list.size(); ++i) { - if (T(0) != value(arg_list[i])) + if (std::not_equal_to()(T(0),value(arg_list[i]))) return T(1); } @@ -8659,15 +8681,16 @@ namespace exprtk template static inline T process_1(const Sequence& arg_list) { - return (T(0) != value(arg_list[0])) ? T(1) : T(0); + return std::not_equal_to() + (T(0),value(arg_list[0])) ? T(1) : T(0); } template static inline T process_2(const Sequence& arg_list) { return ( - (T(0) != value(arg_list[0])) || - (T(0) != value(arg_list[1])) + std::not_equal_to()(T(0),value(arg_list[0])) || + std::not_equal_to()(T(0),value(arg_list[1])) ) ? T(1) : T(0); } @@ -8675,9 +8698,9 @@ namespace exprtk static inline T process_3(const Sequence& arg_list) { return ( - (T(0) != value(arg_list[0])) || - (T(0) != value(arg_list[1])) || - (T(0) != value(arg_list[2])) + std::not_equal_to()(T(0),value(arg_list[0])) || + std::not_equal_to()(T(0),value(arg_list[1])) || + std::not_equal_to()(T(0),value(arg_list[2])) ) ? T(1) : T(0); } @@ -8685,10 +8708,10 @@ namespace exprtk static inline T process_4(const Sequence& arg_list) { return ( - (T(0) != value(arg_list[0])) || - (T(0) != value(arg_list[1])) || - (T(0) != value(arg_list[2])) || - (T(0) != value(arg_list[3])) + std::not_equal_to()(T(0),value(arg_list[0])) || + std::not_equal_to()(T(0),value(arg_list[1])) || + std::not_equal_to()(T(0),value(arg_list[2])) || + std::not_equal_to()(T(0),value(arg_list[3])) ) ? T(1) : T(0); } @@ -8696,11 +8719,11 @@ namespace exprtk static inline T process_5(const Sequence& arg_list) { return ( - (T(0) != value(arg_list[0])) || - (T(0) != value(arg_list[1])) || - (T(0) != value(arg_list[2])) || - (T(0) != value(arg_list[3])) || - (T(0) != value(arg_list[4])) + std::not_equal_to()(T(0),value(arg_list[0])) || + std::not_equal_to()(T(0),value(arg_list[1])) || + std::not_equal_to()(T(0),value(arg_list[2])) || + std::not_equal_to()(T(0),value(arg_list[3])) || + std::not_equal_to()(T(0),value(arg_list[4])) ) ? T(1) : T(0); } }; @@ -8885,6 +8908,7 @@ namespace exprtk for (std::size_t i = 1; i < vec.size(); ++i) { T v_i = (*vec[i]); + if (v_i < result) result = v_i; } @@ -9068,8 +9092,8 @@ namespace exprtk typedef expression_node* expression_ptr; typedef Operation operation_t; - explicit unary_variable_node(const T& v) - : v_(v) + explicit unary_variable_node(const T& var) + : v_(var) {} inline T value() const @@ -9112,12 +9136,13 @@ namespace exprtk typedef typename functor_t::bfunc_t bfunc_t; typedef typename functor_t::ufunc_t ufunc_t; - explicit uvouv_node(const T& v0,const T& v1, ufunc_t u0, ufunc_t u1, bfunc_t f) - : v0_(v0), - v1_(v1), - u0_(u0), - u1_(u1), - f_ (f ) + explicit uvouv_node(const T& var0,const T& var1, + ufunc_t uf0, ufunc_t uf1, bfunc_t bf) + : v0_(var0), + v1_(var1), + u0_(uf0), + u1_(uf1), + f_ (bf) {} inline T value() const @@ -9180,8 +9205,8 @@ namespace exprtk typedef expression_node* expression_ptr; typedef Operation operation_t; - explicit unary_branch_node(expression_ptr branch) - : branch_(branch), + explicit unary_branch_node(expression_ptr brnch) + : branch_(brnch), branch_deletable_(branch_deletable(branch_)) {} @@ -9242,6 +9267,9 @@ namespace exprtk template <> struct param_to_str<0> { static std::string result() { static const std::string r("c"); return r; } }; + #define exprtk_crtype(Type) \ + param_to_str::result>::result() \ + template struct T0oT1oT2process { @@ -9259,9 +9287,9 @@ namespace exprtk template static inline std::string id() { - static const std::string result = "(" + param_to_str::result>::result() + "o" + - param_to_str::result>::result() + ")o(" + - param_to_str::result>::result() + ")" ; + static const std::string result = "(" + exprtk_crtype(T0) + "o" + + exprtk_crtype(T1) + ")o(" + + exprtk_crtype(T2) + ")" ; return result; } }; @@ -9277,9 +9305,9 @@ namespace exprtk template static inline std::string id() { - static const std::string result = "(" + param_to_str::result>::result() + ")o(" + - param_to_str::result>::result() + "o" + - param_to_str::result>::result() + ")" ; + static const std::string result = "(" + exprtk_crtype(T0) + ")o(" + + exprtk_crtype(T1) + "o" + + exprtk_crtype(T2) + ")" ; return result; } }; @@ -9304,10 +9332,10 @@ namespace exprtk template static inline std::string id() { - static const std::string result = "(" + param_to_str::result>::result() + "o" + - param_to_str::result>::result() + ")o" + - "(" + param_to_str::result>::result() + "o" + - param_to_str::result>::result() + ")" ; + static const std::string result = "(" + exprtk_crtype(T0) + "o" + + exprtk_crtype(T1) + ")o" + + "(" + exprtk_crtype(T2) + "o" + + exprtk_crtype(T3) + ")" ; return result; } }; @@ -9324,10 +9352,10 @@ namespace exprtk template static inline std::string id() { - static const std::string result = "(" + param_to_str::result>::result() + ")o((" + - param_to_str::result>::result() + ")o(" + - param_to_str::result>::result() + "o" + - param_to_str::result>::result() + "))" ; + static const std::string result = "(" + exprtk_crtype(T0) + ")o((" + + exprtk_crtype(T1) + ")o(" + + exprtk_crtype(T2) + "o" + + exprtk_crtype(T3) + "))" ; return result; } }; @@ -9345,10 +9373,10 @@ namespace exprtk template static inline std::string id() { - static const std::string result = "(" + param_to_str::result>::result() + ")o((" + - param_to_str::result>::result() + "o" + - param_to_str::result>::result() + ")o(" + - param_to_str::result>::result() + "))" ; + static const std::string result = "(" + exprtk_crtype(T0) + ")o((" + + exprtk_crtype(T1) + "o" + + exprtk_crtype(T2) + ")o(" + + exprtk_crtype(T3) + "))" ; return result; } }; @@ -9366,10 +9394,10 @@ namespace exprtk template static inline std::string id() { - static const std::string result = "((" + param_to_str::result>::result() + "o" + - param_to_str::result>::result() + ")o(" + - param_to_str::result>::result() + "))o(" + - param_to_str::result>::result() + ")"; + static const std::string result = "((" + exprtk_crtype(T0) + "o" + + exprtk_crtype(T1) + ")o(" + + exprtk_crtype(T2) + "))o(" + + exprtk_crtype(T3) + ")"; return result; } }; @@ -9387,15 +9415,17 @@ namespace exprtk template static inline std::string id() { - static const std::string result = "((" + param_to_str::result>::result() + ")o(" + - param_to_str::result>::result() + "o" + - param_to_str::result>::result() + "))o(" + - param_to_str::result>::result() + ")" ; + static const std::string result = "((" + exprtk_crtype(T0) + ")o(" + + exprtk_crtype(T1) + "o" + + exprtk_crtype(T2) + "))o(" + + exprtk_crtype(T3) + ")" ; return result; } }; }; + #undef exprtk_crtype + template struct nodetype_T0oT1 { static const typename expression_node::node_type result; }; template @@ -9479,10 +9509,10 @@ namespace exprtk typedef T value_type; typedef T0oT1 node_type; - T0oT1(T0 t0, T1 t1, const bfunc_t f) - : t0_(t0), - t1_(t1), - f_(f) + T0oT1(T0 p0, T1 p1, const bfunc_t p2) + : t0_(p0), + t1_(p1), + f_ (p2) {} inline typename expression_node::node_type type() const @@ -9518,10 +9548,10 @@ namespace exprtk template static inline expression_node* allocate(Allocator& allocator, - T0 t0, T1 t1, - bfunc_t f) + T0 p0, T1 p1, + bfunc_t p2) { - return allocator.template allocate_type(t0,t1,f); + return allocator.template allocate_type(p0,p1,p2); } private: @@ -9545,12 +9575,12 @@ namespace exprtk typedef T0oT1oT2 node_type; typedef ProcessMode process_mode_t; - T0oT1oT2(T0 t0, T1 t1, T2 t2, const bfunc_t f0, const bfunc_t f1) - : t0_(t0), - t1_(t1), - t2_(t2), - f0_(f0), - f1_(f1) + T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4) + : t0_(p0), + t1_(p1), + t2_(p2), + f0_(p3), + f1_(p4) {} inline typename expression_node::node_type type() const @@ -9605,9 +9635,9 @@ namespace exprtk } template - static inline expression_node* allocate(Allocator& allocator, T0 t0, T1 t1, T2 t2, bfunc_t f0, bfunc_t f1) + static inline expression_node* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4) { - return allocator.template allocate_type(t0,t1,t2,f0,f1); + return allocator.template allocate_type(p0,p1,p2,p3,p4); } private: @@ -9637,14 +9667,14 @@ namespace exprtk typedef T0oT1oT2oT3 node_type; typedef ProcessMode process_mode_t; - T0oT1oT2oT3(T0 t0, T1 t1, T2 t2, T3 t3, bfunc_t f0, bfunc_t f1, bfunc_t f2) - : t0_(t0), - t1_(t1), - t2_(t2), - t3_(t3), - f0_(f0), - f1_(f1), - f2_(f2) + T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6) + : t0_(p0), + t1_(p1), + t2_(p2), + t3_(p3), + f0_(p4), + f1_(p5), + f2_(p6) {} inline T value() const @@ -9699,10 +9729,10 @@ namespace exprtk template static inline expression_node* allocate(Allocator& allocator, - T0 t0, T1 t1, T2 t2, T3 t3, - bfunc_t f0, bfunc_t f1, bfunc_t f2) + T0 p0, T1 p1, T2 p2, T3 p3, + bfunc_t p4, bfunc_t p5, bfunc_t p6) { - return allocator.template allocate_type(t0,t1,t2,t3,f0,f1,f2); + return allocator.template allocate_type(p0,p1,p2,p3,p4,p5,p6); } private: @@ -9729,11 +9759,11 @@ namespace exprtk typedef T value_type; typedef T0oT1oT2_sf3 node_type; - T0oT1oT2_sf3(T0 t0, T1 t1, T2 t2, const tfunc_t f) - : t0_(t0), - t1_(t1), - t2_(t2), - f_(f) + T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3) + : t0_(p0), + t1_(p1), + t2_(p2), + f_(p3) {} inline typename expression_node::node_type type() const @@ -9783,9 +9813,9 @@ namespace exprtk } template - static inline expression_node* allocate(Allocator& allocator, T0 t0, T1 t1, T2 t2, tfunc_t f) + static inline expression_node* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3) { - return allocator.template allocate_type(t0,t1,t2,f); + return allocator.template allocate_type(p0,p1,p2,p3); } private: @@ -9821,10 +9851,10 @@ namespace exprtk typedef T value_type; typedef T0oT1oT2_sf3ext node_type; - T0oT1oT2_sf3ext(T0 t0, T1 t1, T2 t2) - : t0_(t0), - t1_(t1), - t2_(t2) + T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2) + : t0_(p0), + t1_(p1), + t2_(p2) {} inline typename expression_node::node_type type() const @@ -9869,9 +9899,9 @@ namespace exprtk } template - static inline expression_node* allocate(Allocator& allocator, T0 t0, T1 t1, T2 t2) + static inline expression_node* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2) { - return allocator.template allocate_type(t0,t1,t2); + return allocator.template allocate_type(p0,p1,p2); } private: @@ -9908,12 +9938,12 @@ namespace exprtk typedef T value_type; typedef T0oT1oT2oT3_sf4 node_type; - T0oT1oT2oT3_sf4(T0 t0, T1 t1, T2 t2, T3 t3, const qfunc_t f) - : t0_(t0), - t1_(t1), - t2_(t2), - t3_(t3), - f_(f) + T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4) + : t0_(p0), + t1_(p1), + t2_(p2), + t3_(p3), + f_(p4) {} inline typename expression_node::node_type type() const @@ -9968,9 +9998,9 @@ namespace exprtk } template - static inline expression_node* allocate(Allocator& allocator, T0 t0, T1 t1, T2 t2, T3 t3, qfunc_t f) + static inline expression_node* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4) { - return allocator.template allocate_type(t0,t1,t2,t3,f); + return allocator.template allocate_type(p0,p1,p2,p3,p4); } private: @@ -9995,11 +10025,11 @@ namespace exprtk typedef T value_type; typedef T0oT1oT2oT3_sf4ext node_type; - T0oT1oT2oT3_sf4ext(T0 t0, T1 t1, T2 t2, T3 t3) - : t0_(t0), - t1_(t1), - t2_(t2), - t3_(t3) + T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3) + : t0_(p0), + t1_(p1), + t2_(p2), + t3_(p3) {} inline typename expression_node::node_type type() const @@ -10049,9 +10079,9 @@ namespace exprtk } template - static inline expression_node* allocate(Allocator& allocator, T0 t0, T1 t1, T2 t2, T3 t3) + static inline expression_node* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3) { - return allocator.template allocate_type(t0,t1,t2,t3); + return allocator.template allocate_type(p0,p1,p2,p3); } private: @@ -10118,9 +10148,9 @@ namespace exprtk typedef Operation operation_t; // variable op variable node - explicit vov_node(const T& v0, const T& v1) - : v0_(v0), - v1_(v1) + explicit vov_node(const T& var0, const T& var1) + : v0_(var0), + v1_(var1) {} inline T value() const @@ -10168,9 +10198,9 @@ namespace exprtk typedef Operation operation_t; // constant op variable node - explicit cov_node(const T& c, const T& v) - : c_(c), - v_(v) + explicit cov_node(const T& const_var, const T& var) + : c_(const_var), + v_(var) {} inline T value() const @@ -10218,9 +10248,9 @@ namespace exprtk typedef Operation operation_t; // variable op constant node - explicit voc_node(const T& v, const T& c) - : v_(v), - c_(c) + explicit voc_node(const T& var, const T& const_var) + : v_(var), + c_(const_var) {} inline T value() const @@ -10264,10 +10294,10 @@ namespace exprtk typedef Operation operation_t; // variable op constant node - explicit vob_node(const T& v, const expression_ptr branch) - : v_(v) + explicit vob_node(const T& var, const expression_ptr brnch) + : v_(var) { - init_branches<1>(branch_,branch); + init_branches<1>(branch_,brnch); } ~vob_node() @@ -10314,10 +10344,10 @@ namespace exprtk typedef Operation operation_t; // variable op constant node - explicit bov_node(const expression_ptr branch, const T& v) - : v_(v) + explicit bov_node(const expression_ptr brnch, const T& var) + : v_(var) { - init_branches<1>(branch_,branch); + init_branches<1>(branch_,brnch); } ~bov_node() @@ -10364,10 +10394,10 @@ namespace exprtk typedef Operation operation_t; // variable op constant node - explicit cob_node(const T c, const expression_ptr branch) - : c_(c) + explicit cob_node(const T const_var, const expression_ptr brnch) + : c_(const_var) { - init_branches<1>(branch_,branch); + init_branches<1>(branch_,brnch); } ~cob_node() @@ -10425,10 +10455,10 @@ namespace exprtk typedef Operation operation_t; // variable op constant node - explicit boc_node(const expression_ptr branch, const T c) - : c_(c) + explicit boc_node(const expression_ptr brnch, const T const_var) + : c_(const_var) { - init_branches<1>(branch_,branch); + init_branches<1>(branch_,brnch); } ~boc_node() @@ -10486,9 +10516,9 @@ namespace exprtk typedef Operation operation_t; // string op string node - explicit sos_node(SType0 s0, SType1 s1) - : s0_(s0), - s1_(s1) + explicit sos_node(SType0 p0, SType1 p1) + : s0_(p0), + s1_(p1) {} inline T value() const @@ -10536,9 +10566,9 @@ namespace exprtk typedef Operation operation_t; // string-range op string node - explicit str_xrox_node(SType0 s0, SType1 s1, RangePack rp0) - : s0_(s0), - s1_(s1), + explicit str_xrox_node(SType0 p0, SType1 p1, RangePack rp0) + : s0_(p0), + s1_(p1), rp0_(rp0) {} @@ -10599,9 +10629,9 @@ namespace exprtk typedef Operation operation_t; // string op string range node - explicit str_xoxr_node(SType0 s0, SType1 s1, RangePack rp1) - : s0_(s0), - s1_(s1), + explicit str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1) + : s0_(p0), + s1_(p1), rp1_(rp1) {} @@ -10662,9 +10692,9 @@ namespace exprtk typedef Operation operation_t; // string-range op string-range node - explicit str_xroxr_node(SType0 s0, SType1 s1, RangePack rp0, RangePack rp1) - : s0_(s0), - s1_(s1), + explicit str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1) + : s0_(p0), + s1_(p1), rp0_(rp0), rp1_(rp1) {} @@ -10737,10 +10767,10 @@ namespace exprtk typedef Operation operation_t; // variable op variable node - explicit sosos_node(SType0 s0, SType1 s1, SType2 s2) - : s0_(s0), - s1_(s1), - s2_(s2) + explicit sosos_node(SType0 p0, SType1 p1, SType2 p2) + : s0_(p0), + s1_(p1), + s2_(p2) {} inline T value() const @@ -11481,7 +11511,7 @@ namespace exprtk } template - inline bool add_impl(const std::string& symbol_name, RType t, const bool is_constant) + inline bool add_impl(const std::string& symbol_name, RType t, const bool is_const) { if (symbol_name.size() > 1) { @@ -11498,7 +11528,7 @@ namespace exprtk if (map.end() == itr) { - map[symbol_name] = Tie::make(t,is_constant); + map[symbol_name] = Tie::make(t,is_const); ++size; } @@ -11507,66 +11537,66 @@ namespace exprtk struct tie_array { - static inline std::pair make(std::pair v, const bool is_constant = false) + static inline std::pair make(std::pair v, const bool is_const = false) { - return std::make_pair(is_constant,new vector_t(v.first,v.second)); + return std::make_pair(is_const,new vector_t(v.first,v.second)); } }; struct tie_stdvec { template - static inline std::pair make(std::vector& v, const bool is_constant = false) + static inline std::pair make(std::vector& v, const bool is_const = false) { - return std::make_pair(is_constant,new vector_t(v)); + return std::make_pair(is_const,new vector_t(v)); } }; struct tie_stddeq { template - static inline std::pair make(std::deque& v, const bool is_constant = false) + static inline std::pair make(std::deque& v, const bool is_const = false) { - return std::make_pair(is_constant,new vector_t(v)); + return std::make_pair(is_const,new vector_t(v)); } }; template - inline bool add(const std::string& symbol_name, T (&v)[v_size], const bool is_constant = false) + inline bool add(const std::string& symbol_name, T (&v)[v_size], const bool is_const = false) { - return add_impl >(symbol_name,std::make_pair(v,v_size),is_constant); + return add_impl >(symbol_name,std::make_pair(v,v_size),is_const); } - inline bool add(const std::string& symbol_name, T* v, const std::size_t v_size, const bool is_constant = false) + inline bool add(const std::string& symbol_name, T* v, const std::size_t v_size, const bool is_const = false) { - return add_impl >(symbol_name,std::make_pair(v,v_size),is_constant); + return add_impl >(symbol_name,std::make_pair(v,v_size),is_const); } template - inline bool add(const std::string& symbol_name, std::vector& v, const bool is_constant = false) + inline bool add(const std::string& symbol_name, std::vector& v, const bool is_const = false) { - return add_impl&>(symbol_name,v,is_constant); + return add_impl&>(symbol_name,v,is_const); } template - inline bool add(const std::string& symbol_name, std::deque& v, const bool is_constant = false) + inline bool add(const std::string& symbol_name, std::deque& v, const bool is_const = false) { - return add_impl&>(symbol_name,v,is_constant); + return add_impl&>(symbol_name,v,is_const); } - inline bool add(const std::string& symbol_name, RawType& t, const bool is_constant = false) + inline bool add(const std::string& symbol_name, RawType& t, const bool is_const = false) { struct tie { - static inline std::pair make(T& t,const bool is_constant = false) + static inline std::pair make(T& t,const bool is_const = false) { - return std::make_pair(is_constant,new variable_node_t(t)); + return std::make_pair(is_const,new variable_node_t(t)); } #ifndef exprtk_disable_string_capabilities - static inline std::pair make(std::string& t,const bool is_constant = false) + static inline std::pair make(std::string& t,const bool is_const = false) { - return std::make_pair(is_constant,new stringvar_node_t(t)); + return std::make_pair(is_const,new stringvar_node_t(t)); } #endif @@ -11575,9 +11605,9 @@ namespace exprtk return std::make_pair(is_constant,&t); } - static inline std::pair make(vararg_function_t& t, const bool is_constant = false) + static inline std::pair make(vararg_function_t& t, const bool is_const = false) { - return std::make_pair(is_constant,&t); + return std::make_pair(is_const,&t); } }; @@ -11596,7 +11626,7 @@ namespace exprtk if (map.end() == itr) { - map[symbol_name] = tie::make(t,is_constant); + map[symbol_name] = tie::make(t,is_const); ++size; } @@ -11974,13 +12004,13 @@ namespace exprtk return local_data().variable_store.get(variable_name); } - inline variable_ptr get_variable(const T& variable_ref) const + inline variable_ptr get_variable(const T& var_ref) const { if (!valid()) return reinterpret_cast(0); else return local_data().variable_store.get_from_varptr( - reinterpret_cast(&variable_ref)); + reinterpret_cast(&var_ref)); } #ifndef exprtk_disable_string_capabilities @@ -12429,9 +12459,9 @@ namespace exprtk inline void load_from(const symbol_table& st) { - std::vector name_list; - { + std::vector name_list; + st.local_data().function_store.get_list(name_list); if (!name_list.empty()) @@ -12442,8 +12472,6 @@ namespace exprtk add_function(name_list[i],ifunc); } } - - name_list.clear(); } { @@ -12459,8 +12487,6 @@ namespace exprtk add_vararg_function(name_list[i],ivafunc); } } - - name_list.clear(); } } @@ -12501,7 +12527,6 @@ namespace exprtk } st_holder* holder_; - }; template @@ -12628,6 +12653,7 @@ namespace exprtk expression_holder_->ref_count++; symbol_table_ = e.symbol_table_; } + return *this; } @@ -12889,8 +12915,8 @@ namespace exprtk inline bool update_error(type& error, const std::string& expression) { if ( - expression.empty() || - (error.token.position > expression.size()) || + expression.empty() || + (error.token.position > expression.size()) || (std::numeric_limits::max() == error.token.position) ) { @@ -13305,11 +13331,15 @@ namespace exprtk virtual ~unknown_symbol_resolver() {} - virtual bool process(const std::string& /*unknown_symbol*/, symbol_type& st, T& default_value, std::string& error_message) + virtual bool process(const std::string& /*unknown_symbol*/, + symbol_type& st, + T& default_value, + std::string& error_message) { st = e_variable_type; default_value = T(0); error_message = ""; + return true; } }; @@ -13717,7 +13747,7 @@ namespace exprtk inline void disable_unknown_symbol_resolver() { - resolve_unknown_symbol_ = false; + resolve_unknown_symbol_ = false; unknown_symbol_resolver_ = &default_usr_; } @@ -15997,9 +16027,9 @@ namespace exprtk const scope_element& se = sem_.get_element(symbol); if ( - (se.name != symbol) || - (scope_element::e_vector != se.type) || - (se.depth > scope_depth_) + (se.name != symbol) || + (se.depth > scope_depth_) || + (scope_element::e_vector != se.type) ) { if (0 == (vec = symbol_table_.get_vector(symbol))) @@ -16120,6 +16150,7 @@ namespace exprtk for (std::size_t i = 0; i < NumberOfParameters; ++i) { branch[i] = p.parse_expression(); + if (0 == branch[i]) { return p.error_node(); @@ -16303,7 +16334,8 @@ namespace exprtk if ( (vector_size <= T(0)) || - (0 != (vector_size - details::numeric::trunc(vector_size))) + std::not_equal_to() + (T(0),vector_size - details::numeric::trunc(vector_size)) ) { set_error( @@ -16812,7 +16844,7 @@ namespace exprtk scope_element& se = sem_.get_element(var0_name); if ( - (se.active) && + (se.active) && (se.name == var0_name) && (scope_element::e_variable == se.type) ) @@ -17086,20 +17118,20 @@ namespace exprtk if (create_result) { - expression_node_ptr variable = symbol_table_.get_variable(symbol); + expression_node_ptr var = symbol_table_.get_variable(symbol); - if (variable) + if (var) { cache_symbol(symbol); if (symbol_table_.is_constant_node(symbol)) { - variable = expression_generator_(variable->value()); + var = expression_generator_(var->value()); } next_token(); - return variable; + return var; } } @@ -17331,7 +17363,7 @@ namespace exprtk } if ( - branch && + branch && (e_level00 == precedence) && token_is(token_t::e_ternary,false) ) @@ -17487,9 +17519,9 @@ namespace exprtk node_allocator_ = &na; } - inline void set_strength_reduction_state(const bool strength_reduction_enabled) + inline void set_strength_reduction_state(const bool enabled) { - strength_reduction_enabled_ = strength_reduction_enabled; + strength_reduction_enabled_ = enabled; } inline bool strength_reduction_enabled() const @@ -18021,6 +18053,7 @@ namespace exprtk return synthesize_null_expression(operation,branch); expression_node_ptr result = error_node(); + #ifndef exprtk_disable_enhanced_features if (synthesize_expression(operation,branch,result)) return result; @@ -18035,7 +18068,8 @@ namespace exprtk 3. c o boc -> boc 4. boc o c -> boc */ - expression_node_ptr result = error_node(); + result = error_node(); + if (cocob_optimizable(operation,branch)) result = synthesize_cocob_expression::process(*this,operation,branch); else if (coboc_optimizable(operation,branch) && (0 == result)) @@ -18966,6 +19000,7 @@ namespace exprtk nse.depth = parser_->scope_depth_; nse.data = 0; nse.var_node = new variable_node_t((*v)); + if (!parser_->sem_.add_element(nse)) { parser_->set_synthesis_error("Failed to add new local vector element to SEM [1]"); @@ -19295,17 +19330,29 @@ namespace exprtk expression_node_ptr result = error_node(); if (details::is_constant_node(branch[0])) { - if ((details::e_scand == operation) && (T(0) == branch[0]->value())) + if ( + (details::e_scand == operation) && + std::equal_to()(T(0),branch[0]->value()) + ) result = node_allocator_->allocate_c(T(0)); - else if ((details::e_scor == operation) && (T(0) != branch[0]->value())) + else if ( + (details::e_scor == operation) && + std::not_equal_to()(T(0),branch[0]->value()) + ) result = node_allocator_->allocate_c(T(1)); } if (details::is_constant_node(branch[1]) && (0 == result)) { - if ((details::e_scand == operation) && (T(0) == branch[1]->value())) + if ( + (details::e_scand == operation) && + std::equal_to()(T(0),branch[1]->value()) + ) result = node_allocator_->allocate_c(T(0)); - else if ((details::e_scor == operation) && (T(0) != branch[1]->value())) + else if ( + (details::e_scor == operation) && + std::not_equal_to()(T(0),branch[1]->value()) + ) result = node_allocator_->allocate_c(T(1)); } @@ -19389,7 +19436,7 @@ namespace exprtk if (0 == p) return node_allocator_->allocate_c(T(1)); - else if (T(2) == c) + else if (std::equal_to()(T(2),c)) { return node_allocator_-> template allocate_rr > >(v,v); @@ -20289,7 +20336,7 @@ namespace exprtk if (expr_gen.cardinal_pow_optimizable(operation,c)) { - if (T(1) == c) + if (std::equal_to()(T(1),c)) return branch[0]; else return expr_gen.cardinal_pow_optimization(v,c); @@ -20358,7 +20405,6 @@ namespace exprtk return true; } - }; struct synthesize_sf4ext_expression @@ -22006,9 +22052,9 @@ namespace exprtk } // (c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1) else if ( - (c0 == c1) && - (details::e_mul == o0) && - (details::e_mul == o2) && + (std::equal_to()(c0,c1)) && + (details::e_mul == o0) && + (details::e_mul == o2) && ( (details::e_add == o1) || (details::e_sub == o1) @@ -22202,9 +22248,9 @@ namespace exprtk } // (v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1) else if ( - (c0 == c1) && - (details::e_mul == o0) && - (details::e_mul == o2) && + (std::equal_to()(c0,c1)) && + (details::e_mul == o0) && + (details::e_mul == o2) && ( (details::e_add == o1) || (details::e_sub == o1) @@ -22230,9 +22276,9 @@ namespace exprtk } // (v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c else if ( - (c0 == c1) && - (details::e_div == o0) && - (details::e_div == o2) && + (std::equal_to()(c0,c1)) && + (details::e_div == o0) && + (details::e_div == o2) && ( (details::e_add == o1) || (details::e_sub == o1) @@ -22404,9 +22450,9 @@ namespace exprtk } // (c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1) else if ( - (c0 == c1) && - (details::e_mul == o0) && - (details::e_mul == o2) && + (std::equal_to()(c0,c1)) && + (details::e_mul == o0) && + (details::e_mul == o2) && ( (details::e_add == o1) || (details::e_sub == o1) @@ -22578,9 +22624,9 @@ namespace exprtk } // (v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1) else if ( - (c0 == c1) && - (details::e_mul == o0) && - (details::e_mul == o2) && + (std::equal_to()(c0,c1)) && + (details::e_mul == o0) && + (details::e_mul == o2) && ( (details::e_add == o1) || (details::e_sub == o1) ) @@ -25960,6 +26006,9 @@ namespace exprtk struct function { + function() + {} + function(const std::string& n) : name_(n) {} @@ -26484,7 +26533,7 @@ namespace exprtk ); } - inline bool forward(const std::string& name, const std::size_t& arg_count, symbol_table_t& symbol_table) + inline bool forward(const std::string& name, const std::size_t& arg_count, symbol_table_t& sym_table) { if (arg_count > 6) return false; @@ -26508,7 +26557,7 @@ namespace exprtk exprtk::ifunction& ifunc = (*(fp_map_[arg_count])[name]); - return symbol_table.add_function(name,ifunc); + return sym_table.add_function(name,ifunc); } } diff --git a/exprtk_benchmark.cpp b/exprtk_benchmark.cpp index d086ab3..1797d0f 100644 --- a/exprtk_benchmark.cpp +++ b/exprtk_benchmark.cpp @@ -63,19 +63,24 @@ bool load_expression(exprtk::symbol_table& symbol_table, Sequence,Allocator>& expr_seq) { exprtk::parser parser; + for (std::size_t i = 0; i < expression_list_size; ++i) { exprtk::expression expression; expression.register_symbol_table(symbol_table); + if (!parser.compile(expression_list[i],expression)) { printf("[load_expression] - Parser Error: %s\tExpression: %s\n", parser.error().c_str(), expression_list[i].c_str()); + return false; } + expr_seq.push_back(expression); } + return true; } @@ -86,8 +91,10 @@ void run_exprtk_benchmark(T& x, T& y, { T total = T(0); unsigned int count = 0; + exprtk::timer timer; timer.start(); + for (x = lower_bound_x; x <= upper_bound_x; x += delta) { for (y = lower_bound_y; y <= upper_bound_y; y += delta) @@ -96,7 +103,9 @@ void run_exprtk_benchmark(T& x, T& y, ++count; } } + timer.stop(); + if (T(0) != total) printf("[exprtk] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n", timer.time(), @@ -113,8 +122,10 @@ void run_native_benchmark(T& x, T& y, NativeFunction f, const std::string& expr_ { T total = T(0); unsigned int count = 0; + exprtk::timer timer; timer.start(); + for (x = lower_bound_x; x <= upper_bound_x; x += delta) { for (y = lower_bound_y; y <= upper_bound_y; y += delta) @@ -123,7 +134,9 @@ void run_native_benchmark(T& x, T& y, NativeFunction f, const std::string& expr_ ++count; } } + timer.stop(); + if (T(0) != total) printf("[native] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n", timer.time(), @@ -146,6 +159,7 @@ bool run_parse_benchmark(exprtk::symbol_table& symbol_table) { exprtk::timer timer; timer.start(); + for (std::size_t r = 0; r < rounds; ++r) { if (!parser.compile(expression_list[i],expression)) @@ -153,15 +167,19 @@ bool run_parse_benchmark(exprtk::symbol_table& symbol_table) printf("[run_parse_benchmark] - Parser Error: %s\tExpression: %s\n", parser.error().c_str(), expression_list[i].c_str()); + return false; } } + timer.stop(); + printf("[parse] Total Time:%12.8f Rate:%14.3fparse/sec Expression: %s\n", timer.time(), rounds / timer.time(), expression_list[i].c_str()); } + return true; } @@ -278,10 +296,12 @@ int main(int argc, char* argv[]) if (argc >= 2) { const std::string file_name = argv[1]; + if (argc == 2) perform_file_based_benchmark(file_name); else perform_file_based_benchmark(file_name,atoi(argv[2])); + return 0; } @@ -379,16 +399,20 @@ void pgo_primer() std::size_t load_expression_file(const std::string& file_name, std::deque& expression_list) { std::ifstream stream(file_name.c_str()); + if (!stream) return 0; + std::string buffer; buffer.reserve(1024); std::size_t line_count = 0; + while (std::getline(stream,buffer)) { if (buffer.empty()) continue; else if ('#' == buffer[0]) continue; + ++line_count; expression_list.push_back(buffer); } @@ -399,6 +423,7 @@ std::size_t load_expression_file(const std::string& file_name, std::deque expr_str_list; + if (0 == load_expression_file(file_name,expr_str_list)) { std::cout << "Failed to load any expressions from: " << file_name << "\n"; @@ -463,17 +488,21 @@ void perform_file_based_benchmark(const std::string& file_name, const std::size_ { parser_t parser; + for (std::size_t i = 0; i < expr_str_list.size(); ++i) { expression_t expression; expression.register_symbol_table(symbol_table); + if (!parser.compile(expr_str_list[i],expression)) { printf("[perform_file_based_benchmark] - Parser Error: %s\tExpression: %s\n", parser.error().c_str(), expr_str_list[i].c_str()); + return; } + expression_list.push_back(expression); } } @@ -483,6 +512,7 @@ void perform_file_based_benchmark(const std::string& file_name, const std::size_ double single_eval_total_time = 0.0; total_timer.start(); + for (std::size_t i = 0; i < expression_list.size(); ++i) { expression_t& e = expression_list[i]; @@ -499,12 +529,14 @@ void perform_file_based_benchmark(const std::string& file_name, const std::size_ timer.start(); double sum = 0.0; + for (std::size_t r = 0; r < rounds; ++r) { sum += e.value(); std::swap(a,b); std::swap(x,y); } + timer.stop(); printf("Expression %3d of %3d %9.3f ns\t%10d ns\t(%30.10f) '%s'\n", @@ -519,6 +551,7 @@ void perform_file_based_benchmark(const std::string& file_name, const std::size_ single_eval_total_time += (timer.time() * 1000000000.0) / (1.0 * rounds); } + total_timer.stop(); printf("[*] Number Of Evals: %15.0f\n", diff --git a/exprtk_test.cpp b/exprtk_test.cpp index c6bcb5b..ede8611 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -1129,6 +1129,7 @@ inline bool test_expression(const std::string& expression_string, const T& expec printf("test_expression() - Error: %s Expression: %s\n", parser.error().c_str(), expression_string.c_str()); + return false; } } @@ -1137,6 +1138,7 @@ inline bool test_expression(const std::string& expression_string, const T& expec { printf("test_expression() - Error: Expression did not compile to a constant! Expression: %s\n", expression_string.c_str()); + return false; } @@ -1148,6 +1150,7 @@ inline bool test_expression(const std::string& expression_string, const T& expec expression_string.c_str(), (double)expected_result, (double)result); + return false; } @@ -1170,7 +1173,9 @@ inline bool run_test00() } if (!result) + { return false; + } } return true; @@ -1538,6 +1543,7 @@ inline bool run_test01() for (std::size_t r = 0; r < rounds; ++r) { bool loop_result = true; + for (std::size_t i = 0; i < test_list_size; ++i) { test_xy& test = const_cast&>(test_list[i]); @@ -1554,12 +1560,15 @@ inline bool run_test01() { exprtk::parser parser; + if (!parser.compile(test.expr,expression)) { printf("run_test01() - Error: %s Expression: %s\n", parser.error().c_str(), test.expr.c_str()); + loop_result = false; + continue; } } @@ -1572,6 +1581,7 @@ inline bool run_test01() test.expr.c_str(), (double)test.result, (double)result); + loop_result = false; } } @@ -1662,12 +1672,15 @@ inline bool run_test01() { exprtk::parser parser; + if (!parser.compile(test.expr,expression)) { printf("run_test01() - Error: %s Expression: %s\n", parser.error().c_str(), test.expr.c_str()); + loop_result = false; + continue; } } @@ -1741,12 +1754,15 @@ inline bool run_test01() { exprtk::parser parser; + if (!parser.compile(expr_list[i],expression)) { printf("run_test01() - Error: %s Expression: %s\n", parser.error().c_str(), expr_list[i].c_str()); + loop_result = false; + continue; } } @@ -2077,6 +2093,7 @@ inline bool run_test02() printf("run_test02() - Error: %s Expression: %s\n", parser.error().c_str(), test.expr.c_str()); + return false; } } @@ -2098,7 +2115,9 @@ inline bool run_test02() } if (!result) + { return false; + } } return true; @@ -2161,6 +2180,7 @@ inline bool run_test03() printf("run_test03() - Error - Invalid number of variables in symbol_table! Expected: %d got: %d\n", static_cast(variable_list_size), static_cast(symbol_table.variable_count())); + return false; } @@ -2176,6 +2196,7 @@ inline bool run_test03() printf("run_test03() - Error: %s Expression: %s\n", parser.error().c_str(), expression_string.c_str()); + return false; } } @@ -2217,6 +2238,7 @@ inline bool run_test04() printf("run_test04() - Error: %s Expression: %s\n", parser.error().c_str(), expression_string.c_str()); + return false; } } @@ -2237,6 +2259,7 @@ inline bool run_test04() (double)result2, (double)x, (double)y); + return false; } @@ -2277,6 +2300,7 @@ inline bool run_test05() printf("run_test05() - Error: %s Expression: %s\n", parser.error().c_str(), expression_string.c_str()); + return false; } } @@ -2306,6 +2330,7 @@ inline bool run_test05() (double)x, (double)y, static_cast(i)); + return false; } } @@ -2339,6 +2364,7 @@ inline bool run_test06() printf("run_test06() - Error: %s Expression: %s\n", parser.error().c_str(), expression_string.c_str()); + return false; } } @@ -2358,6 +2384,7 @@ inline bool run_test06() printf("run_test06() - Integration Error: Expected: %19.15f\tResult: %19.15f\n", (double)(pi / T(2)), (double)total_area1); + return false; } @@ -2410,6 +2437,7 @@ inline bool run_test07() (double)x, (double)deriv1_real_result, (double)deriv1_result1); + return false; } } @@ -2431,6 +2459,7 @@ inline bool run_test07() (double)x, (double)deriv2_real_result, (double)deriv2_result1); + return false; } } @@ -2452,6 +2481,7 @@ inline bool run_test07() (double)x, (double)deriv3_real_result, (double)deriv3_result1); + return false; } } @@ -2636,6 +2666,7 @@ inline bool run_test08() printf("run_test08() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str[j].c_str()); + return false; } } @@ -2716,6 +2747,7 @@ inline bool run_test09() printf("run_test09() - Error: %s Expression: %s\n", parser.error().c_str(), expression_string.c_str()); + return false; } } @@ -2743,6 +2775,7 @@ inline bool run_test09() printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n", (double)expected, (double)result); + return false; } } @@ -2772,6 +2805,7 @@ inline bool run_test10() static inline bool variable(exprtk::symbol_table& symbol_table, const std::string& variable_name, const T& value) { exprtk::details::variable_node* var = symbol_table.get_variable(variable_name); + if (var) return (!not_equal(var->ref(),value)); else @@ -2781,6 +2815,7 @@ inline bool run_test10() static inline bool string(exprtk::symbol_table& symbol_table, const std::string& string_name, const std::string& str) { exprtk::details::stringvar_node* str_node = symbol_table.get_stringvar(string_name); + if (str_node) return (str_node->ref() == str); else @@ -3173,11 +3208,13 @@ inline bool run_test10() { exprtk::parser parser; + if (!parser.compile(expression_string,expression0)) { printf("run_test10() - Error: %s Expression: %s\n", parser.error().c_str(), expression_string.c_str()); + return false; } } @@ -3189,11 +3226,13 @@ inline bool run_test10() { exprtk::parser parser; + if (!parser.compile(expression_string,expression1)) { printf("run_test10() - Error: %s Expression: %s\n", parser.error().c_str(), expression_string.c_str()); + return false; } } @@ -3230,14 +3269,18 @@ inline bool run_test10() { exprtk::parser parser; + parser.cache_symbols() = true; + if (!parser.compile(expression_string,expression)) { printf("run_test10() - Error: %s Expression: %s\n", parser.error().c_str(), expression_string.c_str()); + return false; } + parser.expression_symbols(variable_list); } @@ -3553,11 +3596,13 @@ inline bool run_test10() { exprtk::parser parser; + if (!parser.compile(expression_list[i],expression)) { printf("run_test10() - swaps Error: %s Expression: %s\n", parser.error().c_str(), expression_list[i].c_str()); + return false; } } @@ -3573,7 +3618,9 @@ inline bool run_test10() } if (failed) + { return false; + } } } @@ -3602,11 +3649,13 @@ inline bool run_test11() { { exprtk::parser parser; + if (!parser.compile(expression_string,expression)) { printf("run_test11() - Error: %s Expression: %s\n", parser.error().c_str(), expression_string.c_str()); + return false; } } @@ -3627,6 +3676,7 @@ inline bool run_test11() { exprtk::parser parser; + if (!parser.compile(expression_string,expression)) { printf("run_test11() - Error: %s Expression: %s\n", @@ -3732,11 +3782,13 @@ inline bool run_test12() { exprtk::parser parser; + if (!parser.compile(expr_str,expression)) { printf("run_test12() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str.c_str()); + return false; } } @@ -3827,6 +3879,7 @@ inline bool run_test13() printf("run_test13() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str.c_str()); + return false; } } @@ -3848,16 +3901,21 @@ inline std::size_t load_expressions(const std::string& file_name, Sequence& sequence) { std::ifstream stream(file_name.c_str()); + if (!stream) return 0; + std::string buffer; buffer.reserve(1024); + std::size_t line_count = 0; + while (std::getline(stream,buffer)) { if (buffer.empty()) continue; else if ('#' == buffer[0]) continue; + ++line_count; sequence.push_back(buffer); } @@ -3939,6 +3997,7 @@ inline bool run_test14() printf("run_test14() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str_list[i].c_str()); + failure = true; } else @@ -3951,9 +4010,11 @@ inline bool run_test14() for (std::size_t i = 0; i < expression_list.size(); ++i) { T result = expression_list[i].value(); + if (result != T(1)) { failure = true; + printf("run_test14() - Error with evaluation of expression: %s\n", expr_str_list[i].c_str()); } @@ -4020,6 +4081,7 @@ inline bool run_test15() printf("run_test15() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str_list[i].c_str()); + return false; } else @@ -4039,6 +4101,7 @@ inline bool run_test15() printf("run_test15() - Error: %s Expression: %s\n", parser.error().c_str(), base_expr_str.c_str()); + return false; } } @@ -4056,6 +4119,7 @@ inline bool run_test15() (double)base_result, (double)result, expr_str_list[i].c_str()); + failure = true; } } @@ -4198,6 +4262,7 @@ inline bool run_test16() printf("run_test16() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str_list[i].c_str()); + return false; } else @@ -4212,6 +4277,7 @@ inline bool run_test16() { printf("run_test16() - Error in evaluation! (1) Expression: %s\n", expr_str_list[i].c_str()); + failure = true; } } @@ -4314,6 +4380,7 @@ inline bool run_test17() printf("run_test17() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str_list[i].c_str()); + return false; } else @@ -4328,6 +4395,7 @@ inline bool run_test17() { printf("run_test17() - Error in evaluation! (1) Expression: %s\n", expr_str_list[i].c_str()); + failure = true; } } @@ -4341,10 +4409,12 @@ struct va_func : public exprtk::ivararg_function inline T operator()(const std::vector& arglist) { T result = T(0); + for (std::size_t i = 0; i < arglist.size(); ++i) { result += arglist[i]; } + return result; } }; @@ -4409,6 +4479,7 @@ inline bool run_test18() printf("run_test18() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str_list[i].c_str()); + return false; } else @@ -4423,6 +4494,7 @@ inline bool run_test18() { printf("run_test18() - Error in evaluation! (1) Expression: %s\n", expr_str_list[i].c_str()); + failure = true; } } @@ -4499,6 +4571,7 @@ inline bool run_test19() printf("run_test19() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str_list[i].c_str()); + return false; } else @@ -4513,6 +4586,7 @@ inline bool run_test19() { printf("run_test19() - Error in evaluation! (1) Expression: %s\n", expr_str_list[i].c_str()); + failure = true; } } @@ -4621,6 +4695,7 @@ inline bool run_test19() printf("run_test19() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str_list[i].c_str()); + return false; } @@ -4632,6 +4707,7 @@ inline bool run_test19() expr_str_list[i].c_str(), result_list[i], result); + return false; } } @@ -4760,6 +4836,7 @@ inline bool run_test19() parser.error().c_str(), static_cast(i), expression_str[i].c_str()); + return false; } else @@ -4945,6 +5022,7 @@ inline bool run_test19() parser.error().c_str(), static_cast(i), expression_str[i].c_str()); + return false; } else @@ -5066,6 +5144,7 @@ inline bool run_test19() printf("run_test19() - Error: %s Expression: %s\n", parser.error().c_str(), expression_str.c_str()); + return false; } @@ -5083,6 +5162,7 @@ inline bool run_test19() expression_str.c_str(), (double)std::sqrt(x), (double)result); + failure = true; } } @@ -5146,6 +5226,7 @@ inline bool run_test19() printf("run_test19() - Error: %s Expression: %s\n", parser.error().c_str(), expression_str.c_str()); + return false; } @@ -5186,6 +5267,7 @@ inline bool run_test19() printf("run_test19() - Error: %s Expression: %s\n", parser.error().c_str(), expression_str.c_str()); + return false; } @@ -5203,6 +5285,7 @@ inline bool run_test19() x, sum, result); + return false; } } @@ -5215,7 +5298,6 @@ inline bool run_test19() template struct my_usr : public exprtk::parser::unknown_symbol_resolver { - typedef typename exprtk::parser::unknown_symbol_resolver usr_t; bool process(const std::string& unknown_symbol, @@ -5228,6 +5310,7 @@ struct my_usr : public exprtk::parser::unknown_symbol_resolver st = usr_t::e_variable_type; default_value = next_value(); error_message = ""; + return true; } else if (unknown_symbol[0] == 'c') @@ -5235,6 +5318,7 @@ struct my_usr : public exprtk::parser::unknown_symbol_resolver st = usr_t::e_constant_type; default_value = next_value(); error_message = ""; + return true; } else @@ -5247,6 +5331,7 @@ struct my_usr : public exprtk::parser::unknown_symbol_resolver T next_value(const bool reset = false) { static T value = 0; + if (reset) return (value = 0); else @@ -5282,6 +5367,7 @@ inline bool run_test20() printf("run_test20() - Error: %s Expression: %s\n", parser.error().c_str(), expr_str.c_str()); + return false; } @@ -5292,6 +5378,7 @@ inline bool run_test20() { printf("run_test20() - Error in evaluation! (1) Expression: %s\n", expr_str.c_str()); + return false; } } diff --git a/readme.txt b/readme.txt index 0335971..c3fa4e5 100644 --- a/readme.txt +++ b/readme.txt @@ -67,10 +67,10 @@ expressions that can be parsed and evaluated using the ExprTk library. (14) (sin(x / pi) cos(2y) + 1) == (sin(x / pi) * cos(2 * y) + 1) (15) 75x^17 + 25.1x^5 - 35x^4 - 15.2x^3 + 40x^2 - 15.3x + 1 (16) (avg(x,y) <= x + y ? x - y : x * y) + 2.345 * pi / x - (17) fib_i := fib_i + (x := y + 0 * (fib_i := x + (y := fib_i))) - (18) while (x <= 100) { x -= 1; } - (19) x <= 'abc123' and (y in 'AString') or ('1x2y3z' != z) - (20) (x like '*123*') or ('a123b' ilike y) + (17) while (x <= 100) { x -= 1; } + (18) x <= 'abc123' and (y in 'AString') or ('1x2y3z' != z) + (19) (x like '*123*') or ('a123b' ilike y) + (20) sgn(+1.2^3.4z / -5.6y) <= {-7.8^9 / -10.11x } @@ -88,8 +88,8 @@ The most recent version of the C++ Mathematical Expression Toolkit Library including all updates and tests can be found at the following locations: - (1) Download: http://www.partow.net/programming/exprtk/index.html - (2) Repository: https://exprtk.googlecode.com/svn/ + (a) Download: http://www.partow.net/programming/exprtk/index.html + (b) Repository: https://exprtk.googlecode.com/svn/ @@ -100,10 +100,10 @@ include path (e.g: /usr/include/). [06 - COMPILATION] - (a) For a complete build: make clean all - (b) For a PGO build: make clean pgo - (c) To strip executables: make strip_bin - (d) Execute valgrind check: make valgrind_check + (a) For a complete build: make clean all + (b) For a PGO build: make clean pgo + (c) To strip executables: make strip_bin + (d) Execute valgrind check: make valgrind_check @@ -158,7 +158,7 @@ of C++ compilers: +----------+---------------------------------------------------------+ | /= | Assign the division of x by the value of the expression | | | on the right-hand side to x. Where x is either a | -| | variable or vector type. (eg: x[i+j] /= abs(y * z)) | +| | variable or vector type. (eg: x[i + j] /= abs(y * z)) | +----------+---------------------------------------------------------+ | %= | Assign x modulo the value of the expression on the right| | | hand side to x. Where x is either a variable or vector | @@ -422,11 +422,11 @@ of C++ compilers: | | eg: | | | 1. if (x > y) z; else w; | | | 2. if (x > y) z; else if (w != u) v; | -| | 3. if (x < y) {z; w+1;} else u; | +| | 3. if (x < y) {z; w + 1;} else u; | | | 4. if ((x != y) and (z > w)) | | | { | | | y := sin(x) / u; | -| | z := w+1; | +| | z := w + 1; | | | } | | | else if (x > (z + 1)) | | | { | @@ -471,7 +471,7 @@ of C++ compilers: | for | The structure will repeatedly evaluate the internal | | | statement(s) while the condition is true. On each loop | | | iteration, an 'incrementing' expression is evaluated. | -| | The conditional is mandatory whereas the initializer | +| | The conditional is mandatory whereas the initialiser | | | and incrementing expressions are optional. | | | eg: | | | for (var x := 0; (x < n) and (x != y); x += 1) | @@ -868,7 +868,7 @@ vectors. The definitions must be unique as shadowing is not allowed and object life-times are based on scope. Definitions use the following general form: - var := ; + var := ; (1) Variable Definition Variables are of numeric type denoting a single value. They can be @@ -900,13 +900,13 @@ zero. The following are examples of vector definitions: var x[3] := [123 + 3y + sin(w/z)]; (d) Initialise the first two values, other elements to zero - var x[3] := {1 + x[2], sin(y[0] / x[]) + 3}; + var x[3] := { 1 + x[2], sin(y[0] / x[]) + 3 }; (e) Initialise the first three (all) values - var x[3] := {1,2,3}; + var x[3] := { 1, 2, 3 }; - (f) Error as there are too many initializers - var x[3] := {1,2,3,4}; + (f) Error as there are too many initialisers + var x[3] := { 1, 2, 3, 4 }; (g) Error as a vector of size zero is not allowed. var x[0]; @@ -914,7 +914,7 @@ zero. The following are examples of vector definitions: (3) Return Value Variable and vector definitions have a return value. In the case of -variable definitions, the value to which the variable is initialized +variable definitions, the value to which the variable is initialised will be returned. Where as for vectors, the value of the first element (eg: v[0]) will be returned. @@ -927,14 +927,14 @@ vector expression can be assigned to a variable. Every element of the vector is assigned the value of the variable or expression. var x := 3; - var y[3] := {1,2,3}; + var y[3] := { 1, 2, 3 }; y := x + 1; (b) Vector To Variable: The variable is assigned the value of the first element of the vector (aka vec[0]) var x := 3; - var y[3] := {1,2,3}; + var y[3] := { 1, 2, 3 }; x := y + 1; @@ -972,16 +972,16 @@ The following simple example demonstrates the vector processing capabilities by computing the dot-product of the vectors v0 and v1 and then assigning it to the variable v0dotv1: - var v0[3] := {1,2,3}; - var v1[3] := {4,5,6}; + var v0[3] := { 1, 2, 3 }; + var v1[3] := { 4, 5, 6 }; var v0dotv1 := sum(v0 * v1); The following is a for-loop based implementation that is equivalent to the previously mentioned dot-product computation expression: - var v0[3] := {1,2,3}; - var v1[3] := {4,5,6}; + var v0[3] := { 1, 2, 3 }; + var v1[3] := { 4, 5, 6 }; var v0dotv1; for (var i := 0; i < min(v0[],v1[]); i += 1) @@ -995,8 +995,8 @@ is not a vector but rather a singular variable denoting a boolean state of either 'true' or 'false' depending on the nature of the inequality. - var x[3] := {1,1,1}; - var y[3] := {3,2,1}; + var x[3] := { 1, 1, 1 }; + var y[3] := { 3, 2, 1 }; y > x == false @@ -1005,10 +1005,12 @@ Note: When the aggregate operations denoted above are used in conjunction with a vector or vector expression, the return value is not a vector but rather a single value. - var x[3] := {1,2,3}; + var x[3] := { 1, 2, 3 }; sum(1 + 2x) == 15 - 7 == avg(3x + 1) + avg(3x + 1) == 7 + min(1 / x) == (1 / 3) + max(x / 2) == (3 / 2) @@ -1027,6 +1029,7 @@ There are two types of function interface: (1) ifunction (2) ivararg_function + (3) function_compositor (1) ifunction @@ -1061,24 +1064,62 @@ example defines a vararg function called 'boo': inline T operator()(const std::vector& arglist) { T result = T(0); + for (std::size_t i = 0; i < arglist.size(); ++i) { result += arglist[i] / arglist[i > 0 ? (i - 1) : 0]; } + return result; } }; -(3) Using Functions In Expressions -For the above denoted custom functions to be used in an expression, an -instance of each function needs to be registered with a symbol_table -that has been associated with the expression instance. The following -demonstrates how all the pieces are put together: +(3) 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. - typedef exprtk::symbol_table symbol_table_t; - typedef exprtk::expression expression_t; - typedef exprtk::parser parser_t; +All composited functions are registered with a symbol table, allowing +them to call other functions that have been registered with the symbol +table instance, furthermore the functions can be recursive in nature. +The following example defines, using two different methods, composited +functions then implicitly registers the functions with the denoted +symbol table. + + typedef exprtk::symbol_table symbol_table_t; + typedef exprtk::function_compositor compositor_t; + typedef typename compositor_t::function function_t; + + symbol_table_t symbol_table; + + compositor_t compositor(symbol_table); + + // define function koo0(v1,v2) { ... } + compositor + .add("koo0", + " 1 + cos(v1 * v2) / 3;", + "v1","v2"); + + // define function koo1(x,y,z) { ... } + compositor + .add(function_t() + .name("koo1") + .var("x").var("y").var("z") + .expression("1 + cos(x * y) / z;")); + + +(4) Using Functions In Expressions +For the above denoted custom and composited functions to be used in an +expression, an instance of each function needs to be registered with a +symbol_table that has been associated with the expression instance. +The following demonstrates how all the pieces are put together: + + typedef exprtk::symbol_table symbol_table_t; + typedef exprtk::expression expression_t; + typedef exprtk::parser parser_t; + typedef exprtk::function_compositor compositor_t; + typedef typename compositor_t::function function_t; foo f; boo b; @@ -1087,11 +1128,18 @@ demonstrates how all the pieces are put together: symbol_table.add_function("foo",f); symbol_table.add_vararg_function("boo",b); + compositor + .add(function_t() + .name("koo") + .var("v1") + .var("v2") + .expression("1 + cos(v1 * v2) / 3;")); + expression_t expression; expression.register_symbol_table(symbol_table); std::string expression_str = - "foo(1,2,3) + boo(1) / boo(1/2,2/3,3/4,4/5,5/6)"; + "foo(1,2,3) + boo(1) / boo(1/2,2/3,3/4,4/5) + koo(3,4)"; parser_t parser; parser.compile(expression_str,expression); @@ -1099,7 +1147,7 @@ demonstrates how all the pieces are put together: expression.value(); -(4) Function Side-Effects +(5) Function Side-Effects All function calls are assumed to have side-effects by default. This assumption implicitly disables constant folding optimisations when all parameters being passed to the function are deduced as being constants @@ -1121,7 +1169,7 @@ to the constructor to denote the lack of side-effects. }; -(5) Zero Parameter Functions +(6) Zero Parameter Functions When either an ifunction or ivararg_function derived type is defined with zero number of parameters, there are two calling conventions within expressions that are allowed. For a function named 'foo' with @@ -1132,7 +1180,116 @@ zero input parameters the calling styles are as follows: -[15 - EXPRTK NOTES] +[15 - COMPILATION ERRORS] +When attempting to compile a malformed or otherwise erroneous ExprTk +expression, the compilation process will result in an error, as is +indicated by the 'compile' method returning a false value. A +diagnostic indicating the first error encountered and its cause can be +obtained by invoking the 'error' method, as is demonstrated in the +following example: + + if (!parser.compile(expression_string,expression)) + { + printf("Error: %s\n", parser.error().c_str()); + return 1; + } + + +Any error(s) resulting from a failed compilation will be stored in the +parser instance until the next time a compilation is performed. Before +then errors can be enumerated in the order they occurred by invoking +the 'get_error' method which itself will return a 'parser_error' type. +A parser_error object will contain an error diagnostic, an error mode +(or class), and the character position of the error in the expression +string. The following example demonstrates the enumeration of error(s) +in the event of a failed compilation. + + if (!parser.compile(expression_string,expression)) + { + for (std::size_t i = 0; i < parser.error_count(); ++i) + { + typedef exprtk::parser_error::type error_t; + + error_t error = parser.get_error(i); + + printf("Error[%02d] Position: %02d Type: [%14s] Msg: %s\n", + i, + error.token.position, + exprtk::parser_error::to_str(error.mode).c_str(), + error.diagnostic.c_str()); + } + + return 1; + } + + +For expressions comprised of multiple lines, the error position +provided in the parser_error object can be converted into a pair of +line and column numbers by invoking the 'update_error' function as is +demonstrated by the following example: + + if (!parser.compile(program_str,expression)) + { + for (std::size_t i = 0; i < parser.error_count(); ++i) + { + typedef exprtk::parser_error::type error_t; + + error_t error = parser.get_error(i); + + exprtk::parser_error::update_error(error,program_str); + + printf("Error[%02d] at line: %d column: %d\n", + i, + error.line_no, + error.column_no); + } + + return 1; + } + + +Note: The are five distinct error modes in ExprTk which denote the +class of an error. These classes are as follows: + + (a) Syntax + (b) Token + (c) Numeric + (d) Symbol Table + (e) Lexer + + +(a) Syntax Errors +These are errors related to invalid syntax found within the denoted +expression. Examples are invalid sequences of operators and variables, +incorrect number of parameters to functions, invalid conditional or +loop structures and invalid use of keywords. + + eg: 'for := sin(x,y,z) + 2 * equal > until[2 - x,3]' + + +(b) Token Errors +Errors in this class relate to token level errors detected by one or +more of the following checkers: + + (1) Bracket Checker + (2) Numeric Checker + (3) Sequence Checker + +(c) Numeric Errors +This class of error is related to conversion of numeric values from +their string form to the underlying numerical type (float, double +etc). + +(d) Symbol Table Errors +This is the class of errors related to failures when interacting with +the registered symbol_table instance. Errors such as not being able to +find, within the symbol_table, symbols representing variables or +functions, to being unable to create new variables in the symbol_table +via the 'unknown symbol resolver' mechanism. + + + +[16 - EXPRTK NOTES] The following is a list of facts and suggestions one may want to take into account when using Exprtk: @@ -1268,17 +1425,17 @@ into account when using Exprtk: sum, swap, switch, tanh, tan, true, trunc, until, var, while, xnor, xor, xor - (28) Every ExprTk statement is a "value returning" expression. Unlike - some languages that limit the types of expressions that can be - performed in certain situations, in ExprTk any valid expression - can be used in any "value consuming" context. Eg: + (28) Every valid ExprTk statement is a "value returning" expression. + Unlike some languages that limit the types of expressions that + can be performed in certain situations, in ExprTk any valid + expression can be used in any "value consuming" context. Eg: var y := 3; for (var x := switch { - case 1 : 7; - case 2 : -1 + ~{var x{};}; - default: y > 2 ? 3 : 4; + case 1 : 7; + case 2 : -1 + ~{var x{};}; + default: y > 2 ? 3 : 4; }; x != while (y > 0) { y -= 1; }; x -= {if(min(x,y) < 2 * max(x,y)) @@ -1292,7 +1449,7 @@ into account when using Exprtk: -[16 - SIMPLE EXPRTK EXAMPLE] +[17 - SIMPLE EXPRTK EXAMPLE] --- snip --- #include #include @@ -1380,7 +1537,7 @@ int main() -[17 - BUILD OPTIONS] +[18 - BUILD OPTIONS] When building ExprTk there are a number of defines that will enable or disable certain features and capabilities. The defines can either be part of a compiler command line switch or scoped around the include to @@ -1418,32 +1575,35 @@ in a compilation failure. -[18 - FILES] -(00) Makefile -(01) readme.txt -(02) exprtk.hpp -(03) exprtk_test.cpp -(04) exprtk_benchmark.cpp -(05) exprtk_simple_example_01.cpp -(06) exprtk_simple_example_02.cpp -(07) exprtk_simple_example_03.cpp -(08) exprtk_simple_example_04.cpp -(09) exprtk_simple_example_05.cpp -(10) exprtk_simple_example_06.cpp -(11) exprtk_simple_example_07.cpp -(12) exprtk_simple_example_08.cpp -(13) exprtk_simple_example_09.cpp -(14) exprtk_simple_example_10.cpp -(15) exprtk_simple_example_11.cpp -(16) exprtk_simple_example_12.cpp -(17) exprtk_simple_example_13.cpp -(18) exprtk_simple_example_14.cpp -(19) exprtk_simple_example_15.cpp -(20) exprtk_simple_example_16.cpp +[19 - FILES] +The source distribution of ExprTk is comprised of the following set of +files: + + (00) Makefile + (01) readme.txt + (02) exprtk.hpp + (03) exprtk_test.cpp + (04) exprtk_benchmark.cpp + (05) exprtk_simple_example_01.cpp + (06) exprtk_simple_example_02.cpp + (07) exprtk_simple_example_03.cpp + (08) exprtk_simple_example_04.cpp + (09) exprtk_simple_example_05.cpp + (10) exprtk_simple_example_06.cpp + (11) exprtk_simple_example_07.cpp + (12) exprtk_simple_example_08.cpp + (13) exprtk_simple_example_09.cpp + (14) exprtk_simple_example_10.cpp + (15) exprtk_simple_example_11.cpp + (16) exprtk_simple_example_12.cpp + (17) exprtk_simple_example_13.cpp + (18) exprtk_simple_example_14.cpp + (19) exprtk_simple_example_15.cpp + (20) exprtk_simple_example_16.cpp -[19 - LANGUAGE STRUCTURE] +[20 - LANGUAGE STRUCTURE] +-------------------------------------------------------------+ |00 - If Statement | | |