diff --git a/exprtk.hpp b/exprtk.hpp index fe8203f..7617c10 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -44,8 +44,6 @@ #include -#define exprtk_enable_string_capabilities - namespace exprtk { namespace details @@ -141,10 +139,11 @@ namespace exprtk { "abs", "acos", "and", "asin", "atan", "atan2", "avg", "ceil", "clamp", "cos", "cosh", "cot", "csc", "deg2grad", "deg2rad", "equal", "exp", - "floor", "for", "grad2deg", "hyp", "if", "ilike", "in", "inrange", "like", "log", - "log10", "logn", "max", "min", "mod", "mul", "nand", "nor", "not", - "not_equal", "or", "rad2deg", "root", "round", "roundn", "sec", "shl", - "shr", "sin", "sinh", "sqrt", "sum", "tan", "tanh", "while", "xor" + "floor", "for", "grad2deg", "hyp", "if", "ilike", "in", "inrange", + "like", "log", "log10", "logn", "max", "min", "mod", "mul", "nand", + "nor", "not", "not_equal", "or", "rad2deg", "root", "round", "roundn", + "sec", "shl", "shr", "sin", "sinh", "sqrt", "sum", "tan", "tanh", + "while", "xor" }; static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string); @@ -269,6 +268,7 @@ namespace exprtk 10000000000000.0, 100000000000000.0, 1000000000000000.0, + 10000000000000000.0, }; namespace numeric @@ -1717,7 +1717,6 @@ namespace exprtk const std::string value_; }; - template class unary_node : public expression_node { @@ -2224,7 +2223,6 @@ namespace exprtk template T variable_node::null_value = T(std::numeric_limits::quiet_NaN()); - template class stringvar_node : public expression_node { @@ -3820,7 +3818,7 @@ namespace exprtk vm_itr_t itr = variable_map_.find(variable_name); if (variable_map_.end() != itr) { - delete itr->second; + delete (*itr).second.second; variable_map_.erase(itr); --variable_count_; return true; @@ -3892,7 +3890,7 @@ namespace exprtk const variable_pair_t& vp = short_variable_lut_[static_cast(i)]; if (0 != vp.second) { - vlist.push_back(std::make_pair(std::string("")+static_cast(i),vp.second->value())); + vlist.push_back(std::make_pair(std::string("") + static_cast(i),vp.second->value())); ++count; } } @@ -3950,7 +3948,7 @@ namespace exprtk if ( (!details::is_letter(symbol[i])) && (!details:: is_digit(symbol[i])) && - ('_' != symbol[i]) + ('_' != symbol[i]) ) return false; } @@ -4231,7 +4229,7 @@ namespace exprtk template class Sequence> inline std::size_t expression_symbols(Sequence& symbols_list) { - if (!symbol_name_caching_) + if (!symbol_name_cache_) return 0; if (symbol_name_cache_.empty()) return 0; @@ -4667,7 +4665,7 @@ namespace exprtk return variable; } - #ifdef exprtk_enable_string_capabilities + #ifndef exprtk_disable_string_capabilities //Are we dealing with a string variable? variable = symbol_table_->get_stringvar(symbol); if (variable) @@ -4742,7 +4740,7 @@ namespace exprtk case token_t::symbol : return parse_symbol(); - #ifdef exprtk_enable_string_capabilities + #ifndef exprtk_disable_string_capabilities case token_t::string : { expression_node_ptr literal_exp = expression_generator_(current_token_.value); @@ -4850,7 +4848,7 @@ namespace exprtk return error_node(); } - #ifdef exprtk_enable_string_capabilities + #ifndef exprtk_disable_string_capabilities inline bool valid_string_operation(const details::operator_type& operation) const { return (details::e_add == operation) || @@ -4997,16 +4995,16 @@ namespace exprtk // When using older C++ compilers due to the large number of type instantiations // required by the extended optimisations the compiler may crash or not be able // to compile this file properly. - #define exprtk_no_extended_optimisations + #define exprtk_disable_extended_optimisations #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) #if (defined(_MSC_VER) && (_MSC_VER <= 1400)) - #ifndef exprtk_no_extended_optimisations - #define exprtk_no_extended_optimisations + #ifndef exprtk_disable_extended_optimisations + #define exprtk_disable_extended_optimisations #endif #endif #endif - #ifndef exprtk_no_extended_optimisations + #ifndef exprtk_disable_extended_optimisations inline bool vovovov_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const { if (!operation_optimizable(operation)) @@ -5084,30 +5082,8 @@ namespace exprtk expression_node_ptr branch[2] = { b0, b1 }; if ((0 == b0) || (0 == b1)) return error_node(); - else if (is_invalid_string_op(operation,branch)) - return error_node(); - else if (details::e_assign == operation) - return synthesize_assignment_expression(operation,branch); - else if (is_string_operation(operation,branch)) - return synthesize_string_expression(operation,branch); - else if (cov_optimizable(operation,branch)) - return synthesize_cov_expression(operation,branch); - else if (voc_optimizable(operation,branch)) - return synthesize_voc_expression(operation,branch); - else if (vov_optimizable(operation,branch)) - return synthesize_vov_expression(operation,branch); - else if (vovov1_optimizable(operation,branch)) - return synthesize_vovov1_expression(operation,branch); - else if (vovov2_optimizable(operation,branch)) - return synthesize_vovov2_expression(operation,branch); - else if (covov1_optimizable(operation,branch)) - return synthesize_covov1_expression(operation,branch); - else if (covov2_optimizable(operation,branch)) - return synthesize_covov2_expression(operation,branch); - else if (vovovov_optimizable(operation,branch)) - return synthesize_vovovov_expression(operation,branch); else - return synthesize_expression(operation,branch); + return expression_generator::operator()(operation,branch); } inline expression_node_ptr conditional(expression_node_ptr condition, @@ -5150,25 +5126,27 @@ namespace exprtk return error_node(); switch (operation) { - case details::e_sf00 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf01 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf02 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf03 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf04 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf05 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf06 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf07 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf08 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf09 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf10 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf11 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf12 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf13 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf14 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf15 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf16 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf17 : return node_allocator_->allocate > >(operation,branch); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate > >(operation,branch); + 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_sf04,details::sf04_op) + case_stmt(details::e_sf05,details::sf05_op) + case_stmt(details::e_sf06,details::sf06_op) + case_stmt(details::e_sf07,details::sf07_op) + case_stmt(details::e_sf08,details::sf08_op) + case_stmt(details::e_sf09,details::sf09_op) + case_stmt(details::e_sf10,details::sf10_op) + case_stmt(details::e_sf11,details::sf11_op) + case_stmt(details::e_sf12,details::sf12_op) + case_stmt(details::e_sf13,details::sf13_op) + case_stmt(details::e_sf14,details::sf14_op) + case_stmt(details::e_sf15,details::sf15_op) + case_stmt(details::e_sf16,details::sf16_op) + case_stmt(details::e_sf17,details::sf17_op) + default : return error_node(); + #undef case_stmt } } @@ -5178,32 +5156,34 @@ namespace exprtk return error_node(); switch (operation) { - case details::e_sf18 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf19 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf20 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf21 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf22 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf23 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf24 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf25 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf26 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf27 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf28 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf29 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf30 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf31 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf32 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf33 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf34 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf35 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf36 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf37 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf38 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf39 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf40 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf41 : return node_allocator_->allocate > >(operation,branch); - case details::e_sf42 : return node_allocator_->allocate > >(operation,branch); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate > >(operation,branch); + case_stmt(details::e_sf18,details::sf18_op) + case_stmt(details::e_sf19,details::sf19_op) + case_stmt(details::e_sf20,details::sf20_op) + case_stmt(details::e_sf21,details::sf21_op) + case_stmt(details::e_sf22,details::sf22_op) + case_stmt(details::e_sf23,details::sf23_op) + case_stmt(details::e_sf24,details::sf24_op) + case_stmt(details::e_sf25,details::sf25_op) + case_stmt(details::e_sf26,details::sf26_op) + case_stmt(details::e_sf27,details::sf27_op) + case_stmt(details::e_sf28,details::sf28_op) + case_stmt(details::e_sf29,details::sf29_op) + case_stmt(details::e_sf30,details::sf30_op) + case_stmt(details::e_sf31,details::sf31_op) + case_stmt(details::e_sf32,details::sf32_op) + case_stmt(details::e_sf33,details::sf33_op) + case_stmt(details::e_sf34,details::sf34_op) + case_stmt(details::e_sf35,details::sf35_op) + case_stmt(details::e_sf36,details::sf36_op) + case_stmt(details::e_sf37,details::sf37_op) + case_stmt(details::e_sf38,details::sf38_op) + case_stmt(details::e_sf39,details::sf39_op) + case_stmt(details::e_sf40,details::sf40_op) + case_stmt(details::e_sf41,details::sf41_op) + case_stmt(details::e_sf42,details::sf42_op) + default : return error_node(); + #undef case_stmt } } @@ -5277,24 +5257,26 @@ namespace exprtk node_allocator_->free(branch[0]); switch (operation) { - case details::e_add : return node_allocator_->allocate_cr > >(c,v); - case details::e_sub : return node_allocator_->allocate_cr > >(c,v); - case details::e_mul : return node_allocator_->allocate_cr > >(c,v); - case details::e_div : return node_allocator_->allocate_cr > >(c,v); - case details::e_mod : return node_allocator_->allocate_cr > >(c,v); - case details::e_pow : return node_allocator_->allocate_cr > >(c,v); - case details::e_lt : return node_allocator_->allocate_cr > >(c,v); - case details::e_lte : return node_allocator_->allocate_cr > >(c,v); - case details::e_gt : return node_allocator_->allocate_cr > >(c,v); - case details::e_gte : return node_allocator_->allocate_cr > >(c,v); - case details::e_eq : return node_allocator_->allocate_cr > >(c,v); - case details::e_ne : return node_allocator_->allocate_cr > >(c,v); - case details::e_and : return node_allocator_->allocate_cr > >(c,v); - case details::e_nand : return node_allocator_->allocate_cr > >(c,v); - case details::e_or : return node_allocator_->allocate_cr > >(c,v); - case details::e_nor : return node_allocator_->allocate_cr > >(c,v); - case details::e_xor : return node_allocator_->allocate_cr > >(c,v); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_cr > >(c,v); + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } } @@ -5305,24 +5287,26 @@ namespace exprtk node_allocator_->free(branch[1]); switch (operation) { - case details::e_add : return node_allocator_->allocate_rc > >(v,c); - case details::e_sub : return node_allocator_->allocate_rc > >(v,c); - case details::e_mul : return node_allocator_->allocate_rc > >(v,c); - case details::e_div : return node_allocator_->allocate_rc > >(v,c); - case details::e_mod : return node_allocator_->allocate_rc > >(v,c); - case details::e_pow : return node_allocator_->allocate_rc > >(v,c); - case details::e_lt : return node_allocator_->allocate_rc > >(v,c); - case details::e_lte : return node_allocator_->allocate_rc > >(v,c); - case details::e_gt : return node_allocator_->allocate_rc > >(v,c); - case details::e_gte : return node_allocator_->allocate_rc > >(v,c); - case details::e_eq : return node_allocator_->allocate_rc > >(v,c); - case details::e_ne : return node_allocator_->allocate_rc > >(v,c); - case details::e_and : return node_allocator_->allocate_rc > >(v,c); - case details::e_nand : return node_allocator_->allocate_rc > >(v,c); - case details::e_or : return node_allocator_->allocate_rc > >(v,c); - case details::e_nor : return node_allocator_->allocate_rc > >(v,c); - case details::e_xor : return node_allocator_->allocate_rc > >(v,c); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rc > >(v,c); + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } } @@ -5332,24 +5316,26 @@ namespace exprtk Type& v2 = dynamic_cast*>(branch[1])->ref(); switch (operation) { - case details::e_add : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_sub : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_mul : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_div : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_mod : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_pow : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_lt : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_lte : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_gt : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_gte : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_eq : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_ne : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_and : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_nand : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_or : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_nor : return node_allocator_->allocate_rr > >(v1,v2); - case details::e_xor : return node_allocator_->allocate_rr > >(v1,v2); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr > >(v1,v2); + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } } @@ -5359,24 +5345,26 @@ namespace exprtk details::operator_type op = dynamic_cast*>(node)->operation(); switch (op) { - case details::e_add : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_sub : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_mul : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_div : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_mod : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_pow : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_lt : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_lte : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_gt : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_gte : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_eq : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_ne : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_and : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_nand : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_or : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_nor : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - case details::e_xor : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr > >(v0,(*dynamic_cast >*>(node))); + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } } @@ -5386,24 +5374,26 @@ namespace exprtk expression_node_ptr result = error_node(); switch (operation) { - case details::e_add : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_sub : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_mul : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_div : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_mod : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_pow : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_lt : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_lte : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_gt : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_gte : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_eq : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_ne : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_and : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_nand : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_or : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_nor : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - case details::e_xor : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; - default : return error_node(); + #define case_stmt(op0,op1) case op0 : result = synthesize_vovov1_expression_impl >(v0,branch[1]); break; + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } node_allocator_->free(branch[1]); return result; @@ -5415,24 +5405,26 @@ namespace exprtk details::operator_type op = dynamic_cast*>(node)->operation(); switch (op) { - case details::e_add : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_sub : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_mul : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_div : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_mod : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_pow : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_lt : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_lte : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_gt : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_gte : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_eq : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_ne : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_and : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_nand : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_or : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_nor : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - case details::e_xor : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr,Operation1> >((*dynamic_cast >*>(node)),v0); + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } } @@ -5442,24 +5434,26 @@ namespace exprtk expression_node_ptr result = error_node(); switch (operation) { - case details::e_add : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_sub : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_mul : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_div : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_mod : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_pow : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_lt : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_lte : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_gt : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_gte : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_eq : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_ne : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_and : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_nand : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_or : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_nor : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - case details::e_xor : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; - default : return error_node(); + #define case_stmt(op0,op1) case op0 : result = synthesize_vovov2_expression_impl >(v0,branch[0]); break; + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } node_allocator_->free(branch[0]); return result; @@ -5471,24 +5465,26 @@ namespace exprtk details::operator_type op = dynamic_cast*>(node)->operation(); switch (op) { - case details::e_add : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_sub : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_mul : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_div : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_mod : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_pow : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_lt : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_lte : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_gt : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_gte : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_eq : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_ne : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_and : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_nand : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_or : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_nor : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - case details::e_xor : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr > >(c,(*dynamic_cast >*>(node))); + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } } @@ -5498,24 +5494,26 @@ namespace exprtk expression_node_ptr result = error_node(); switch (operation) { - case details::e_add : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_sub : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_mul : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_div : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_mod : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_pow : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_lt : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_lte : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_gt : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_gte : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_eq : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_ne : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_and : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_nand : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_or : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_nor : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - case details::e_xor : result = synthesize_covov1_expression_impl >(c,branch[1]); break; - default : return error_node(); + #define case_stmt(op0,op1) case op0 : result = synthesize_covov1_expression_impl >(c,branch[1]); break; + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } node_allocator_->free(branch[1]); return result; @@ -5527,24 +5525,26 @@ namespace exprtk details::operator_type op = dynamic_cast*>(node)->operation(); switch (op) { - case details::e_add : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_sub : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_mul : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_div : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_mod : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_pow : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_lt : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_lte : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_gt : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_gte : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_eq : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_ne : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_and : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_nand : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_or : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_nor : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - case details::e_xor : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr,Operation2> >((*dynamic_cast >*>(node)),v); + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } } @@ -5554,54 +5554,58 @@ namespace exprtk expression_node_ptr result = error_node(); switch (operation) { - case details::e_add : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_sub : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_mul : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_div : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_mod : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_pow : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_lt : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_lte : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_gt : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_gte : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_eq : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_ne : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_and : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_nand : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_or : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_nor : result = synthesize_covov2_expression_impl >(branch[0],v); break; - case details::e_xor : result = synthesize_covov2_expression_impl >(branch[0],v); break; - default : return error_node(); + #define case_stmt(op0,op1) case op0 : result = synthesize_covov2_expression_impl >(branch[0],v); break; + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } node_allocator_->free(branch[0]); return result; } - #ifndef exprtk_no_extended_optimisations + #ifndef exprtk_disable_extended_optimisations template inline expression_node_ptr synthesize_vovovov_expression_impl2(expression_node_ptr (&node)[2]) { details::operator_type op = dynamic_cast*>(node[1])->operation(); switch (op) { - case details::e_add : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_sub : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_mul : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_div : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_mod : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_pow : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_lt : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_lte : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_gt : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_gte : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_eq : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_ne : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_and : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_nand : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_or : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_nor : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - case details::e_xor : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr > >((*dynamic_cast*>(node[0])),(*dynamic_cast >*>(node[1]))); + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } #else template @@ -5611,64 +5615,69 @@ namespace exprtk #endif } - #ifndef exprtk_no_extended_optimisations + #ifndef exprtk_disable_extended_optimisations template inline expression_node_ptr synthesize_vovovov_expression_impl1(expression_node_ptr (&node)[2]) { details::operator_type op = dynamic_cast*>(node[0])->operation(); switch (op) { - case details::e_add : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_sub : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_mul : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_div : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_mod : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_pow : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_lt : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_lte : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_gt : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_gte : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_eq : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_ne : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_and : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_nand : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_or : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_nor : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - case details::e_xor : return synthesize_vovovov_expression_impl2, Operation2>(node); break; - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return synthesize_vovovov_expression_impl2,Operation2>(node); break; + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } + } #else template inline expression_node_ptr synthesize_vovovov_expression_impl1(expression_node_ptr (&)[2]) { return error_node(); - #endif } + #endif - #ifndef exprtk_no_extended_optimisations + #ifndef exprtk_disable_extended_optimisations inline expression_node_ptr synthesize_vovovov_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) { expression_node_ptr result = error_node(); switch (opr) { - case details::e_add : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_sub : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_mul : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_div : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_mod : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_pow : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_lt : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_lte : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_gt : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_gte : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_eq : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_ne : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_and : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_nand : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_or : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_nor : result = synthesize_vovovov_expression_impl1 >(branch); break; - case details::e_xor : result = synthesize_vovovov_expression_impl1 >(branch); break; - default : return error_node(); + #define case_stmt(op0,op1) case op0 : result = synthesize_vovovov_expression_impl1 >(branch); break; + case_stmt(details:: e_add,details:: add_op) + case_stmt(details:: e_sub,details:: sub_op) + case_stmt(details:: e_mul,details:: mul_op) + case_stmt(details:: e_div,details:: div_op) + case_stmt(details:: e_mod,details:: mod_op) + case_stmt(details:: e_pow,details:: pow_op) + case_stmt(details:: e_lt,details:: lt_op) + case_stmt(details:: e_lte,details:: lte_op) + case_stmt(details:: e_gt,details:: gt_op) + case_stmt(details:: e_gte,details:: gte_op) + case_stmt(details:: e_eq,details:: eq_op) + case_stmt(details:: e_ne,details:: ne_op) + case_stmt(details:: e_and,details:: and_op) + case_stmt(details::e_nand,details::nand_op) + case_stmt(details:: e_or,details:: or_op) + case_stmt(details:: e_nor,details:: nor_op) + case_stmt(details:: e_xor,details:: xor_op) + default : return error_node(); + #undef case_stmt } node_allocator_->free(branch[0]); node_allocator_->free(branch[1]); @@ -5686,16 +5695,18 @@ namespace exprtk { switch (opr) { - case details::e_lt : return node_allocator_->allocate_tt >,T0,T1>(s0,s1); - case details::e_lte : return node_allocator_->allocate_tt >,T0,T1>(s0,s1); - case details::e_gt : return node_allocator_->allocate_tt >,T0,T1>(s0,s1); - case details::e_gte : return node_allocator_->allocate_tt >,T0,T1>(s0,s1); - case details::e_eq : return node_allocator_->allocate_tt >,T0,T1>(s0,s1); - case details::e_ne : return node_allocator_->allocate_tt >,T0,T1>(s0,s1); - case details::e_in : return node_allocator_->allocate_tt >,T0,T1>(s0,s1); - case details::e_like : return node_allocator_->allocate_tt >,T0,T1>(s0,s1); - case details::e_ilike: return node_allocator_->allocate_tt >,T0,T1>(s0,s1); - default : return error_node(); + #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_tt >,T0,T1>(s0,s1); + case_stmt(details::e_lt ,details:: lt_op) + case_stmt(details::e_lte ,details:: lte_op) + case_stmt(details::e_gt ,details:: gt_op) + case_stmt(details::e_gte ,details:: gte_op) + case_stmt(details::e_eq ,details:: eq_op) + case_stmt(details::e_ne ,details:: ne_op) + case_stmt(details::e_in ,details:: in_op) + case_stmt(details::e_like ,details:: like_op) + case_stmt(details::e_ilike,details::ilike_op) + default : return error_node(); + #undef case_stmt } } @@ -5747,7 +5758,7 @@ namespace exprtk return result; } - #ifdef exprtk_enable_string_capabilities + #ifndef exprtk_disable_string_capabilities inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) { if (details::is_string_node(branch[0])) @@ -5879,15 +5890,16 @@ namespace exprtk const details::binary_node* node = dynamic_cast*>(expr); if (0 == node) return false; - if (!operation_optimizable(node->operation())) + else if (!operation_optimizable(node->operation())) return false; expression_node_ptr b0 = node->branch(0); expression_node_ptr b1 = node->branch(1); if (details::is_variable_node(b0) && (details::is_variable_node(b1) || details::is_constant_node(b1))) return true; - if (details::is_constant_node(b0) && (details::is_variable_node(b1) || details::is_constant_node(b1))) + else if (details::is_constant_node(b0) && (details::is_variable_node(b1) || details::is_constant_node(b1))) return true; - return false; + else + return false; } inline void perform_bn_type0_optimization(const expression_node_ptr) @@ -6100,6 +6112,125 @@ namespace exprtk else return std::numeric_limits::quiet_NaN(); } + + template + inline bool pgo_primer() + { + static const std::string expression_list[] + = { + "(y + x)", + "2 * (y + x)", + "(2 * y + 2 * x)", + "(y + x / y) * (x - y / x)", + "x / ((x + y) * (x - y)) / y", + "1 - ((x * y) + (y / x)) - 3", + "sin(2 * x) + cos(pi / y)", + "1 - sin(2 * x) + cos(pi / y)", + "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)", + "(x^2 / sin(2 * pi / y)) -x / 2", + "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)", + "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))", + "if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x", + "(yy + xx)", + "2 * (yy + xx)", + "(2 * yy + 2 * xx)", + "(yy + xx / yy) * (xx - yy / xx)", + "xx / ((xx + yy) * (xx - yy)) / yy", + "1 - ((xx * yy) + (yy / xx)) - 3", + "sin(2 * xx) + cos(pi / yy)", + "1 - sin(2 * xx) + cos(pi / yy)", + "sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3)", + "(xx^2 / sin(2 * pi / yy)) -xx / 2", + "clamp(-1.0, sin(2 * pi * xx) + cos(yy / 2 * pi), +1.0)", + "max(3.33, min(sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3), 1.11))", + "if(avg(xx,yy) <= xx + yy, xx - yy, xx * yy) + 2 * pi / xx" + }; + static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string); + + T x = T(0); + T y = T(0); + T xx = T(0); + T yy = T(0); + + exprtk::symbol_table symbol_table; + symbol_table.add_constants(); + symbol_table.add_variable( "x", x); + symbol_table.add_variable( "y", y); + symbol_table.add_variable("xx",xx); + symbol_table.add_variable("yy",yy); + + typedef typename std::deque > expr_list_t; + expr_list_t optimized_expr_list; + expr_list_t unoptimized_expr_list; + + const std::size_t rounds = 100; + + //Generate optimised expressions + { + for (std::size_t r = 0; r < rounds; ++r) + { + optimized_expr_list.clear(); + 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,exprtk::parser::e_all)) + { + return false; + } + optimized_expr_list.push_back(expression); + } + } + } + + //Generate unoptimised expressions + { + for (std::size_t r = 0; r < rounds; ++r) + { + unoptimized_expr_list.clear(); + 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,exprtk::parser::e_none)) + { + return false; + } + unoptimized_expr_list.push_back(expression); + } + } + } + + struct execute + { + static inline T process(T& x, T& y, expression& expression) + { + static const T lower_bound = T(-20.0); + static const T upper_bound = T(+20.0); + T delta = T(0.1); + T total = T(0.0); + for (x = lower_bound; x <= upper_bound; x += delta) + { + for (y = lower_bound; y <= upper_bound; y += delta) + { + total += expression.value(); + } + } + return total; + } + }; + for (std::size_t i = 0; i < optimized_expr_list.size(); ++i) + { + execute::process( x, y, optimized_expr_list[i]); + execute::process(xx,yy, optimized_expr_list[i]); + execute::process( x, y,unoptimized_expr_list[i]); + execute::process(xx,yy,unoptimized_expr_list[i]); + } + return true; + } + } #ifdef WIN32 diff --git a/exprtk_test.cpp b/exprtk_test.cpp index d388a8a..b45ccb7 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -715,7 +715,7 @@ inline bool test_expression(const std::string& expression_string, const T& expec } template -inline bool run_test0() +inline bool run_test00() { const std::size_t rounds = 100; for (std::size_t r = 0; r < rounds; ++r) @@ -747,7 +747,7 @@ struct test_xy }; template -inline bool run_test1() +inline bool run_test01() { static const test_xy test_list[] = { @@ -791,7 +791,13 @@ inline bool run_test1() test_xy("(x + y) > y" ,T(2.0),T(3.0),T(1.0)), test_xy("(x + y) > x" ,T(2.0),T(3.0),T(1.0)), test_xy("(x * y) > y" ,T(2.0),T(3.0),T(1.0)), - test_xy("(x * y) > x" ,T(2.0),T(3.0),T(1.0)) + test_xy("(x * y) > x" ,T(2.0),T(3.0),T(1.0)), + test_xy("(2x + 3y) == (2*x + 3*y)" ,T(2.0),T(3.0),T(1.0)), + test_xy("2(x + y) == (2*x + 2*y)" ,T(2.0),T(3.0),T(1.0)), + test_xy(" (x + y)3 == (3*x + 3*y)" ,T(2.0),T(3.0),T(1.0)), + test_xy("2x + 3y == 2*x + 3*y" ,T(2.0),T(3.0),T(1.0)), + test_xy("2(x + y) == 2*x + 2*y" ,T(2.0),T(3.0),T(1.0)), + test_xy(" (x + y)3 == 3*x + 3*y" ,T(2.0),T(3.0),T(1.0)) }; static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_xy); @@ -850,7 +856,7 @@ struct test_ab }; template -inline bool run_test2() +inline bool run_test02() { static const test_ab test_list[] = { @@ -947,7 +953,7 @@ inline bool run_test2() } template -inline bool run_test3() +inline bool run_test03() { std::string expression_string = "a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+z+" "A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+" @@ -1009,7 +1015,7 @@ inline bool run_test3() if (!parser.compile(expression_string,expression)) { - std::cout << "run_test1() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; + std::cout << "run_test01() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } expression.value(); @@ -1024,7 +1030,7 @@ inline T clamp(const T& l, const T& v, const T& u) } template -inline bool run_test4() +inline bool run_test04() { std::string expression_string = "clamp(-1.0,sin(2 * pi * x) + cos(y / 2 * pi),+1.0)"; @@ -1045,7 +1051,7 @@ inline bool run_test4() if (!parser.compile(expression_string,expression)) { - std::cout << "run_test2() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; + std::cout << "run_test02() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } } @@ -1059,7 +1065,7 @@ inline bool run_test4() T result2 = clamp(-1.0,std::sin(2 * pi * x) + std::cos(y / 2 * pi),+1.0); if (not_equal(result1,result2)) { - printf("run_test2() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\n", + printf("run_test02() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\n", expression_string.c_str(), result1, result2, @@ -1074,7 +1080,7 @@ inline bool run_test4() } template -inline bool run_test5() +inline bool run_test05() { typedef exprtk::expression expression_t; std::string expression_string = "clamp(-1.0,sin(2 * pi * x_var123) + cos(y_var123 / 2 * pi),+1.0)"; @@ -1098,7 +1104,7 @@ inline bool run_test5() if (!parser.compile(expression_string,e)) { - std::cout << "run_test3() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; + std::cout << "run_test03() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } expression_list.push_back(e); @@ -1117,7 +1123,7 @@ inline bool run_test5() T result = expr.value(); if (not_equal(result,real_result)) { - printf("run_test3() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\tIndex:%d\n", + printf("run_test03() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\tIndex:%d\n", expression_string.c_str(), real_result, result, @@ -1134,7 +1140,7 @@ inline bool run_test5() } template -inline bool run_test6() +inline bool run_test06() { typedef exprtk::expression expression_t; std::string expression_string = "sqrt(1 - (x^2))"; @@ -1151,7 +1157,7 @@ inline bool run_test6() if (!parser.compile(expression_string,expression)) { - std::cout << "run_test4() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; + std::cout << "run_test06() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } @@ -1161,13 +1167,13 @@ inline bool run_test6() if (not_equal(total_area1,total_area2,0.000001)) { - printf("run_test4() - Integration Error: area1 != area2\n"); + printf("run_test06() - Integration Error: area1 != area2\n"); return false; } if (not_equal(total_area1,pi/T(2.0),0.000001)) { - printf("run_test4() - Integration Error: Expected: %19.15f\tResult: %19.15f\n", + printf("run_test06() - Integration Error: Expected: %19.15f\tResult: %19.15f\n", pi/T(2.0), total_area1); return false; @@ -1176,7 +1182,7 @@ inline bool run_test6() } template -inline bool run_test7() +inline bool run_test07() { typedef exprtk::expression expression_t; std::string expression_string = "sin(2x+1/3)"; @@ -1193,7 +1199,7 @@ inline bool run_test7() if (!parser.compile(expression_string,expression)) { - std::cout << "run_test5() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; + std::cout << "run_test07() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } @@ -1205,12 +1211,12 @@ inline bool run_test7() if (not_equal(result1,result2,0.000000001)) { - printf("run_test5() - Derivative Error: result1 != result2\n"); + printf("run_test07() - Derivative Error: result1 != result2\n"); return false; } if (not_equal(result1,real_result,0.000000001)) { - printf("run_test5() - Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n", + printf("run_test05() - Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n", x, real_result, result1); @@ -1221,7 +1227,7 @@ inline bool run_test7() } template -inline bool run_test8() +inline bool run_test08() { static const std::string expr_str[] = @@ -1332,7 +1338,7 @@ inline bool run_test8() if (!parser.compile(expr_str[j],expression)) { - std::cout << "run_test6() - Error: " << parser.error() << "\tExpression: " << expr_str[j] << std::endl; + std::cout << "run_test08() - Error: " << parser.error() << "\tExpression: " << expr_str[j] << std::endl; return false; } expression.value(); @@ -1353,7 +1359,7 @@ struct myfunc : public exprtk::ifunction }; template -inline bool run_test9() +inline bool run_test09() { static const std::size_t rounds = 100000; for (std::size_t i = 0; i < rounds; ++i) @@ -1396,7 +1402,7 @@ inline bool run_test9() if (!parser.compile(expression_string,expression)) { - std::cout << "run_test7() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; + std::cout << "run_test09() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } const T pi = T(3.14159265358979323846); @@ -1415,7 +1421,7 @@ inline bool run_test9() if (not_equal(result,expected,0.0000001)) { - printf("run_test7() - Error Expected: %19.15f\tResult: %19.15f\n", + printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n", expected, result); return false; @@ -1424,19 +1430,116 @@ inline bool run_test9() return true; } +template +inline bool run_test10() +{ + T x = T(1.1); + T y = T(2.2); + T xx = T(3.3); + T yy = T(4.4); + + exprtk::symbol_table symbol_table; + + { + symbol_table.add_variable("x", x); + symbol_table.add_variable("y", y); + symbol_table.add_variable("xx",xx); + symbol_table.add_variable("yy",yy); + + if (!symbol_table.symbol_exists("x")) + { + std::cout << "run_test10() - Symbol 'x' does not exist!\n"; + return false; + } + else if (!symbol_table.symbol_exists("y")) + { + std::cout << "run_test10() - Symbol 'y' does not exist!\n"; + return false; + } + else if (!symbol_table.symbol_exists("xx")) + { + std::cout << "run_test10() - Symbol 'xx' does not exist!\n"; + return false; + } + else if (!symbol_table.symbol_exists("yy")) + { + std::cout << "run_test10() - Symbol 'yy' does not exist!\n"; + return false; + } + + struct test + { + 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 + return false; + } + }; + + if (!test::variable(symbol_table,"x",x)) + { + std::cout << "run_test10() - Symbol 'x' value failure!\n"; + return false; + } + else if (!test::variable(symbol_table,"y",y)) + { + std::cout << "run_test10() - Symbol 'y' value failure!\n"; + return false; + } + else if (!test::variable(symbol_table,"xx",xx)) + { + std::cout << "run_test10() - Symbol 'xx' value failure!\n"; + return false; + } + else if (!test::variable(symbol_table,"yy",yy)) + { + std::cout << "run_test10() - Symbol 'yy' value failure!\n"; + return false; + } + + if (symbol_table.remove_variable("x")) + { + return false; + } + else if (symbol_table.remove_variable("y")) + { + return false; + } + else if (symbol_table.remove_variable("xx")) + { + return false; + } + else if (symbol_table.remove_variable("yy")) + { + return false; + } + } + + { + } + + return true; +} + int main() { return ( - run_test0() && - run_test1() && - run_test2() && - run_test3() && - run_test4() && - run_test5() && - run_test6() && - run_test7() && - run_test8() && - run_test9() + run_test00() && + run_test01() && + run_test02() && + run_test03() && + run_test04() && + run_test05() && + run_test06() && + run_test07() && + run_test08() && + run_test09() && + run_test10() ) ? 0 : 1; }