34716 {
34717 switch (p)
34718 {
34719 #define case_stmt(cp) \
34720 case cp : return node_allocator_-> \
34721 allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \
34722
34738 #undef case_stmt
34739 default : return error_node();
34740 }
34741 }
34742
34743 inline expression_node_ptr cardinal_pow_optimisation(const T& v, const T& c)
34744 {
34745 const bool not_recipricol = (c >= T(0));
34746 const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
34747
34748 if (0 == p)
34749 return node_allocator_->allocate_c<literal_node_t>(T(1));
34750 else if (std::equal_to<T>()(T(2),c))
34751 {
34752 return node_allocator_->
34753 template allocate_rr<typename details::vov_node<Type,details::mul_op<Type> > >(v,v);
34754 }
34755 else
34756 {
34757 if (not_recipricol)
34758 return cardinal_pow_optimisation_impl<T,details::ipow_node>(v,p);
34759 else
34760 return cardinal_pow_optimisation_impl<T,details::ipowinv_node>(v,p);
34761 }
34762 }
34763
34764 inline bool cardinal_pow_optimisable(const details::operator_type& operation, const T& c) const
34765 {
34766 return (details::e_pow == operation) && (details::numeric::abs(c) <= T(60)) && details::numeric::is_integer(c);
34767 }
34768
34769 inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr (&branch)[2])
34770 {
34771 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
34772 const bool not_recipricol = (c >= T(0));
34773 const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
34774
34775 node_allocator_->free(branch[1]);
34776
34777 if (0 == p)
34778 {
34779 details::free_all_nodes(*node_allocator_, branch);
34780
34781 return node_allocator_->allocate_c<literal_node_t>(T(1));
34782 }
34783 else if (not_recipricol)
34784 return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipow_node>(branch[0],p);
34785 else
34786 return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipowinv_node>(branch[0],p);
34787 }
34788 #else
34789 inline expression_node_ptr cardinal_pow_optimisation(T&, const T&)
34790 {
34791 return error_node();
34792 }
34793
34794 inline bool cardinal_pow_optimisable(const details::operator_type&, const T&)
34795 {
34796 return false;
34797 }
34798
34799 inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr(&)[2])
34800 {
34801 return error_node();
34802 }
34803 #endif
34804
34805 struct synthesize_binary_ext_expression
34806 {
34807 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34808 const details::operator_type& operation,
34809 expression_node_ptr (&branch)[2])
34810 {
34813
34814 if (left_neg && right_neg)
34815 {
34816 if (
34817 (details::e_add == operation) ||
34818 (details::e_sub == operation) ||
34819 (details::e_mul == operation) ||
34820 (details::e_div == operation)
34821 )
34822 {
34823 if (
34824 !expr_gen.parser_->simplify_unary_negation_branch(branch[0]) ||
34825 !expr_gen.parser_->simplify_unary_negation_branch(branch[1])
34826 )
34827 {
34828 details::free_all_nodes(*expr_gen.node_allocator_,branch);
34829
34830 return error_node();
34831 }
34832 }
34833
34834 switch (operation)
34835 {
34836
34837 case details::e_add : return expr_gen(details::e_neg,
34838 expr_gen.node_allocator_->
34839 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
34840 (branch[0],branch[1]));
34841
34842
34843 case details::e_sub : return expr_gen.node_allocator_->
34844 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
34845 (branch[1],branch[0]);
34846
34847 default : break;
34848 }
34849 }
34850 else if (left_neg && !right_neg)
34851 {
34852 if (
34853 (details::e_add == operation) ||
34854 (details::e_sub == operation) ||
34855 (details::e_mul == operation) ||
34856 (details::e_div == operation)
34857 )
34858 {
34859 if (!expr_gen.parser_->simplify_unary_negation_branch(branch[0]))
34860 {
34861 details::free_all_nodes(*expr_gen.node_allocator_,branch);
34862
34863 return error_node();
34864 }
34865
34866 switch (operation)
34867 {
34868
34869 case details::e_add : return expr_gen.node_allocator_->
34870 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
34871 (branch[1], branch[0]);
34872
34873
34874 case details::e_sub : return expr_gen(details::e_neg,
34875 expr_gen.node_allocator_->
34876 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
34877 (branch[0], branch[1]));
34878
34879
34880 case details::e_mul : return expr_gen(details::e_neg,
34881 expr_gen.node_allocator_->
34882 template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
34883 (branch[0], branch[1]));
34884
34885
34886 case details::e_div : return expr_gen(details::e_neg,
34887 expr_gen.node_allocator_->
34888 template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
34889 (branch[0], branch[1]));
34890
34891 default : return error_node();
34892 }
34893 }
34894 }
34895 else if (!left_neg && right_neg)
34896 {
34897 if (
34898 (details::e_add == operation) ||
34899 (details::e_sub == operation) ||
34900 (details::e_mul == operation) ||
34901 (details::e_div == operation)
34902 )
34903 {
34904 if (!expr_gen.parser_->simplify_unary_negation_branch(branch[1]))
34905 {
34906 details::free_all_nodes(*expr_gen.node_allocator_,branch);
34907
34908 return error_node();
34909 }
34910
34911 switch (operation)
34912 {
34913
34914 case details::e_add : return expr_gen.node_allocator_->
34915 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
34916 (branch[0], branch[1]);
34917
34918
34919 case details::e_sub : return expr_gen.node_allocator_->
34920 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
34921 (branch[0], branch[1]);
34922
34923
34924 case details::e_mul : return expr_gen(details::e_neg,
34925 expr_gen.node_allocator_->
34926 template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
34927 (branch[0], branch[1]));
34928
34929
34930 case details::e_div : return expr_gen(details::e_neg,
34931 expr_gen.node_allocator_->
34932 template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
34933 (branch[0], branch[1]));
34934
34935 default : return error_node();
34936 }
34937 }
34938 }
34939
34940 switch (operation)
34941 {
34942 #define case_stmt(op0, op1) \
34943 case op0 : return expr_gen.node_allocator_-> \
34944 template allocate<typename details::binary_ext_node<Type,op1<Type> > > \
34945 (branch[0], branch[1]); \
34946
34949 #undef case_stmt
34950 default : return error_node();
34951 }
34952 }
34953 };
34954
34955 struct synthesize_vob_expression
34956 {
34957 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34958 const details::operator_type& operation,
34959 expression_node_ptr (&branch)[2])
34960 {
34961 const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref();
34962
34963 #ifndef exprtk_disable_enhanced_features
34964 if (details::is_sf3ext_node(branch[1]))
34965 {
34966 expression_node_ptr result = error_node();
34967
34968 const bool synthesis_result =
34969 synthesize_sf4ext_expression::template compile_right<vtype>
34970 (expr_gen, v, operation, branch[1], result);
34971
34972 if (synthesis_result)
34973 {
34974 details::free_node(*expr_gen.node_allocator_,branch[1]);
34975 return result;
34976 }
34977 }
34978 #endif
34979
34980 if (
34981 (details::e_mul == operation) ||
34982 (details::e_div == operation)
34983 )
34984 {
34985 if (details::is_uv_node(branch[1]))
34986 {
34987 typedef details::uv_base_node<Type>* uvbn_ptr_t;
34988
34989 details::operator_type o = static_cast<uvbn_ptr_t>(branch[1])->operation();
34990
34991 if (details::e_neg == o)
34992 {
34993 const Type& v1 = static_cast<uvbn_ptr_t>(branch[1])->v();
34994
34995 details::free_node(*expr_gen.node_allocator_,branch[1]);
34996
34997 switch (operation)
34998 {
34999 case details::e_mul : return expr_gen(details::e_neg,
35000 expr_gen.node_allocator_->
35001 template allocate_rr<typename details::
35002 vov_node<Type,details::mul_op<Type> > >(v,v1));
35003
35004 case details::e_div : return expr_gen(details::e_neg,
35005 expr_gen.node_allocator_->
35006 template allocate_rr<typename details::
35007 vov_node<Type,details::div_op<Type> > >(v,v1));
35008
35009 default : break;
35010 }
35011 }
35012 }
35013 }
35014
35015 switch (operation)
35016 {
35017 #define case_stmt(op0, op1) \
35018 case op0 : return expr_gen.node_allocator_-> \
35019 template allocate_rc<typename details::vob_node<Type,op1<Type> > > \
35020 (v, branch[1]); \
35021
35024 #undef case_stmt
35025 default : return error_node();
35026 }
35027 }
35028 };
35029
35030 struct synthesize_bov_expression
35031 {
35032 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35033 const details::operator_type& operation,
35034 expression_node_ptr (&branch)[2])
35035 {
35036 const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref();
35037
35038 #ifndef exprtk_disable_enhanced_features
35039 if (details::is_sf3ext_node(branch[0]))
35040 {
35041 expression_node_ptr result = error_node();
35042
35043 const bool synthesis_result =
35044 synthesize_sf4ext_expression::template compile_left<vtype>
35045 (expr_gen, v, operation, branch[0], result);
35046
35047 if (synthesis_result)
35048 {
35049 details::free_node(*expr_gen.node_allocator_, branch[0]);
35050
35051 return result;
35052 }
35053 }
35054 #endif
35055
35056 if (
35057 (details::e_add == operation) ||
35058 (details::e_sub == operation) ||
35059 (details::e_mul == operation) ||
35060 (details::e_div == operation)
35061 )
35062 {
35063 if (details::is_uv_node(branch[0]))
35064 {
35065 typedef details::uv_base_node<Type>* uvbn_ptr_t;
35066
35067 details::operator_type o = static_cast<uvbn_ptr_t>(branch[0])->operation();
35068
35069 if (details::e_neg == o)
35070 {
35071 const Type& v0 = static_cast<uvbn_ptr_t>(branch[0])->v();
35072
35073 details::free_node(*expr_gen.node_allocator_,branch[0]);
35074
35075 switch (operation)
35076 {
35077 case details::e_add : return expr_gen.node_allocator_->
35078 template allocate_rr<typename details::
35079 vov_node<Type,details::sub_op<Type> > >(v,v0);
35080
35081 case details::e_sub : return expr_gen(details::e_neg,
35082 expr_gen.node_allocator_->
35083 template allocate_rr<typename details::
35084 vov_node<Type,details::add_op<Type> > >(v0,v));
35085
35086 case details::e_mul : return expr_gen(details::e_neg,
35087 expr_gen.node_allocator_->
35088 template allocate_rr<typename details::
35089 vov_node<Type,details::mul_op<Type> > >(v0,v));
35090
35091 case details::e_div : return expr_gen(details::e_neg,
35092 expr_gen.node_allocator_->
35093 template allocate_rr<typename details::
35094 vov_node<Type,details::div_op<Type> > >(v0,v));
35095 default : break;
35096 }
35097 }
35098 }
35099 }
35100
35101 switch (operation)
35102 {
35103 #define case_stmt(op0, op1) \
35104 case op0 : return expr_gen.node_allocator_-> \
35105 template allocate_cr<typename details::bov_node<Type,op1<Type> > > \
35106 (branch[0], v); \
35107
35110 #undef case_stmt
35111 default : return error_node();
35112 }
35113 }
35114 };
35115
35116 struct synthesize_cob_expression
35117 {
35118 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35119 const details::operator_type& operation,
35120 expression_node_ptr (&branch)[2])
35121 {
35122 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
35123
35124 details::free_node(*expr_gen.node_allocator_,branch[0]);
35125
35126 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35127 {
35128 details::free_node(*expr_gen.node_allocator_,branch[1]);
35129
35130 return expr_gen(T(0));
35131 }
35132 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35133 {
35134 details::free_node(*expr_gen.node_allocator_, branch[1]);
35135
35136 return expr_gen(T(0));
35137 }
35138 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35139 return branch[1];
35140 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35141 return branch[1];
35142
35143 if (details::is_cob_node(branch[1]))
35144 {
35145
35146
35147
35148 if (
35149 (details::e_mul == operation) ||
35150 (details::e_add == operation)
35151 )
35152 {
35153 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35154
35155 if (operation == cobnode->operation())
35156 {
35157 switch (operation)
35158 {
35159 case details::e_add : cobnode->set_c(c + cobnode->c()); break;
35160 case details::e_mul : cobnode->set_c(c * cobnode->c()); break;
35161 default : return error_node();
35162 }
35163
35164 return cobnode;
35165 }
35166 }
35167
35168 if (operation == details::e_mul)
35169 {
35170 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35171 details::operator_type cob_opr = cobnode->operation();
35172
35173 if (
35174 (details::e_div == cob_opr) ||
35175 (details::e_mul == cob_opr)
35176 )
35177 {
35178 switch (cob_opr)
35179 {
35180 case details::e_div : cobnode->set_c(c * cobnode->c()); break;
35181 case details::e_mul : cobnode->set_c(cobnode->c() / c); break;
35182 default : return error_node();
35183 }
35184
35185 return cobnode;
35186 }
35187 }
35188 else if (operation == details::e_div)
35189 {
35190 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35191 details::operator_type cob_opr = cobnode->operation();
35192
35193 if (
35194 (details::e_div == cob_opr) ||
35195 (details::e_mul == cob_opr)
35196 )
35197 {
35198 details::expression_node<Type>* new_cobnode = error_node();
35199
35200 switch (cob_opr)
35201 {
35202 case details::e_div : new_cobnode = expr_gen.node_allocator_->
35203 template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
35204 (c / cobnode->c(), cobnode->move_branch(0));
35205 break;
35206
35207 case details::e_mul : new_cobnode = expr_gen.node_allocator_->
35208 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35209 (c / cobnode->c(), cobnode->move_branch(0));
35210 break;
35211
35212 default : return error_node();
35213 }
35214
35215 details::free_node(*expr_gen.node_allocator_,branch[1]);
35216
35217 return new_cobnode;
35218 }
35219 }
35220 }
35221 #ifndef exprtk_disable_enhanced_features
35222 else if (details::is_sf3ext_node(branch[1]))
35223 {
35224 expression_node_ptr result = error_node();
35225
35226 const bool synthesis_result =
35227 synthesize_sf4ext_expression::template compile_right<ctype>
35228 (expr_gen, c, operation, branch[1], result);
35229
35230 if (synthesis_result)
35231 {
35232 details::free_node(*expr_gen.node_allocator_,branch[1]);
35233
35234 return result;
35235 }
35236 }
35237 #endif
35238
35239 switch (operation)
35240 {
35241 #define case_stmt(op0, op1) \
35242 case op0 : return expr_gen.node_allocator_-> \
35243 template allocate_tt<typename details::cob_node<Type,op1<Type> > > \
35244 (c, branch[1]); \
35245
35248 #undef case_stmt
35249 default : return error_node();
35250 }
35251 }
35252 };
35253
35254 struct synthesize_boc_expression
35255 {
35256 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35257 const details::operator_type& operation,
35258 expression_node_ptr (&branch)[2])
35259 {
35260 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
35261
35262 details::free_node(*(expr_gen.node_allocator_), branch[1]);
35263
35264 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35265 {
35266 details::free_node(*expr_gen.node_allocator_, branch[0]);
35267
35268 return expr_gen(T(0));
35269 }
35270 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35271 {
35272 details::free_node(*expr_gen.node_allocator_, branch[0]);
35273
35274 return expr_gen(std::numeric_limits<T>::quiet_NaN());
35275 }
35276 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35277 return branch[0];
35278 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35279 return branch[0];
35280
35281 if (details::is_boc_node(branch[0]))
35282 {
35283
35284
35285
35286 if (
35287 (details::e_mul == operation) ||
35288 (details::e_add == operation)
35289 )
35290 {
35291 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35292
35293 if (operation == bocnode->operation())
35294 {
35295 switch (operation)
35296 {
35297 case details::e_add : bocnode->set_c(c + bocnode->c()); break;
35298 case details::e_mul : bocnode->set_c(c * bocnode->c()); break;
35299 default : return error_node();
35300 }
35301
35302 return bocnode;
35303 }
35304 }
35305 else if (operation == details::e_div)
35306 {
35307 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35308 details::operator_type boc_opr = bocnode->operation();
35309
35310 if (
35311 (details::e_div == boc_opr) ||
35312 (details::e_mul == boc_opr)
35313 )
35314 {
35315 switch (boc_opr)
35316 {
35317 case details::e_div : bocnode->set_c(c * bocnode->c()); break;
35318 case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
35319 default : return error_node();
35320 }
35321
35322 return bocnode;
35323 }
35324 }
35325 else if (operation == details::e_pow)
35326 {
35327
35328 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35329 details::operator_type boc_opr = bocnode->operation();
35330
35331 if (details::e_pow == boc_opr)
35332 {
35333 bocnode->set_c(bocnode->c() * c);
35334
35335 return bocnode;
35336 }
35337 }
35338 }
35339
35340 #ifndef exprtk_disable_enhanced_features
35341 if (details::is_sf3ext_node(branch[0]))
35342 {
35343 expression_node_ptr result = error_node();
35344
35345 const bool synthesis_result =
35346 synthesize_sf4ext_expression::template compile_left<ctype>
35347 (expr_gen, c, operation, branch[0], result);
35348
35349 if (synthesis_result)
35350 {
35351 free_node(*expr_gen.node_allocator_, branch[0]);
35352
35353 return result;
35354 }
35355 }
35356 #endif
35357
35358 switch (operation)
35359 {
35360 #define case_stmt(op0, op1) \
35361 case op0 : return expr_gen.node_allocator_-> \
35362 template allocate_cr<typename details::boc_node<Type,op1<Type> > > \
35363 (branch[0], c); \
35364
35367 #undef case_stmt
35368 default : return error_node();
35369 }
35370 }
35371 };
35372
35373 struct synthesize_cocob_expression
35374 {
35375 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35376 const details::operator_type& operation,
35377 expression_node_ptr (&branch)[2])
35378 {
35379 expression_node_ptr result = error_node();
35380
35381
35382 if (details::is_cob_node(branch[0]))
35383 {
35384 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[0]);
35385
35386 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
35387
35388 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35389 {
35390 details::free_node(*expr_gen.node_allocator_, branch[0]);
35391 details::free_node(*expr_gen.node_allocator_, branch[1]);
35392
35393 return expr_gen(T(0));
35394 }
35395 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35396 {
35397 details::free_node(*expr_gen.node_allocator_, branch[0]);
35398 details::free_node(*expr_gen.node_allocator_, branch[1]);
35399
35400 return expr_gen(T(std::numeric_limits<T>::quiet_NaN()));
35401 }
35402 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35403 {
35404 details::free_node(*expr_gen.node_allocator_, branch[1]);
35405
35406 return branch[0];
35407 }
35408 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35409 {
35410 details::free_node(*expr_gen.node_allocator_, branch[1]);
35411
35412 return branch[0];
35413 }
35414 else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
35415 {
35416 details::free_node(*expr_gen.node_allocator_, branch[1]);
35417
35418 return branch[0];
35419 }
35420
35421 const bool op_addsub = (details::e_add == cobnode->operation()) ||
35422 (details::e_sub == cobnode->operation()) ;
35423
35424 if (op_addsub)
35425 {
35426 switch (operation)
35427 {
35428 case details::e_add : cobnode->set_c(cobnode->c() + c); break;
35429 case details::e_sub : cobnode->set_c(cobnode->c() - c); break;
35430 default : return error_node();
35431 }
35432
35433 result = cobnode;
35434 }
35435 else if (details::e_mul == cobnode->operation())
35436 {
35437 switch (operation)
35438 {
35439 case details::e_mul : cobnode->set_c(cobnode->c() * c); break;
35440 case details::e_div : cobnode->set_c(cobnode->c() / c); break;
35441 default : return error_node();
35442 }
35443
35444 result = cobnode;
35445 }
35446 else if (details::e_div == cobnode->operation())
35447 {
35448 if (details::e_mul == operation)
35449 {
35450 cobnode->set_c(cobnode->c() * c);
35451 result = cobnode;
35452 }
35453 else if (details::e_div == operation)
35454 {
35455 result = expr_gen.node_allocator_->
35456 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35457 (cobnode->c() / c, cobnode->move_branch(0));
35458
35459 details::free_node(*expr_gen.node_allocator_, branch[0]);
35460 }
35461 }
35462
35463 if (result)
35464 {
35465 details::free_node(*expr_gen.node_allocator_,branch[1]);
35466 }
35467 }
35468
35469
35470 else if (details::is_cob_node(branch[1]))
35471 {
35472 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35473
35474 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
35475
35476 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35477 {
35478 details::free_node(*expr_gen.node_allocator_, branch[0]);
35479 details::free_node(*expr_gen.node_allocator_, branch[1]);
35480
35481 return expr_gen(T(0));
35482 }
35483 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35484 {
35485 details::free_node(*expr_gen.node_allocator_, branch[0]);
35486 details::free_node(*expr_gen.node_allocator_, branch[1]);
35487
35488 return expr_gen(T(0));
35489 }
35490 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35491 {
35492 details::free_node(*expr_gen.node_allocator_, branch[0]);
35493
35494 return branch[1];
35495 }
35496 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35497 {
35498 details::free_node(*expr_gen.node_allocator_, branch[0]);
35499
35500 return branch[1];
35501 }
35502
35503 if (details::e_add == cobnode->operation())
35504 {
35505 if (details::e_add == operation)
35506 {
35507 cobnode->set_c(c + cobnode->c());
35508 result = cobnode;
35509 }
35510 else if (details::e_sub == operation)
35511 {
35512 result = expr_gen.node_allocator_->
35513 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
35514 (c - cobnode->c(), cobnode->move_branch(0));
35515
35516 details::free_node(*expr_gen.node_allocator_,branch[1]);
35517 }
35518 }
35519 else if (details::e_sub == cobnode->operation())
35520 {
35521 if (details::e_add == operation)
35522 {
35523 cobnode->set_c(c + cobnode->c());
35524 result = cobnode;
35525 }
35526 else if (details::e_sub == operation)
35527 {
35528 result = expr_gen.node_allocator_->
35529 template allocate_tt<typename details::cob_node<Type,details::add_op<Type> > >
35530 (c - cobnode->c(), cobnode->move_branch(0));
35531
35532 details::free_node(*expr_gen.node_allocator_,branch[1]);
35533 }
35534 }
35535 else if (details::e_mul == cobnode->operation())
35536 {
35537 if (details::e_mul == operation)
35538 {
35539 cobnode->set_c(c * cobnode->c());
35540 result = cobnode;
35541 }
35542 else if (details::e_div == operation)
35543 {
35544 result = expr_gen.node_allocator_->
35545 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35546 (c / cobnode->c(), cobnode->move_branch(0));
35547
35548 details::free_node(*expr_gen.node_allocator_,branch[1]);
35549 }
35550 }
35551 else if (details::e_div == cobnode->operation())
35552 {
35553 if (details::e_mul == operation)
35554 {
35555 cobnode->set_c(c * cobnode->c());
35556 result = cobnode;
35557 }
35558 else if (details::e_div == operation)
35559 {
35560 result = expr_gen.node_allocator_->
35561 template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
35562 (c / cobnode->c(), cobnode->move_branch(0));
35563
35564 details::free_node(*expr_gen.node_allocator_,branch[1]);
35565 }
35566 }
35567
35568 if (result)
35569 {
35570 details::free_node(*expr_gen.node_allocator_,branch[0]);
35571 }
35572 }
35573
35574 return result;
35575 }
35576 };
35577
35578 struct synthesize_coboc_expression
35579 {
35580 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35581 const details::operator_type& operation,
35582 expression_node_ptr (&branch)[2])
35583 {
35584 expression_node_ptr result = error_node();
35585
35586
35587 if (details::is_boc_node(branch[0]))
35588 {
35589 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35590
35591 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
35592
35593 if (details::e_add == bocnode->operation())
35594 {
35595 switch (operation)
35596 {
35597 case details::e_add : bocnode->set_c(bocnode->c() + c); break;
35598 case details::e_sub : bocnode->set_c(bocnode->c() - c); break;
35599 default : return error_node();
35600 }
35601
35602 result = bocnode;
35603 }
35604 else if (details::e_mul == bocnode->operation())
35605 {
35606 switch (operation)
35607 {
35608 case details::e_mul : bocnode->set_c(bocnode->c() * c); break;
35609 case details::e_div : bocnode->set_c(bocnode->c() / c); break;
35610 default : return error_node();
35611 }
35612
35613 result = bocnode;
35614 }
35615 else if (details::e_sub == bocnode->operation())
35616 {
35617 if (details::e_add == operation)
35618 {
35619 result = expr_gen.node_allocator_->
35620 template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
35621 (bocnode->move_branch(0), c - bocnode->c());
35622
35623 details::free_node(*expr_gen.node_allocator_,branch[0]);
35624 }
35625 else if (details::e_sub == operation)
35626 {
35627 bocnode->set_c(bocnode->c() + c);
35628 result = bocnode;
35629 }
35630 }
35631 else if (details::e_div == bocnode->operation())
35632 {
35633 switch (operation)
35634 {
35635 case details::e_div : bocnode->set_c(bocnode->c() * c); break;
35636 case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
35637 default : return error_node();
35638 }
35639
35640 result = bocnode;
35641 }
35642
35643 if (result)
35644 {
35645 details::free_node(*expr_gen.node_allocator_, branch[1]);
35646 }
35647 }
35648
35649
35650 else if (details::is_boc_node(branch[1]))
35651 {
35652 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[1]);
35653
35654 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
35655
35656 if (details::e_add == bocnode->operation())
35657 {
35658 if (details::e_add == operation)
35659 {
35660 bocnode->set_c(c + bocnode->c());
35661 result = bocnode;
35662 }
35663 else if (details::e_sub == operation)
35664 {
35665 result = expr_gen.node_allocator_->
35666 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
35667 (c - bocnode->c(), bocnode->move_branch(0));
35668
35669 details::free_node(*expr_gen.node_allocator_,branch[1]);
35670 }
35671 }
35672 else if (details::e_sub == bocnode->operation())
35673 {
35674 if (details::e_add == operation)
35675 {
35676 result = expr_gen.node_allocator_->
35677 template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
35678 (bocnode->move_branch(0), c - bocnode->c());
35679
35680 details::free_node(*expr_gen.node_allocator_,branch[1]);
35681 }
35682 else if (details::e_sub == operation)
35683 {
35684 result = expr_gen.node_allocator_->
35685 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
35686 (c + bocnode->c(), bocnode->move_branch(0));
35687
35688 details::free_node(*expr_gen.node_allocator_,branch[1]);
35689 }
35690 }
35691 else if (details::e_mul == bocnode->operation())
35692 {
35693 if (details::e_mul == operation)
35694 {
35695 bocnode->set_c(c * bocnode->c());
35696 result = bocnode;
35697 }
35698 else if (details::e_div == operation)
35699 {
35700 result = expr_gen.node_allocator_->
35701 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35702 (c / bocnode->c(), bocnode->move_branch(0));
35703
35704 details::free_node(*expr_gen.node_allocator_,branch[1]);
35705 }
35706 }
35707 else if (details::e_div == bocnode->operation())
35708 {
35709 if (details::e_mul == operation)
35710 {
35711 bocnode->set_c(bocnode->c() / c);
35712 result = bocnode;
35713 }
35714 else if (details::e_div == operation)
35715 {
35716 result = expr_gen.node_allocator_->
35717 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35718 (c * bocnode->c(), bocnode->move_branch(0));
35719
35720 details::free_node(*expr_gen.node_allocator_,branch[1]);
35721 }
35722 }
35723
35724 if (result)
35725 {
35726 details::free_node(*expr_gen.node_allocator_,branch[0]);
35727 }
35728 }
35729
35730 return result;
35731 }
35732 };
35733
35734 #ifndef exprtk_disable_enhanced_features
35735 inline bool synthesize_expression(const details::operator_type& operation,
35736 expression_node_ptr (&branch)[2],
35737 expression_node_ptr& result)
35738 {
35739 result = error_node();
35740
35741 if (!operation_optimisable(operation))
35742 return false;
35743
35744 const std::string node_id = branch_to_id(branch);
35745
35746 const typename synthesize_map_t::iterator itr = synthesize_map_.find(node_id);
35747
35748 if (synthesize_map_.end() != itr)
35749 {
35750 result = itr->second((*this), operation, branch);
35751
35752 return true;
35753 }
35754 else
35755 return false;
35756 }
35757
35758 struct synthesize_vov_expression
35759 {
35760 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35761 const details::operator_type& operation,
35762 expression_node_ptr (&branch)[2])
35763 {
35764 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
35765 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
35766
35767 switch (operation)
35768 {
35769 #define case_stmt(op0, op1) \
35770 case op0 : return expr_gen.node_allocator_-> \
35771 template allocate_rr<typename details::vov_node<Type,op1<Type> > > \
35772 (v1, v2); \
35773
35776 #undef case_stmt
35777 default : return error_node();
35778 }
35779 }
35780 };
35781
35782 struct synthesize_cov_expression
35783 {
35784 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35785 const details::operator_type& operation,
35786 expression_node_ptr (&branch)[2])
35787 {
35788 const Type c =
static_cast<details::literal_node<Type>*
> (branch[0])->
value();
35789 const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref ();
35790
35791 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35792
35793 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35794 return expr_gen(T(0));
35795 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35796 return expr_gen(T(0));
35797 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35798 return static_cast<details::variable_node<Type>*>(branch[1]);
35799 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35800 return static_cast<details::variable_node<Type>*>(branch[1]);
35801
35802 switch (operation)
35803 {
35804 #define case_stmt(op0, op1) \
35805 case op0 : return expr_gen.node_allocator_-> \
35806 template allocate_cr<typename details::cov_node<Type,op1<Type> > > \
35807 (c, v); \
35808
35811 #undef case_stmt
35812 default : return error_node();
35813 }
35814 }
35815 };
35816
35817 struct synthesize_voc_expression
35818 {
35819 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35820 const details::operator_type& operation,
35821 expression_node_ptr (&branch)[2])
35822 {
35823 const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref ();
35824 const Type c =
static_cast<details::literal_node<Type>*
> (branch[1])->
value();
35825
35826 details::free_node(*(expr_gen.node_allocator_), branch[1]);
35827
35828 if (expr_gen.cardinal_pow_optimisable(operation,c))
35829 {
35830 if (std::equal_to<T>()(T(1),c))
35831 return branch[0];
35832 else
35833 return expr_gen.cardinal_pow_optimisation(v,c);
35834 }
35835 else if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35836 return expr_gen(T(0));
35837 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35838 return expr_gen(std::numeric_limits<T>::quiet_NaN());
35839 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35840 return static_cast<details::variable_node<Type>*>(branch[0]);
35841 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35842 return static_cast<details::variable_node<Type>*>(branch[0]);
35843 else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
35844 return static_cast<details::variable_node<Type>*>(branch[0]);
35845
35846 switch (operation)
35847 {
35848 #define case_stmt(op0, op1) \
35849 case op0 : return expr_gen.node_allocator_-> \
35850 template allocate_rc<typename details::voc_node<Type,op1<Type> > > \
35851 (v, c); \
35852
35855 #undef case_stmt
35856 default : return error_node();
35857 }
35858 }
35859 };
35860
35861 struct synthesize_sf3ext_expression
35862 {
35863 template <typename T0, typename T1, typename T2>
35864 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35865 const details::operator_type& sf3opr,
35866 T0 t0, T1 t1, T2 t2)
35867 {
35868 switch (sf3opr)
35869 {
35870 #define case_stmt(op) \
35871 case details::e_sf##op : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,details::sf##op##_op<Type> >:: \
35872 allocate(*(expr_gen.node_allocator_), t0, t1, t2); \
35873
35882 #undef case_stmt
35883 default : return error_node();
35884 }
35885 }
35886
35887 template <typename T0, typename T1, typename T2>
35888 static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
35889 T0 t0, T1 t1, T2 t2,
35890 expression_node_ptr& result)
35891 {
35892 details::operator_type sf3opr;
35893
35894 if (!expr_gen.sf3_optimisable(id,sf3opr))
35895 return false;
35896 else
35897 result = synthesize_sf3ext_expression::template process<T0, T1, T2>
35898 (expr_gen, sf3opr, t0, t1, t2);
35899
35900 return true;
35901 }
35902 };
35903
35904 struct synthesize_sf4ext_expression
35905 {
35906 template <typename T0, typename T1, typename T2, typename T3>
35907 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35908 const details::operator_type& sf4opr,
35909 T0 t0, T1 t1, T2 t2, T3 t3)
35910 {
35911 switch (sf4opr)
35912 {
35913 #define case_stmt0(op) \
35914 case details::e_sf##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sf##op##_op<Type> >:: \
35915 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
35916
35917 #define case_stmt1(op) \
35918 case details::e_sf4ext##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sfext##op##_op<Type> >:: \
35919 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
35920
35930
35947
35948 #undef case_stmt0
35949 #undef case_stmt1
35950 default : return error_node();
35951 }
35952 }
35953
35954 template <typename T0, typename T1, typename T2, typename T3>
35955 static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
35956 T0 t0, T1 t1, T2 t2, T3 t3,
35957 expression_node_ptr& result)
35958 {
35959 details::operator_type sf4opr;
35960
35961 if (!expr_gen.sf4_optimisable(id,sf4opr))
35962 return false;
35963 else
35964 result = synthesize_sf4ext_expression::template process<T0, T1, T2, T3>
35965 (expr_gen, sf4opr, t0, t1, t2, t3);
35966
35967 return true;
35968 }
35969
35970
35971 template <typename ExternalType>
35972 static inline bool compile_right(expression_generator<Type>& expr_gen,
35973 ExternalType t,
35974 const details::operator_type& operation,
35975 expression_node_ptr& sf3node,
35976 expression_node_ptr& result)
35977 {
35978 if (!details::is_sf3ext_node(sf3node))
35979 return false;
35980
35981 typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
35982
35983 sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
35984 const std::string id = "t" + expr_gen.to_str(operation) + "(" + n->type_id() + ")";
35985
35986 switch (n->type())
35987 {
35988 case details::expression_node<Type>::e_covoc : return compile_right_impl
35989 <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
35990 (expr_gen, id, t, sf3node, result);
35991
35992 case details::expression_node<Type>::e_covov : return compile_right_impl
35993 <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
35994 (expr_gen, id, t, sf3node, result);
35995
35996 case details::expression_node<Type>::e_vocov : return compile_right_impl
35997 <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
35998 (expr_gen, id, t, sf3node, result);
35999
36000 case details::expression_node<Type>::e_vovoc : return compile_right_impl
36001 <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
36002 (expr_gen, id, t, sf3node, result);
36003
36004 case details::expression_node<Type>::e_vovov : return compile_right_impl
36005 <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
36006 (expr_gen, id, t, sf3node, result);
36007
36008 default : return false;
36009 }
36010 }
36011
36012
36013 template <typename ExternalType>
36014 static inline bool compile_left(expression_generator<Type>& expr_gen,
36015 ExternalType t,
36016 const details::operator_type& operation,
36017 expression_node_ptr& sf3node,
36018 expression_node_ptr& result)
36019 {
36020 if (!details::is_sf3ext_node(sf3node))
36021 return false;
36022
36023 typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
36024
36025 sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
36026
36027 const std::string id = "(" + n->type_id() + ")" + expr_gen.to_str(operation) + "t";
36028
36029 switch (n->type())
36030 {
36031 case details::expression_node<Type>::e_covoc : return compile_left_impl
36032 <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
36033 (expr_gen, id, t, sf3node, result);
36034
36035 case details::expression_node<Type>::e_covov : return compile_left_impl
36036 <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
36037 (expr_gen, id, t, sf3node, result);
36038
36039 case details::expression_node<Type>::e_vocov : return compile_left_impl
36040 <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
36041 (expr_gen, id, t, sf3node, result);
36042
36043 case details::expression_node<Type>::e_vovoc : return compile_left_impl
36044 <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
36045 (expr_gen, id, t, sf3node, result);
36046
36047 case details::expression_node<Type>::e_vovov : return compile_left_impl
36048 <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
36049 (expr_gen, id, t, sf3node, result);
36050
36051 default : return false;
36052 }
36053 }
36054
36055 template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
36056 static inline bool compile_right_impl(expression_generator<Type>& expr_gen,
36057 const std::string& id,
36058 ExternalType t,
36059 expression_node_ptr& node,
36060 expression_node_ptr& result)
36061 {
36062 SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
36063
36064 if (n)
36065 {
36066 T0 t0 = n->t0();
36067 T1 t1 = n->t1();
36068 T2 t2 = n->t2();
36069
36070 return synthesize_sf4ext_expression::template compile<ExternalType, T0, T1, T2>
36071 (expr_gen, id, t, t0, t1, t2, result);
36072 }
36073 else
36074 return false;
36075 }
36076
36077 template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
36078 static inline bool compile_left_impl(expression_generator<Type>& expr_gen,
36079 const std::string& id,
36080 ExternalType t,
36081 expression_node_ptr& node,
36082 expression_node_ptr& result)
36083 {
36084 SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
36085
36086 if (n)
36087 {
36088 T0 t0 = n->t0();
36089 T1 t1 = n->t1();
36090 T2 t2 = n->t2();
36091
36092 return synthesize_sf4ext_expression::template compile<T0, T1, T2, ExternalType>
36093 (expr_gen, id, t0, t1, t2, t, result);
36094 }
36095 else
36096 return false;
36097 }
36098 };
36099
36100 struct synthesize_vovov_expression0
36101 {
36102 typedef typename vovov_t::type0 node_type;
36103 typedef typename vovov_t::sf3_type sf3_type;
36104
36105 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36106 const details::operator_type& operation,
36107 expression_node_ptr (&branch)[2])
36108 {
36109
36110 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
36111 const Type& v0 = vov->v0();
36112 const Type& v1 = vov->v1();
36113 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
36114 const details::operator_type o0 = vov->operation();
36115 const details::operator_type o1 = operation;
36116
36117 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36118
36119 expression_node_ptr result = error_node();
36120
36121 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36122 {
36123
36124 if ((details::e_div == o0) && (details::e_div == o1))
36125 {
36126 const bool synthesis_result =
36127 synthesize_sf3ext_expression::
36128 template compile<vtype, vtype, vtype>(expr_gen, "t/(t*t)", v0, v1, v2, result);
36129
36130 exprtk_debug((
"(v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)\n"));
36131
36132 return (synthesis_result) ? result : error_node();
36133 }
36134 }
36135
36136 const bool synthesis_result =
36137 synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
36138 (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
36139
36140 if (synthesis_result)
36141 return result;
36142
36143 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36144 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36145
36146 if (!expr_gen.valid_operator(o0,f0))
36147 return error_node();
36148 else if (!expr_gen.valid_operator(o1,f1))
36149 return error_node();
36150 else
36151 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
36152 }
36153
36154 static inline std::string id(expression_generator<Type>& expr_gen,
36155 const details::operator_type o0,
36156 const details::operator_type o1)
36157 {
36158 return details::build_string()
36159 << "(t" << expr_gen.to_str(o0)
36160 << "t)" << expr_gen.to_str(o1)
36161 << "t";
36162 }
36163 };
36164
36165 struct synthesize_vovov_expression1
36166 {
36167 typedef typename vovov_t::type1 node_type;
36168 typedef typename vovov_t::sf3_type sf3_type;
36169
36170 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36171 const details::operator_type& operation,
36172 expression_node_ptr (&branch)[2])
36173 {
36174
36175 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
36176 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
36177 const Type& v1 = vov->v0();
36178 const Type& v2 = vov->v1();
36179 const details::operator_type o0 = operation;
36180 const details::operator_type o1 = vov->operation();
36181
36182 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36183
36184 expression_node_ptr result = error_node();
36185
36186 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36187 {
36188
36189 if ((details::e_div == o0) && (details::e_div == o1))
36190 {
36191 const bool synthesis_result =
36192 synthesize_sf3ext_expression::
36193 template compile<vtype, vtype, vtype>(expr_gen, "(t*t)/t", v0, v2, v1, result);
36194
36195 exprtk_debug((
"v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1\n"));
36196
36197 return (synthesis_result) ? result : error_node();
36198 }
36199 }
36200
36201 const bool synthesis_result =
36202 synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
36203 (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
36204
36205 if (synthesis_result)
36206 return result;
36207
36208 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36209 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36210
36211 if (!expr_gen.valid_operator(o0,f0))
36212 return error_node();
36213 else if (!expr_gen.valid_operator(o1,f1))
36214 return error_node();
36215 else
36216 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
36217 }
36218
36219 static inline std::string id(expression_generator<Type>& expr_gen,
36220 const details::operator_type o0,
36221 const details::operator_type o1)
36222 {
36223 return details::build_string()
36224 << "t" << expr_gen.to_str(o0)
36225 << "(t" << expr_gen.to_str(o1)
36226 << "t)";
36227 }
36228 };
36229
36230 struct synthesize_vovoc_expression0
36231 {
36232 typedef typename vovoc_t::type0 node_type;
36233 typedef typename vovoc_t::sf3_type sf3_type;
36234
36235 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36236 const details::operator_type& operation,
36237 expression_node_ptr (&branch)[2])
36238 {
36239
36240 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
36241 const Type& v0 = vov->v0();
36242 const Type& v1 = vov->v1();
36243 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
36244 const details::operator_type o0 = vov->operation();
36245 const details::operator_type o1 = operation;
36246
36247 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36248 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36249
36250 expression_node_ptr result = error_node();
36251
36252 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36253 {
36254
36255 if ((details::e_div == o0) && (details::e_div == o1))
36256 {
36257 const bool synthesis_result =
36258 synthesize_sf3ext_expression::
36259 template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
36260
36261 exprtk_debug((
"(v0 / v1) / c --> (vovoc) v0 / (v1 * c)\n"));
36262
36263 return (synthesis_result) ? result : error_node();
36264 }
36265 }
36266
36267 const bool synthesis_result =
36268 synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
36269 (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
36270
36271 if (synthesis_result)
36272 return result;
36273
36274 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36275 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36276
36277 if (!expr_gen.valid_operator(o0,f0))
36278 return error_node();
36279 else if (!expr_gen.valid_operator(o1,f1))
36280 return error_node();
36281 else
36282 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
36283 }
36284
36285 static inline std::string id(expression_generator<Type>& expr_gen,
36286 const details::operator_type o0,
36287 const details::operator_type o1)
36288 {
36289 return details::build_string()
36290 << "(t" << expr_gen.to_str(o0)
36291 << "t)" << expr_gen.to_str(o1)
36292 << "t";
36293 }
36294 };
36295
36296 struct synthesize_vovoc_expression1
36297 {
36298 typedef typename vovoc_t::type1 node_type;
36299 typedef typename vovoc_t::sf3_type sf3_type;
36300
36301 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36302 const details::operator_type& operation,
36303 expression_node_ptr (&branch)[2])
36304 {
36305
36306 const details::voc_base_node<Type>* voc = static_cast<const details::voc_base_node<Type>*>(branch[1]);
36307 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
36308 const Type& v1 = voc->v();
36309 const Type c = voc->c();
36310 const details::operator_type o0 = operation;
36311 const details::operator_type o1 = voc->operation();
36312
36313 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36314
36315 expression_node_ptr result = error_node();
36316
36317 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36318 {
36319
36320 if ((details::e_div == o0) && (details::e_div == o1))
36321 {
36322 const bool synthesis_result =
36323 synthesize_sf3ext_expression::
36324 template compile<vtype, ctype, vtype>(expr_gen, "(t*t)/t", v0, c, v1, result);
36325
36326 exprtk_debug((
"v0 / (v1 / c) --> (vocov) (v0 * c) / v1\n"));
36327
36328 return (synthesis_result) ? result : error_node();
36329 }
36330 }
36331
36332 const bool synthesis_result =
36333 synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
36334 (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
36335
36336 if (synthesis_result)
36337 return result;
36338
36339 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36340 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36341
36342 if (!expr_gen.valid_operator(o0,f0))
36343 return error_node();
36344 else if (!expr_gen.valid_operator(o1,f1))
36345 return error_node();
36346 else
36347 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
36348 }
36349
36350 static inline std::string id(expression_generator<Type>& expr_gen,
36351 const details::operator_type o0,
36352 const details::operator_type o1)
36353 {
36354 return details::build_string()
36355 << "t" << expr_gen.to_str(o0)
36356 << "(t" << expr_gen.to_str(o1)
36357 << "t)";
36358 }
36359 };
36360
36361 struct synthesize_vocov_expression0
36362 {
36363 typedef typename vocov_t::type0 node_type;
36364 typedef typename vocov_t::sf3_type sf3_type;
36365
36366 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36367 const details::operator_type& operation,
36368 expression_node_ptr (&branch)[2])
36369 {
36370
36371 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
36372 const Type& v0 = voc->v();
36373 const Type c = voc->c();
36374 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
36375 const details::operator_type o0 = voc->operation();
36376 const details::operator_type o1 = operation;
36377
36378 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36379
36380 expression_node_ptr result = error_node();
36381
36382 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36383 {
36384
36385 if ((details::e_div == o0) && (details::e_div == o1))
36386 {
36387 const bool synthesis_result =
36388 synthesize_sf3ext_expression::
36389 template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
36390
36391 exprtk_debug((
"(v0 / c) / v1 --> (vovoc) v0 / (v1 * c)\n"));
36392
36393 return (synthesis_result) ? result : error_node();
36394 }
36395 }
36396
36397 const bool synthesis_result =
36398 synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
36399 (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
36400
36401 if (synthesis_result)
36402 return result;
36403
36404 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36405 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36406
36407 if (!expr_gen.valid_operator(o0,f0))
36408 return error_node();
36409 else if (!expr_gen.valid_operator(o1,f1))
36410 return error_node();
36411 else
36412 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
36413 }
36414
36415 static inline std::string id(expression_generator<Type>& expr_gen,
36416 const details::operator_type o0,
36417 const details::operator_type o1)
36418 {
36419 return details::build_string()
36420 << "(t" << expr_gen.to_str(o0)
36421 << "t)" << expr_gen.to_str(o1)
36422 << "t";
36423 }
36424 };
36425
36426 struct synthesize_vocov_expression1
36427 {
36428 typedef typename vocov_t::type1 node_type;
36429 typedef typename vocov_t::sf3_type sf3_type;
36430
36431 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36432 const details::operator_type& operation,
36433 expression_node_ptr (&branch)[2])
36434 {
36435
36436 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
36437 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
36438 const Type c = cov->c();
36439 const Type& v1 = cov->v();
36440 const details::operator_type o0 = operation;
36441 const details::operator_type o1 = cov->operation();
36442
36443 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36444
36445 expression_node_ptr result = error_node();
36446
36447 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36448 {
36449
36450 if ((details::e_div == o0) && (details::e_div == o1))
36451 {
36452 const bool synthesis_result =
36453 synthesize_sf3ext_expression::
36454 template compile<vtype, vtype, ctype>(expr_gen, "(t*t)/t", v0, v1, c, result);
36455
36456 exprtk_debug((
"v0 / (c / v1) --> (vovoc) (v0 * v1) / c\n"));
36457
36458 return (synthesis_result) ? result : error_node();
36459 }
36460 }
36461
36462 const bool synthesis_result =
36463 synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
36464 (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
36465
36466 if (synthesis_result)
36467 return result;
36468
36469 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36470 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36471
36472 if (!expr_gen.valid_operator(o0,f0))
36473 return error_node();
36474 else if (!expr_gen.valid_operator(o1,f1))
36475 return error_node();
36476 else
36477 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
36478 }
36479
36480 static inline std::string id(expression_generator<Type>& expr_gen,
36481 const details::operator_type o0,
36482 const details::operator_type o1)
36483 {
36484 return details::build_string()
36485 << "t" << expr_gen.to_str(o0)
36486 << "(t" << expr_gen.to_str(o1)
36487 << "t)";
36488 }
36489 };
36490
36491 struct synthesize_covov_expression0
36492 {
36493 typedef typename covov_t::type0 node_type;
36494 typedef typename covov_t::sf3_type sf3_type;
36495
36496 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36497 const details::operator_type& operation,
36498 expression_node_ptr (&branch)[2])
36499 {
36500
36501 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
36502 const Type c = cov->c();
36503 const Type& v0 = cov->v();
36504 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
36505 const details::operator_type o0 = cov->operation();
36506 const details::operator_type o1 = operation;
36507
36508 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36509
36510 expression_node_ptr result = error_node();
36511
36512 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36513 {
36514
36515 if ((details::e_div == o0) && (details::e_div == o1))
36516 {
36517 const bool synthesis_result =
36518 synthesize_sf3ext_expression::
36519 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", c, v0, v1, result);
36520
36521 exprtk_debug((
"(c / v0) / v1 --> (covov) c / (v0 * v1)\n"));
36522
36523 return (synthesis_result) ? result : error_node();
36524 }
36525 }
36526
36527 const bool synthesis_result =
36528 synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
36529 (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
36530
36531 if (synthesis_result)
36532 return result;
36533
36534 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36535 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36536
36537 if (!expr_gen.valid_operator(o0,f0))
36538 return error_node();
36539 else if (!expr_gen.valid_operator(o1,f1))
36540 return error_node();
36541 else
36542 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
36543 }
36544
36545 static inline std::string id(expression_generator<Type>& expr_gen,
36546 const details::operator_type o0,
36547 const details::operator_type o1)
36548 {
36549 return details::build_string()
36550 << "(t" << expr_gen.to_str(o0)
36551 << "t)" << expr_gen.to_str(o1)
36552 << "t";
36553 }
36554 };
36555
36556 struct synthesize_covov_expression1
36557 {
36558 typedef typename covov_t::type1 node_type;
36559 typedef typename covov_t::sf3_type sf3_type;
36560
36561 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36562 const details::operator_type& operation,
36563 expression_node_ptr (&branch)[2])
36564 {
36565
36566 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
36567 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
36568 const Type& v0 = vov->v0();
36569 const Type& v1 = vov->v1();
36570 const details::operator_type o0 = operation;
36571 const details::operator_type o1 = vov->operation();
36572
36573 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36574 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36575
36576 expression_node_ptr result = error_node();
36577
36578 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36579 {
36580
36581 if ((details::e_div == o0) && (details::e_div == o1))
36582 {
36583 const bool synthesis_result =
36584 synthesize_sf3ext_expression::
36585 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", c, v1, v0, result);
36586
36587 exprtk_debug((
"c / (v0 / v1) --> (covov) (c * v1) / v0\n"));
36588
36589 return (synthesis_result) ? result : error_node();
36590 }
36591 }
36592
36593 const bool synthesis_result =
36594 synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
36595 (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
36596
36597 if (synthesis_result)
36598 return result;
36599
36600 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36601 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36602
36603 if (!expr_gen.valid_operator(o0,f0))
36604 return error_node();
36605 else if (!expr_gen.valid_operator(o1,f1))
36606 return error_node();
36607 else
36608 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
36609 }
36610
36611 static inline std::string id(expression_generator<Type>& expr_gen,
36612 const details::operator_type o0,
36613 const details::operator_type o1)
36614 {
36615 return details::build_string()
36616 << "t" << expr_gen.to_str(o0)
36617 << "(t" << expr_gen.to_str(o1)
36618 << "t)";
36619 }
36620 };
36621
36622 struct synthesize_covoc_expression0
36623 {
36624 typedef typename covoc_t::type0 node_type;
36625 typedef typename covoc_t::sf3_type sf3_type;
36626
36627 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36628 const details::operator_type& operation,
36629 expression_node_ptr (&branch)[2])
36630 {
36631
36632 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
36633 const Type c0 = cov->c();
36634 const Type& v = cov->v();
36635 const Type c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
36636 const details::operator_type o0 = cov->operation();
36637 const details::operator_type o1 = operation;
36638
36639 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36640 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36641
36642 expression_node_ptr result = error_node();
36643
36644 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36645 {
36646
36647 if ((details::e_add == o0) && (details::e_add == o1))
36648 {
36649 exprtk_debug((
"(c0 + v) + c1 --> (cov) (c0 + c1) + v\n"));
36650
36651 return expr_gen.node_allocator_->
36652 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
36653 }
36654
36655 else if ((details::e_add == o0) && (details::e_sub == o1))
36656 {
36657 exprtk_debug((
"(c0 + v) - c1 --> (cov) (c0 - c1) + v\n"));
36658
36659 return expr_gen.node_allocator_->
36660 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
36661 }
36662
36663 else if ((details::e_sub == o0) && (details::e_add == o1))
36664 {
36665 exprtk_debug((
"(c0 - v) + c1 --> (cov) (c0 + c1) - v\n"));
36666
36667 return expr_gen.node_allocator_->
36668 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
36669 }
36670
36671 else if ((details::e_sub == o0) && (details::e_sub == o1))
36672 {
36673 exprtk_debug((
"(c0 - v) - c1 --> (cov) (c0 - c1) - v\n"));
36674
36675 return expr_gen.node_allocator_->
36676 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
36677 }
36678
36679 else if ((details::e_mul == o0) && (details::e_mul == o1))
36680 {
36681 exprtk_debug((
"(c0 * v) * c1 --> (cov) (c0 * c1) * v\n"));
36682
36683 return expr_gen.node_allocator_->
36684 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
36685 }
36686
36687 else if ((details::e_mul == o0) && (details::e_div == o1))
36688 {
36689 exprtk_debug((
"(c0 * v) / c1 --> (cov) (c0 / c1) * v\n"));
36690
36691 return expr_gen.node_allocator_->
36692 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
36693 }
36694
36695 else if ((details::e_div == o0) && (details::e_mul == o1))
36696 {
36697 exprtk_debug((
"(c0 / v) * c1 --> (cov) (c0 * c1) / v\n"));
36698
36699 return expr_gen.node_allocator_->
36700 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
36701 }
36702
36703 else if ((details::e_div == o0) && (details::e_div == o1))
36704 {
36705 exprtk_debug((
"(c0 / v) / c1 --> (cov) (c0 / c1) / v\n"));
36706
36707 return expr_gen.node_allocator_->
36708 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
36709 }
36710 }
36711
36712 const bool synthesis_result =
36713 synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
36714 (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
36715
36716 if (synthesis_result)
36717 return result;
36718
36719 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36720 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36721
36722 if (!expr_gen.valid_operator(o0,f0))
36723 return error_node();
36724 else if (!expr_gen.valid_operator(o1,f1))
36725 return error_node();
36726 else
36727 return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
36728 }
36729
36730 static inline std::string id(expression_generator<Type>& expr_gen,
36731 const details::operator_type o0,
36732 const details::operator_type o1)
36733 {
36734 return details::build_string()
36735 << "(t" << expr_gen.to_str(o0)
36736 << "t)" << expr_gen.to_str(o1)
36737 << "t";
36738 }
36739 };
36740
36741 struct synthesize_covoc_expression1
36742 {
36743 typedef typename covoc_t::type1 node_type;
36744 typedef typename covoc_t::sf3_type sf3_type;
36745
36746 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36747 const details::operator_type& operation,
36748 expression_node_ptr (&branch)[2])
36749 {
36750
36751 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
36752 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
36753 const Type& v = voc->v();
36754 const Type c1 = voc->c();
36755 const details::operator_type o0 = operation;
36756 const details::operator_type o1 = voc->operation();
36757
36758 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36759 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36760
36761 expression_node_ptr result = error_node();
36762
36763 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36764 {
36765
36766 if ((details::e_add == o0) && (details::e_add == o1))
36767 {
36768 exprtk_debug((
"(c0) + (v + c1) --> (cov) (c0 + c1) + v\n"));
36769
36770 return expr_gen.node_allocator_->
36771 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
36772 }
36773
36774 else if ((details::e_add == o0) && (details::e_sub == o1))
36775 {
36776 exprtk_debug((
"(c0) + (v - c1) --> (cov) (c0 - c1) + v\n"));
36777
36778 return expr_gen.node_allocator_->
36779 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
36780 }
36781
36782 else if ((details::e_sub == o0) && (details::e_add == o1))
36783 {
36784 exprtk_debug((
"(c0) - (v + c1) --> (cov) (c0 - c1) - v\n"));
36785
36786 return expr_gen.node_allocator_->
36787 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
36788 }
36789
36790 else if ((details::e_sub == o0) && (details::e_sub == o1))
36791 {
36792 exprtk_debug((
"(c0) - (v - c1) --> (cov) (c0 + c1) - v\n"));
36793
36794 return expr_gen.node_allocator_->
36795 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
36796 }
36797
36798 else if ((details::e_mul == o0) && (details::e_mul == o1))
36799 {
36800 exprtk_debug((
"(c0) * (v * c1) --> (voc) v * (c0 * c1)\n"));
36801
36802 return expr_gen.node_allocator_->
36803 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
36804 }
36805
36806 else if ((details::e_mul == o0) && (details::e_div == o1))
36807 {
36808 exprtk_debug((
"(c0) * (v / c1) --> (cov) (c0 / c1) * v\n"));
36809
36810 return expr_gen.node_allocator_->
36811 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
36812 }
36813
36814 else if ((details::e_div == o0) && (details::e_mul == o1))
36815 {
36816 exprtk_debug((
"(c0) / (v * c1) --> (cov) (c0 / c1) / v\n"));
36817
36818 return expr_gen.node_allocator_->
36819 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
36820 }
36821
36822 else if ((details::e_div == o0) && (details::e_div == o1))
36823 {
36824 exprtk_debug((
"(c0) / (v / c1) --> (cov) (c0 * c1) / v\n"));
36825
36826 return expr_gen.node_allocator_->
36827 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
36828 }
36829 }
36830
36831 const bool synthesis_result =
36832 synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
36833 (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
36834
36835 if (synthesis_result)
36836 return result;
36837
36838 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36839 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36840
36841 if (!expr_gen.valid_operator(o0,f0))
36842 return error_node();
36843 else if (!expr_gen.valid_operator(o1,f1))
36844 return error_node();
36845 else
36846 return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
36847 }
36848
36849 static inline std::string id(expression_generator<Type>& expr_gen,
36850 const details::operator_type o0,
36851 const details::operator_type o1)
36852 {
36853 return details::build_string()
36854 << "t" << expr_gen.to_str(o0)
36855 << "(t" << expr_gen.to_str(o1)
36856 << "t)";
36857 }
36858 };
36859
36860 struct synthesize_cocov_expression0
36861 {
36862 typedef typename cocov_t::type0 node_type;
36863 static inline expression_node_ptr
process(expression_generator<Type>&,
36864 const details::operator_type&,
36865 expression_node_ptr (&)[2])
36866 {
36867
36868 return error_node();
36869 }
36870 };
36871
36872 struct synthesize_cocov_expression1
36873 {
36874 typedef typename cocov_t::type1 node_type;
36875 typedef typename cocov_t::sf3_type sf3_type;
36876
36877 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36878 const details::operator_type& operation,
36879 expression_node_ptr (&branch)[2])
36880 {
36881
36882 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
36883 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
36884 const Type c1 = cov->c();
36885 const Type& v = cov->v();
36886 const details::operator_type o0 = operation;
36887 const details::operator_type o1 = cov->operation();
36888
36889 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36890 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36891
36892 expression_node_ptr result = error_node();
36893
36894 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36895 {
36896
36897 if ((details::e_add == o0) && (details::e_add == o1))
36898 {
36899 exprtk_debug((
"(c0) + (c1 + v) --> (cov) (c0 + c1) + v\n"));
36900
36901 return expr_gen.node_allocator_->
36902 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
36903 }
36904
36905 else if ((details::e_add == o0) && (details::e_sub == o1))
36906 {
36907 exprtk_debug((
"(c0) + (c1 - v) --> (cov) (c0 + c1) - v\n"));
36908
36909 return expr_gen.node_allocator_->
36910 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
36911 }
36912
36913 else if ((details::e_sub == o0) && (details::e_add == o1))
36914 {
36915 exprtk_debug((
"(c0) - (c1 + v) --> (cov) (c0 - c1) - v\n"));
36916
36917 return expr_gen.node_allocator_->
36918 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
36919 }
36920
36921 else if ((details::e_sub == o0) && (details::e_sub == o1))
36922 {
36923 exprtk_debug((
"(c0) - (c1 - v) --> (cov) (c0 - c1) + v\n"));
36924
36925 return expr_gen.node_allocator_->
36926 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
36927 }
36928
36929 else if ((details::e_mul == o0) && (details::e_mul == o1))
36930 {
36931 exprtk_debug((
"(c0) * (c1 * v) --> (cov) (c0 * c1) * v\n"));
36932
36933 return expr_gen.node_allocator_->
36934 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
36935 }
36936
36937 else if ((details::e_mul == o0) && (details::e_div == o1))
36938 {
36939 exprtk_debug((
"(c0) * (c1 / v) --> (cov) (c0 * c1) / v\n"));
36940
36941 return expr_gen.node_allocator_->
36942 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
36943 }
36944
36945 else if ((details::e_div == o0) && (details::e_mul == o1))
36946 {
36947 exprtk_debug((
"(c0) / (c1 * v) --> (cov) (c0 / c1) / v\n"));
36948
36949 return expr_gen.node_allocator_->
36950 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
36951 }
36952
36953 else if ((details::e_div == o0) && (details::e_div == o1))
36954 {
36955 exprtk_debug((
"(c0) / (c1 / v) --> (cov) (c0 / c1) * v\n"));
36956
36957 return expr_gen.node_allocator_->
36958 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
36959 }
36960 }
36961
36962 const bool synthesis_result =
36963 synthesize_sf3ext_expression::template compile<ctype, ctype, vtype>
36964 (expr_gen, id(expr_gen, o0, o1), c0, c1, v, result);
36965
36966 if (synthesis_result)
36967 return result;
36968
36969 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36970 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36971
36972 if (!expr_gen.valid_operator(o0,f0))
36973 return error_node();
36974 else if (!expr_gen.valid_operator(o1,f1))
36975 return error_node();
36976 else
36977 return node_type::allocate(*(expr_gen.node_allocator_), c0, c1, v, f0, f1);
36978 }
36979
36980 static inline std::string id(expression_generator<Type>& expr_gen,
36981 const details::operator_type o0,
36982 const details::operator_type o1)
36983 {
36984 return details::build_string()
36985 << "t" << expr_gen.to_str(o0)
36986 << "(t" << expr_gen.to_str(o1)
36987 << "t)";
36988 }
36989 };
36990
36991 struct synthesize_vococ_expression0
36992 {
36993 typedef typename vococ_t::type0 node_type;
36994 typedef typename vococ_t::sf3_type sf3_type;
36995
36996 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36997 const details::operator_type& operation,
36998 expression_node_ptr (&branch)[2])
36999 {
37000
37001 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
37002 const Type& v = voc->v();
37003 const Type& c0 = voc->c();
37004 const Type& c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
37005 const details::operator_type o0 = voc->operation();
37006 const details::operator_type o1 = operation;
37007
37008 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37009 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37010
37011 expression_node_ptr result = error_node();
37012
37013 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37014 {
37015
37016 if ((details::e_add == o0) && (details::e_add == o1))
37017 {
37018 exprtk_debug((
"(v + c0) + c1 --> (voc) v + (c0 + c1)\n"));
37019
37020 return expr_gen.node_allocator_->
37021 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 + c1);
37022 }
37023
37024 else if ((details::e_add == o0) && (details::e_sub == o1))
37025 {
37026 exprtk_debug((
"(v + c0) - c1 --> (voc) v + (c0 - c1)\n"));
37027
37028 return expr_gen.node_allocator_->
37029 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 - c1);
37030 }
37031
37032 else if ((details::e_sub == o0) && (details::e_add == o1))
37033 {
37034 exprtk_debug((
"(v - c0) + c1 --> (voc) v - (c0 + c1)\n"));
37035
37036 return expr_gen.node_allocator_->
37037 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c1 - c0);
37038 }
37039
37040 else if ((details::e_sub == o0) && (details::e_sub == o1))
37041 {
37042 exprtk_debug((
"(v - c0) - c1 --> (voc) v - (c0 + c1)\n"));
37043
37044 return expr_gen.node_allocator_->
37045 template allocate_rc<typename details::voc_node<Type,details::sub_op<Type> > >(v, c0 + c1);
37046 }
37047
37048 else if ((details::e_mul == o0) && (details::e_mul == o1))
37049 {
37050 exprtk_debug((
"(v * c0) * c1 --> (voc) v * (c0 * c1)\n"));
37051
37052 return expr_gen.node_allocator_->
37053 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 * c1);
37054 }
37055
37056 else if ((details::e_mul == o0) && (details::e_div == o1))
37057 {
37058 exprtk_debug((
"(v * c0) / c1 --> (voc) v * (c0 / c1)\n"));
37059
37060 return expr_gen.node_allocator_->
37061 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 / c1);
37062 }
37063
37064 else if ((details::e_div == o0) && (details::e_mul == o1))
37065 {
37066 exprtk_debug((
"(v / c0) * c1 --> (voc) v * (c1 / c0)\n"));
37067
37068 return expr_gen.node_allocator_->
37069 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c1 / c0);
37070 }
37071
37072 else if ((details::e_div == o0) && (details::e_div == o1))
37073 {
37074 exprtk_debug((
"(v / c0) / c1 --> (voc) v / (c0 * c1)\n"));
37075
37076 return expr_gen.node_allocator_->
37077 template allocate_rc<typename details::voc_node<Type,details::div_op<Type> > >(v, c0 * c1);
37078 }
37079
37080 else if ((details::e_pow == o0) && (details::e_pow == o1))
37081 {
37082 exprtk_debug((
"(v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)\n"));
37083
37084 return expr_gen.node_allocator_->
37085 template allocate_rc<typename details::voc_node<Type,details::pow_op<Type> > >(v, c0 * c1);
37086 }
37087 }
37088
37089 const bool synthesis_result =
37090 synthesize_sf3ext_expression::template compile<vtype, ctype, ctype>
37091 (expr_gen, id(expr_gen, o0, o1), v, c0, c1, result);
37092
37093 if (synthesis_result)
37094 return result;
37095
37096 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37097 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37098
37099 if (!expr_gen.valid_operator(o0,f0))
37100 return error_node();
37101 else if (!expr_gen.valid_operator(o1,f1))
37102 return error_node();
37103 else
37104 return node_type::allocate(*(expr_gen.node_allocator_), v, c0, c1, f0, f1);
37105 }
37106
37107 static inline std::string id(expression_generator<Type>& expr_gen,
37108 const details::operator_type o0,
37109 const details::operator_type o1)
37110 {
37111 return details::build_string()
37112 << "(t" << expr_gen.to_str(o0)
37113 << "t)" << expr_gen.to_str(o1)
37114 << "t";
37115 }
37116 };
37117
37118 struct synthesize_vococ_expression1
37119 {
37120 typedef typename vococ_t::type0 node_type;
37121
37122 static inline expression_node_ptr
process(expression_generator<Type>&,
37123 const details::operator_type&,
37124 expression_node_ptr (&)[2])
37125 {
37126
37127 exprtk_debug((
"(v) o0 (c0 o1 c1) - Not possible.\n"));
37128 return error_node();
37129 }
37130 };
37131
37132 struct synthesize_vovovov_expression0
37133 {
37134 typedef typename vovovov_t::type0 node_type;
37135 typedef typename vovovov_t::sf4_type sf4_type;
37136 typedef typename node_type::T0 T0;
37137 typedef typename node_type::T1 T1;
37138 typedef typename node_type::T2 T2;
37139 typedef typename node_type::T3 T3;
37140
37141 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37142 const details::operator_type& operation,
37143 expression_node_ptr (&branch)[2])
37144 {
37145
37146 const details::vov_base_node<Type>* vov0 = static_cast<details::vov_base_node<Type>*>(branch[0]);
37147 const details::vov_base_node<Type>* vov1 = static_cast<details::vov_base_node<Type>*>(branch[1]);
37148 const Type& v0 = vov0->v0();
37149 const Type& v1 = vov0->v1();
37150 const Type& v2 = vov1->v0();
37151 const Type& v3 = vov1->v1();
37152 const details::operator_type o0 = vov0->operation();
37153 const details::operator_type o1 = operation;
37154 const details::operator_type o2 = vov1->operation();
37155
37156 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37157 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37158
37159 expression_node_ptr result = error_node();
37160
37161 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37162 {
37163
37164 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37165 {
37166 const bool synthesis_result =
37167 synthesize_sf4ext_expression::
37168 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, v3, result);
37169
37170 exprtk_debug((
"(v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)\n"));
37171
37172 return (synthesis_result) ? result : error_node();
37173 }
37174
37175 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37176 {
37177 const bool synthesis_result =
37178 synthesize_sf4ext_expression::
37179 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v3, v1, v2, result);
37180
37181 exprtk_debug((
"(v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)\n"));
37182
37183 return (synthesis_result) ? result : error_node();
37184 }
37185
37186 else if ((details::e_add == o0) && (details::e_div == o1) && (details::e_div == o2))
37187 {
37188 const bool synthesis_result =
37189 synthesize_sf4ext_expression::
37190 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t+t)*(t/t)", v0, v1, v3, v2, result);
37191
37192 exprtk_debug((
"(v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)\n"));
37193
37194 return (synthesis_result) ? result : error_node();
37195 }
37196
37197 else if ((details::e_sub == o0) && (details::e_div == o1) && (details::e_div == o2))
37198 {
37199 const bool synthesis_result =
37200 synthesize_sf4ext_expression::
37201 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t-t)*(t/t)", v0, v1, v3, v2, result);
37202
37203 exprtk_debug((
"(v0 - v1) / (v2 / v3) --> (vovovov) (v0 - v1) * (v3 / v2)\n"));
37204
37205 return (synthesis_result) ? result : error_node();
37206 }
37207
37208 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
37209 {
37210 const bool synthesis_result =
37211 synthesize_sf4ext_expression::
37212 template compile<vtype, vtype, vtype, vtype>(expr_gen, "((t*t)*t)/t", v0, v1, v3, v2, result);
37213
37214 exprtk_debug((
"(v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2\n"));
37215
37216 return (synthesis_result) ? result : error_node();
37217 }
37218 }
37219
37220 const bool synthesis_result =
37221 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37222 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
37223
37224 if (synthesis_result)
37225 return result;
37226
37227 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37228 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37229 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37230
37231 if (!expr_gen.valid_operator(o0,f0))
37232 return error_node();
37233 else if (!expr_gen.valid_operator(o1,f1))
37234 return error_node();
37235 else if (!expr_gen.valid_operator(o2,f2))
37236 return error_node();
37237 else
37238 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
37239 }
37240
37241 static inline std::string id(expression_generator<Type>& expr_gen,
37242 const details::operator_type o0,
37243 const details::operator_type o1,
37244 const details::operator_type o2)
37245 {
37246 return details::build_string()
37247 << "(t" << expr_gen.to_str(o0)
37248 << "t)" << expr_gen.to_str(o1)
37249 << "(t" << expr_gen.to_str(o2)
37250 << "t)";
37251 }
37252 };
37253
37254 struct synthesize_vovovoc_expression0
37255 {
37256 typedef typename vovovoc_t::type0 node_type;
37257 typedef typename vovovoc_t::sf4_type sf4_type;
37258 typedef typename node_type::T0 T0;
37259 typedef typename node_type::T1 T1;
37260 typedef typename node_type::T2 T2;
37261 typedef typename node_type::T3 T3;
37262
37263 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37264 const details::operator_type& operation,
37265 expression_node_ptr (&branch)[2])
37266 {
37267
37268 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
37269 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
37270 const Type& v0 = vov->v0();
37271 const Type& v1 = vov->v1();
37272 const Type& v2 = voc->v ();
37273 const Type c = voc->c ();
37274 const details::operator_type o0 = vov->operation();
37275 const details::operator_type o1 = operation;
37276 const details::operator_type o2 = voc->operation();
37277
37278 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37279 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37280
37281 expression_node_ptr result = error_node();
37282
37283 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37284 {
37285
37286 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37287 {
37288 const bool synthesis_result =
37289 synthesize_sf4ext_expression::
37290 template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
37291
37292 exprtk_debug((
"(v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
37293
37294 return (synthesis_result) ? result : error_node();
37295 }
37296
37297 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37298 {
37299 const bool synthesis_result =
37300 synthesize_sf4ext_expression::
37301 template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
37302
37303 exprtk_debug((
"(v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
37304
37305 return (synthesis_result) ? result : error_node();
37306 }
37307 }
37308
37309 const bool synthesis_result =
37310 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37311 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
37312
37313 if (synthesis_result)
37314 return result;
37315
37316 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37317 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37318 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37319
37320 if (!expr_gen.valid_operator(o0,f0))
37321 return error_node();
37322 else if (!expr_gen.valid_operator(o1,f1))
37323 return error_node();
37324 else if (!expr_gen.valid_operator(o2,f2))
37325 return error_node();
37326 else
37327 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
37328 }
37329
37330 static inline std::string id(expression_generator<Type>& expr_gen,
37331 const details::operator_type o0,
37332 const details::operator_type o1,
37333 const details::operator_type o2)
37334 {
37335 return details::build_string()
37336 << "(t" << expr_gen.to_str(o0)
37337 << "t)" << expr_gen.to_str(o1)
37338 << "(t" << expr_gen.to_str(o2)
37339 << "t)";
37340 }
37341 };
37342
37343 struct synthesize_vovocov_expression0
37344 {
37345 typedef typename vovocov_t::type0 node_type;
37346 typedef typename vovocov_t::sf4_type sf4_type;
37347 typedef typename node_type::T0 T0;
37348 typedef typename node_type::T1 T1;
37349 typedef typename node_type::T2 T2;
37350 typedef typename node_type::T3 T3;
37351
37352 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37353 const details::operator_type& operation,
37354 expression_node_ptr (&branch)[2])
37355 {
37356
37357 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
37358 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
37359 const Type& v0 = vov->v0();
37360 const Type& v1 = vov->v1();
37361 const Type& v2 = cov->v ();
37362 const Type c = cov->c ();
37363 const details::operator_type o0 = vov->operation();
37364 const details::operator_type o1 = operation;
37365 const details::operator_type o2 = cov->operation();
37366
37367 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37368 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37369
37370 expression_node_ptr result = error_node();
37371
37372 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37373 {
37374
37375 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37376 {
37377 const bool synthesis_result =
37378 synthesize_sf4ext_expression::
37379 template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
37380
37381 exprtk_debug((
"(v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
37382
37383 return (synthesis_result) ? result : error_node();
37384 }
37385
37386 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37387 {
37388 const bool synthesis_result =
37389 synthesize_sf4ext_expression::
37390 template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
37391
37392 exprtk_debug((
"(v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
37393
37394 return (synthesis_result) ? result : error_node();
37395 }
37396 }
37397
37398 const bool synthesis_result =
37399 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37400 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
37401
37402 if (synthesis_result)
37403 return result;
37404
37405 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37406 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37407 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37408
37409 if (!expr_gen.valid_operator(o0,f0))
37410 return error_node();
37411 else if (!expr_gen.valid_operator(o1,f1))
37412 return error_node();
37413 else if (!expr_gen.valid_operator(o2,f2))
37414 return error_node();
37415 else
37416 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
37417 }
37418
37419 static inline std::string id(expression_generator<Type>& expr_gen,
37420 const details::operator_type o0,
37421 const details::operator_type o1,
37422 const details::operator_type o2)
37423 {
37424 return details::build_string()
37425 << "(t" << expr_gen.to_str(o0)
37426 << "t)" << expr_gen.to_str(o1)
37427 << "(t" << expr_gen.to_str(o2)
37428 << "t)";
37429 }
37430 };
37431
37432 struct synthesize_vocovov_expression0
37433 {
37434 typedef typename vocovov_t::type0 node_type;
37435 typedef typename vocovov_t::sf4_type sf4_type;
37436 typedef typename node_type::T0 T0;
37437 typedef typename node_type::T1 T1;
37438 typedef typename node_type::T2 T2;
37439 typedef typename node_type::T3 T3;
37440
37441 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37442 const details::operator_type& operation,
37443 expression_node_ptr (&branch)[2])
37444 {
37445
37446 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
37447 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
37448 const Type c = voc->c ();
37449 const Type& v0 = voc->v ();
37450 const Type& v1 = vov->v0();
37451 const Type& v2 = vov->v1();
37452 const details::operator_type o0 = voc->operation();
37453 const details::operator_type o1 = operation;
37454 const details::operator_type o2 = vov->operation();
37455
37456 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37457 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37458
37459 expression_node_ptr result = error_node();
37460
37461 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37462 {
37463
37464 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37465 {
37466 const bool synthesis_result =
37467 synthesize_sf4ext_expression::
37468 template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v1, c, v2, result);
37469
37470 exprtk_debug((
"(v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)\n"));
37471
37472 return (synthesis_result) ? result : error_node();
37473 }
37474
37475 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37476 {
37477 const bool synthesis_result =
37478 synthesize_sf4ext_expression::
37479 template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, c, v1, result);
37480
37481 exprtk_debug((
"(v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)\n"));
37482
37483 return (synthesis_result) ? result : error_node();
37484 }
37485 }
37486
37487 const bool synthesis_result =
37488 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37489 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
37490
37491 if (synthesis_result)
37492 return result;
37493
37494 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37495 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37496 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37497
37498 if (!expr_gen.valid_operator(o0,f0))
37499 return error_node();
37500 else if (!expr_gen.valid_operator(o1,f1))
37501 return error_node();
37502 else if (!expr_gen.valid_operator(o2,f2))
37503 return error_node();
37504 else
37505 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
37506 }
37507
37508 static inline std::string id(expression_generator<Type>& expr_gen,
37509 const details::operator_type o0,
37510 const details::operator_type o1,
37511 const details::operator_type o2)
37512 {
37513 return details::build_string()
37514 << "(t" << expr_gen.to_str(o0)
37515 << "t)" << expr_gen.to_str(o1)
37516 << "(t" << expr_gen.to_str(o2)
37517 << "t)";
37518 }
37519 };
37520
37521 struct synthesize_covovov_expression0
37522 {
37523 typedef typename covovov_t::type0 node_type;
37524 typedef typename covovov_t::sf4_type sf4_type;
37525 typedef typename node_type::T0 T0;
37526 typedef typename node_type::T1 T1;
37527 typedef typename node_type::T2 T2;
37528 typedef typename node_type::T3 T3;
37529
37530 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37531 const details::operator_type& operation,
37532 expression_node_ptr (&branch)[2])
37533 {
37534
37535 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
37536 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
37537 const Type c = cov->c ();
37538 const Type& v0 = cov->v ();
37539 const Type& v1 = vov->v0();
37540 const Type& v2 = vov->v1();
37541 const details::operator_type o0 = cov->operation();
37542 const details::operator_type o1 = operation;
37543 const details::operator_type o2 = vov->operation();
37544
37545 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37546 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37547
37548 expression_node_ptr result = error_node();
37549
37550 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37551 {
37552
37553 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37554 {
37555 const bool synthesis_result =
37556 synthesize_sf4ext_expression::
37557 template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v1, v0, v2, result);
37558
37559 exprtk_debug((
"(c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)\n"));
37560
37561 return (synthesis_result) ? result : error_node();
37562 }
37563
37564 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37565 {
37566 const bool synthesis_result =
37567 synthesize_sf4ext_expression::
37568 template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v2, v0, v1, result);
37569
37570 exprtk_debug((
"(c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)\n"));
37571
37572 return (synthesis_result) ? result : error_node();
37573 }
37574 }
37575
37576 const bool synthesis_result =
37577 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37578 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
37579
37580 if (synthesis_result)
37581 return result;
37582
37583 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37584 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37585 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37586
37587 if (!expr_gen.valid_operator(o0,f0))
37588 return error_node();
37589 else if (!expr_gen.valid_operator(o1,f1))
37590 return error_node();
37591 else if (!expr_gen.valid_operator(o2,f2))
37592 return error_node();
37593 else
37594 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
37595 }
37596
37597 static inline std::string id(expression_generator<Type>& expr_gen,
37598 const details::operator_type o0,
37599 const details::operator_type o1,
37600 const details::operator_type o2)
37601 {
37602 return details::build_string()
37603 << "(t" << expr_gen.to_str(o0)
37604 << "t)" << expr_gen.to_str(o1)
37605 << "(t" << expr_gen.to_str(o2)
37606 << "t)";
37607 }
37608 };
37609
37610 struct synthesize_covocov_expression0
37611 {
37612 typedef typename covocov_t::type0 node_type;
37613 typedef typename covocov_t::sf4_type sf4_type;
37614 typedef typename node_type::T0 T0;
37615 typedef typename node_type::T1 T1;
37616 typedef typename node_type::T2 T2;
37617 typedef typename node_type::T3 T3;
37618
37619 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37620 const details::operator_type& operation,
37621 expression_node_ptr (&branch)[2])
37622 {
37623
37624 const details::cov_base_node<Type>* cov0 = static_cast<details::cov_base_node<Type>*>(branch[0]);
37625 const details::cov_base_node<Type>* cov1 = static_cast<details::cov_base_node<Type>*>(branch[1]);
37626 const Type c0 = cov0->c();
37627 const Type& v0 = cov0->v();
37628 const Type c1 = cov1->c();
37629 const Type& v1 = cov1->v();
37630 const details::operator_type o0 = cov0->operation();
37631 const details::operator_type o1 = operation;
37632 const details::operator_type o2 = cov1->operation();
37633
37634 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37635 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37636
37637 expression_node_ptr result = error_node();
37638
37639 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37640 {
37641
37642 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
37643 {
37644 const bool synthesis_result =
37645 synthesize_sf3ext_expression::
37646 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
37647
37648 exprtk_debug((
"(c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
37649
37650 return (synthesis_result) ? result : error_node();
37651 }
37652
37653 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
37654 {
37655 const bool synthesis_result =
37656 synthesize_sf3ext_expression::
37657 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
37658
37659 exprtk_debug((
"(c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
37660
37661 return (synthesis_result) ? result : error_node();
37662 }
37663
37664 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
37665 {
37666 const bool synthesis_result =
37667 synthesize_sf3ext_expression::
37668 template compile<ctype, vtype, vtype>(expr_gen, "(t-t)+t", (c0 - c1), v0, v1, result);
37669
37670 exprtk_debug((
"(c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1\n"));
37671
37672 return (synthesis_result) ? result : error_node();
37673 }
37674
37675 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
37676 {
37677 const bool synthesis_result =
37678 synthesize_sf3ext_expression::
37679 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
37680
37681 exprtk_debug((
"(c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
37682
37683 return (synthesis_result) ? result : error_node();
37684 }
37685
37686 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
37687 {
37688 const bool synthesis_result =
37689 synthesize_sf3ext_expression::
37690 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
37691
37692 exprtk_debug((
"(c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
37693
37694 return (synthesis_result) ? result : error_node();
37695 }
37696
37697 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37698 {
37699 const bool synthesis_result =
37700 synthesize_sf3ext_expression::
37701 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
37702
37703 exprtk_debug((
"(c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
37704
37705 return (synthesis_result) ? result : error_node();
37706 }
37707
37708 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37709 {
37710 const bool synthesis_result =
37711 synthesize_sf3ext_expression::
37712 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v1, v0, result);
37713
37714 exprtk_debug((
"(c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0\n"));
37715
37716 return (synthesis_result) ? result : error_node();
37717 }
37718
37719 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
37720 {
37721 const bool synthesis_result =
37722 synthesize_sf3ext_expression::
37723 template compile<ctype, vtype, vtype>(expr_gen, "t*(t*t)", (c0 / c1), v0, v1, result);
37724
37725 exprtk_debug((
"(c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
37726
37727 return (synthesis_result) ? result : error_node();
37728 }
37729
37730 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
37731 {
37732 const bool synthesis_result =
37733 synthesize_sf3ext_expression::
37734 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
37735
37736 exprtk_debug((
"(c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
37737
37738 return (synthesis_result) ? result : error_node();
37739 }
37740
37741 else if (
37742 (std::equal_to<T>()(c0,c1)) &&
37743 (details::e_mul == o0) &&
37744 (details::e_mul == o2) &&
37745 (
37746 (details::e_add == o1) ||
37747 (details::e_sub == o1)
37748 )
37749 )
37750 {
37751 std::string specfunc;
37752
37753 switch (o1)
37754 {
37755 case details::e_add : specfunc = "t*(t+t)"; break;
37756 case details::e_sub : specfunc = "t*(t-t)"; break;
37757 default : return error_node();
37758 }
37759
37760 const bool synthesis_result =
37761 synthesize_sf3ext_expression::
37762 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
37763
37764 exprtk_debug((
"(c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
37765
37766 return (synthesis_result) ? result : error_node();
37767 }
37768 }
37769
37770 const bool synthesis_result =
37771 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37772 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
37773
37774 if (synthesis_result)
37775 return result;
37776
37777 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37778 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37779 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37780
37781 if (!expr_gen.valid_operator(o0,f0))
37782 return error_node();
37783 else if (!expr_gen.valid_operator(o1,f1))
37784 return error_node();
37785 else if (!expr_gen.valid_operator(o2,f2))
37786 return error_node();
37787 else
37788 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
37789 }
37790
37791 static inline std::string id(expression_generator<Type>& expr_gen,
37792 const details::operator_type o0,
37793 const details::operator_type o1,
37794 const details::operator_type o2)
37795 {
37796 return details::build_string()
37797 << "(t" << expr_gen.to_str(o0)
37798 << "t)" << expr_gen.to_str(o1)
37799 << "(t" << expr_gen.to_str(o2)
37800 << "t)";
37801 }
37802 };
37803
37804 struct synthesize_vocovoc_expression0
37805 {
37806 typedef typename vocovoc_t::type0 node_type;
37807 typedef typename vocovoc_t::sf4_type sf4_type;
37808 typedef typename node_type::T0 T0;
37809 typedef typename node_type::T1 T1;
37810 typedef typename node_type::T2 T2;
37811 typedef typename node_type::T3 T3;
37812
37813 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37814 const details::operator_type& operation,
37815 expression_node_ptr (&branch)[2])
37816 {
37817
37818 const details::voc_base_node<Type>* voc0 = static_cast<details::voc_base_node<Type>*>(branch[0]);
37819 const details::voc_base_node<Type>* voc1 = static_cast<details::voc_base_node<Type>*>(branch[1]);
37820 const Type c0 = voc0->c();
37821 const Type& v0 = voc0->v();
37822 const Type c1 = voc1->c();
37823 const Type& v1 = voc1->v();
37824 const details::operator_type o0 = voc0->operation();
37825 const details::operator_type o1 = operation;
37826 const details::operator_type o2 = voc1->operation();
37827
37828 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37829 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37830
37831 expression_node_ptr result = error_node();
37832
37833 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37834 {
37835
37836 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
37837 {
37838 const bool synthesis_result =
37839 synthesize_sf3ext_expression::
37840 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
37841
37842 exprtk_debug((
"(v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
37843
37844 return (synthesis_result) ? result : error_node();
37845 }
37846
37847 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
37848 {
37849 const bool synthesis_result =
37850 synthesize_sf3ext_expression::
37851 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
37852
37853 exprtk_debug((
"(v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
37854
37855 return (synthesis_result) ? result : error_node();
37856 }
37857
37858 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
37859 {
37860 const bool synthesis_result =
37861 synthesize_sf3ext_expression::
37862 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c1 - c0), v0, v1, result);
37863
37864 exprtk_debug((
"(v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1\n"));
37865
37866 return (synthesis_result) ? result : error_node();
37867 }
37868
37869 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
37870 {
37871 const bool synthesis_result =
37872 synthesize_sf3ext_expression::
37873 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
37874
37875 exprtk_debug((
"(v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
37876
37877 return (synthesis_result) ? result : error_node();
37878 }
37879
37880 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
37881 {
37882 const bool synthesis_result =
37883 synthesize_sf3ext_expression::
37884 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
37885
37886 exprtk_debug((
"(v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
37887
37888 return (synthesis_result) ? result : error_node();
37889 }
37890
37891 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37892 {
37893 const bool synthesis_result =
37894 synthesize_sf3ext_expression::
37895 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", Type(1) / (c0 * c1), v0, v1, result);
37896
37897 exprtk_debug((
"(v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1\n"));
37898
37899 return (synthesis_result) ? result : error_node();
37900 }
37901
37902 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37903 {
37904 const bool synthesis_result =
37905 synthesize_sf3ext_expression::
37906 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
37907
37908 exprtk_debug((
"(v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1\n"));
37909
37910 return (synthesis_result) ? result : error_node();
37911 }
37912
37913 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
37914 {
37915 const bool synthesis_result =
37916 synthesize_sf3ext_expression::
37917 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 * c1), v0, v1, result);
37918
37919 exprtk_debug((
"(v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
37920
37921 return (synthesis_result) ? result : error_node();
37922 }
37923
37924 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
37925 {
37926 const bool synthesis_result =
37927 synthesize_sf3ext_expression::
37928 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", Type(1) / (c0 * c1), v0, v1, result);
37929
37930 exprtk_debug((
"(v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1\n"));
37931
37932 return (synthesis_result) ? result : error_node();
37933 }
37934
37935 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_add == o2))
37936 {
37937 const bool synthesis_result =
37938 synthesize_sf4ext_expression::
37939 template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t+t)", v0, T(1) / c0, v1, c1, result);
37940
37941 exprtk_debug((
"(v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)\n"));
37942
37943 return (synthesis_result) ? result : error_node();
37944 }
37945
37946 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_sub == o2))
37947 {
37948 const bool synthesis_result =
37949 synthesize_sf4ext_expression::
37950 template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t-t)", v0, T(1) / c0, v1, c1, result);
37951
37952 exprtk_debug((
"(v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)\n"));
37953
37954 return (synthesis_result) ? result : error_node();
37955 }
37956
37957 else if (
37958 (std::equal_to<T>()(c0,c1)) &&
37959 (details::e_mul == o0) &&
37960 (details::e_mul == o2) &&
37961 (
37962 (details::e_add == o1) ||
37963 (details::e_sub == o1)
37964 )
37965 )
37966 {
37967 std::string specfunc;
37968
37969 switch (o1)
37970 {
37971 case details::e_add : specfunc = "t*(t+t)"; break;
37972 case details::e_sub : specfunc = "t*(t-t)"; break;
37973 default : return error_node();
37974 }
37975
37976 const bool synthesis_result =
37977 synthesize_sf3ext_expression::
37978 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
37979
37980 exprtk_debug((
"(v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
37981
37982 return (synthesis_result) ? result : error_node();
37983 }
37984
37985 else if (
37986 (std::equal_to<T>()(c0,c1)) &&
37987 (details::e_div == o0) &&
37988 (details::e_div == o2) &&
37989 (
37990 (details::e_add == o1) ||
37991 (details::e_sub == o1)
37992 )
37993 )
37994 {
37995 std::string specfunc;
37996
37997 switch (o1)
37998 {
37999 case details::e_add : specfunc = "(t+t)/t"; break;
38000 case details::e_sub : specfunc = "(t-t)/t"; break;
38001 default : return error_node();
38002 }
38003
38004 const bool synthesis_result =
38005 synthesize_sf3ext_expression::
38006 template compile<vtype, vtype, ctype>(expr_gen, specfunc, v0, v1, c0, result);
38007
38008 exprtk_debug((
"(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n"));
38009
38010 return (synthesis_result) ? result : error_node();
38011 }
38012 }
38013
38014 const bool synthesis_result =
38015 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38016 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
38017
38018 if (synthesis_result)
38019 return result;
38020
38021 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38022 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
38023 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38024
38025 if (!expr_gen.valid_operator(o0,f0))
38026 return error_node();
38027 else if (!expr_gen.valid_operator(o1,f1))
38028 return error_node();
38029 else if (!expr_gen.valid_operator(o2,f2))
38030 return error_node();
38031 else
38032 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
38033 }
38034
38035 static inline std::string id(expression_generator<Type>& expr_gen,
38036 const details::operator_type o0,
38037 const details::operator_type o1,
38038 const details::operator_type o2)
38039 {
38040 return details::build_string()
38041 << "(t" << expr_gen.to_str(o0)
38042 << "t)" << expr_gen.to_str(o1)
38043 << "(t" << expr_gen.to_str(o2)
38044 << "t)";
38045 }
38046 };
38047
38048 struct synthesize_covovoc_expression0
38049 {
38050 typedef typename covovoc_t::type0 node_type;
38051 typedef typename covovoc_t::sf4_type sf4_type;
38052 typedef typename node_type::T0 T0;
38053 typedef typename node_type::T1 T1;
38054 typedef typename node_type::T2 T2;
38055 typedef typename node_type::T3 T3;
38056
38057 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38058 const details::operator_type& operation,
38059 expression_node_ptr (&branch)[2])
38060 {
38061
38062 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
38063 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
38064 const Type c0 = cov->c();
38065 const Type& v0 = cov->v();
38066 const Type c1 = voc->c();
38067 const Type& v1 = voc->v();
38068 const details::operator_type o0 = cov->operation();
38069 const details::operator_type o1 = operation;
38070 const details::operator_type o2 = voc->operation();
38071
38072 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38073 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38074
38075 expression_node_ptr result = error_node();
38076
38077 if (expr_gen.parser_->settings_.strength_reduction_enabled())
38078 {
38079
38080 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
38081 {
38082 const bool synthesis_result =
38083 synthesize_sf3ext_expression::
38084 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
38085
38086 exprtk_debug((
"(c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
38087
38088 return (synthesis_result) ? result : error_node();
38089 }
38090
38091 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
38092 {
38093 const bool synthesis_result =
38094 synthesize_sf3ext_expression::
38095 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
38096
38097 exprtk_debug((
"(c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
38098
38099 return (synthesis_result) ? result : error_node();
38100 }
38101
38102 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
38103 {
38104 const bool synthesis_result =
38105 synthesize_sf3ext_expression::
38106 template compile<ctype, vtype, vtype>(expr_gen, "t-(t+t)", (c0 + c1), v0, v1, result);
38107
38108 exprtk_debug((
"(c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1\n"));
38109
38110 return (synthesis_result) ? result : error_node();
38111 }
38112
38113 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
38114 {
38115 const bool synthesis_result =
38116 synthesize_sf3ext_expression::
38117 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
38118
38119 exprtk_debug((
"(c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
38120
38121 return (synthesis_result) ? result : error_node();
38122 }
38123
38124 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
38125 {
38126 const bool synthesis_result =
38127 synthesize_sf3ext_expression::
38128 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
38129
38130 exprtk_debug((
"(c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
38131
38132 return (synthesis_result) ? result : error_node();
38133 }
38134
38135 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
38136 {
38137 const bool synthesis_result =
38138 synthesize_sf3ext_expression::
38139 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 / c1), v1, v0, result);
38140
38141 exprtk_debug((
"(c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)\n"));
38142
38143 return (synthesis_result) ? result : error_node();
38144 }
38145
38146 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
38147 {
38148 const bool synthesis_result =
38149 synthesize_sf3ext_expression::
38150 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
38151
38152 exprtk_debug((
"(c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
38153
38154 return (synthesis_result) ? result : error_node();
38155 }
38156
38157 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
38158 {
38159 const bool synthesis_result =
38160 synthesize_sf3ext_expression::
38161 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 * c1), v0, v1, result);
38162
38163 exprtk_debug((
"(c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
38164
38165 return (synthesis_result) ? result : error_node();
38166 }
38167
38168 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
38169 {
38170 const bool synthesis_result =
38171 synthesize_sf3ext_expression::
38172 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
38173
38174 exprtk_debug((
"(c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
38175
38176 return (synthesis_result) ? result : error_node();
38177 }
38178
38179 else if (
38180 (std::equal_to<T>()(c0,c1)) &&
38181 (details::e_mul == o0) &&
38182 (details::e_mul == o2) &&
38183 (
38184 (details::e_add == o1) ||
38185 (details::e_sub == o1)
38186 )
38187 )
38188 {
38189 std::string specfunc;
38190
38191 switch (o1)
38192 {
38193 case details::e_add : specfunc = "t*(t+t)"; break;
38194 case details::e_sub : specfunc = "t*(t-t)"; break;
38195 default : return error_node();
38196 }
38197
38198 const bool synthesis_result =
38199 synthesize_sf3ext_expression::
38200 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
38201
38202 exprtk_debug((
"(c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
38203
38204 return (synthesis_result) ? result : error_node();
38205 }
38206 }
38207
38208 const bool synthesis_result =
38209 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38210 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
38211
38212 if (synthesis_result)
38213 return result;
38214
38215 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38216 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
38217 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38218
38219 if (!expr_gen.valid_operator(o0,f0))
38220 return error_node();
38221 else if (!expr_gen.valid_operator(o1,f1))
38222 return error_node();
38223 else if (!expr_gen.valid_operator(o2,f2))
38224 return error_node();
38225 else
38226 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
38227 }
38228
38229 static inline std::string id(expression_generator<Type>& expr_gen,
38230 const details::operator_type o0,
38231 const details::operator_type o1,
38232 const details::operator_type o2)
38233 {
38234 return details::build_string()
38235 << "(t" << expr_gen.to_str(o0)
38236 << "t)" << expr_gen.to_str(o1)
38237 << "(t" << expr_gen.to_str(o2)
38238 << "t)";
38239 }
38240 };
38241
38242 struct synthesize_vococov_expression0
38243 {
38244 typedef typename vococov_t::type0 node_type;
38245 typedef typename vococov_t::sf4_type sf4_type;
38246 typedef typename node_type::T0 T0;
38247 typedef typename node_type::T1 T1;
38248 typedef typename node_type::T2 T2;
38249 typedef typename node_type::T3 T3;
38250
38251 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38252 const details::operator_type& operation,
38253 expression_node_ptr (&branch)[2])
38254 {
38255
38256 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
38257 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
38258 const Type c0 = voc->c();
38259 const Type& v0 = voc->v();
38260 const Type c1 = cov->c();
38261 const Type& v1 = cov->v();
38262 const details::operator_type o0 = voc->operation();
38263 const details::operator_type o1 = operation;
38264 const details::operator_type o2 = cov->operation();
38265
38266 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38267 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38268
38269 expression_node_ptr result = error_node();
38270
38271 if (expr_gen.parser_->settings_.strength_reduction_enabled())
38272 {
38273
38274 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
38275 {
38276 const bool synthesis_result =
38277 synthesize_sf3ext_expression::
38278 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
38279
38280 exprtk_debug((
"(v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
38281
38282 return (synthesis_result) ? result : error_node();
38283 }
38284
38285 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
38286 {
38287 const bool synthesis_result =
38288 synthesize_sf3ext_expression::
38289 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
38290
38291 exprtk_debug((
"(v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
38292
38293 return (synthesis_result) ? result : error_node();
38294 }
38295
38296 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
38297 {
38298 const bool synthesis_result =
38299 synthesize_sf3ext_expression::
38300 template compile<vtype, vtype, ctype>(expr_gen, "(t+t)-t", v0, v1, (c1 + c0), result);
38301
38302 exprtk_debug((
"(v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)\n"));
38303
38304 return (synthesis_result) ? result : error_node();
38305 }
38306
38307 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
38308 {
38309 const bool synthesis_result =
38310 synthesize_sf3ext_expression::
38311 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
38312
38313 exprtk_debug((
"(v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
38314
38315 return (synthesis_result) ? result : error_node();
38316 }
38317
38318 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
38319 {
38320 const bool synthesis_result =
38321 synthesize_sf3ext_expression::
38322 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
38323
38324 exprtk_debug((
"(v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
38325
38326 return (synthesis_result) ? result : error_node();
38327 }
38328
38329 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
38330 {
38331 const bool synthesis_result =
38332 synthesize_sf3ext_expression::
38333 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
38334
38335 exprtk_debug((
"(v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)\n"));
38336
38337 return (synthesis_result) ? result : error_node();
38338 }
38339
38340 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
38341 {
38342 const bool synthesis_result =
38343 synthesize_sf3ext_expression::
38344 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 / c1), v0, v1, result);
38345
38346 exprtk_debug((
"(v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
38347
38348 return (synthesis_result) ? result : error_node();
38349 }
38350
38351 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
38352 {
38353 const bool synthesis_result =
38354 synthesize_sf3ext_expression::
38355 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", Type(1) / (c0 * c1), v0, v1, result);
38356
38357 exprtk_debug((
"(v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)\n"));
38358
38359 return (synthesis_result) ? result : error_node();
38360 }
38361
38362 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
38363 {
38364 const bool synthesis_result =
38365 synthesize_sf3ext_expression::
38366 template compile<vtype, vtype, ctype>(expr_gen, "(t*t)*t", v0, v1, Type(1) / (c0 * c1), result);
38367
38368 exprtk_debug((
"(v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))\n"));
38369
38370 return (synthesis_result) ? result : error_node();
38371 }
38372
38373 else if (
38374 (std::equal_to<T>()(c0,c1)) &&
38375 (details::e_mul == o0) &&
38376 (details::e_mul == o2) &&
38377 (
38378 (details::e_add == o1) || (details::e_sub == o1)
38379 )
38380 )
38381 {
38382 std::string specfunc;
38383
38384 switch (o1)
38385 {
38386 case details::e_add : specfunc = "t*(t+t)"; break;
38387 case details::e_sub : specfunc = "t*(t-t)"; break;
38388 default : return error_node();
38389 }
38390
38391 const bool synthesis_result =
38392 synthesize_sf3ext_expression::
38393 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
38394
38395 exprtk_debug((
"(v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
38396
38397 return (synthesis_result) ? result : error_node();
38398 }
38399 }
38400
38401 const bool synthesis_result =
38402 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38403 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
38404
38405 if (synthesis_result)
38406 return result;
38407
38408 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38409 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
38410 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38411
38412 if (!expr_gen.valid_operator(o0,f0))
38413 return error_node();
38414 else if (!expr_gen.valid_operator(o1,f1))
38415 return error_node();
38416 else if (!expr_gen.valid_operator(o2,f2))
38417 return error_node();
38418 else
38419 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
38420 }
38421
38422 static inline std::string id(expression_generator<Type>& expr_gen,
38423 const details::operator_type o0,
38424 const details::operator_type o1,
38425 const details::operator_type o2)
38426 {
38427 return details::build_string()
38428 << "(t" << expr_gen.to_str(o0)
38429 << "t)" << expr_gen.to_str(o1)
38430 << "(t" << expr_gen.to_str(o2)
38431 << "t)";
38432 }
38433 };
38434
38435 struct synthesize_vovovov_expression1
38436 {
38437 typedef typename vovovov_t::type1 node_type;
38438 typedef typename vovovov_t::sf4_type sf4_type;
38439 typedef typename node_type::T0 T0;
38440 typedef typename node_type::T1 T1;
38441 typedef typename node_type::T2 T2;
38442 typedef typename node_type::T3 T3;
38443
38444 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38445 const details::operator_type& operation,
38446 expression_node_ptr (&branch)[2])
38447 {
38448
38449 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
38450
38451 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
38452 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38453 const Type& v1 = vovov->t0();
38454 const Type& v2 = vovov->t1();
38455 const Type& v3 = vovov->t2();
38456 const details::operator_type o0 = operation;
38457 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
38458 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
38459
38460 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38461 binary_functor_t f1 = vovov->f0();
38462 binary_functor_t f2 = vovov->f1();
38463
38464 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38465
38466 expression_node_ptr result = error_node();
38467
38468 const bool synthesis_result =
38469 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38470 (expr_gen,id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
38471
38472 if (synthesis_result)
38473 return result;
38474 else if (!expr_gen.valid_operator(o0,f0))
38475 return error_node();
38476
38478
38479 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
38480 }
38481
38482 static inline std::string id(expression_generator<Type>& expr_gen,
38483 const details::operator_type o0,
38484 const details::operator_type o1,
38485 const details::operator_type o2)
38486 {
38487 return details::build_string()
38488 << "t" << expr_gen.to_str(o0)
38489 << "(t" << expr_gen.to_str(o1)
38490 << "(t" << expr_gen.to_str(o2)
38491 << "t))";
38492 }
38493 };
38494
38495 struct synthesize_vovovoc_expression1
38496 {
38497 typedef typename vovovoc_t::type1 node_type;
38498 typedef typename vovovoc_t::sf4_type sf4_type;
38499 typedef typename node_type::T0 T0;
38500 typedef typename node_type::T1 T1;
38501 typedef typename node_type::T2 T2;
38502 typedef typename node_type::T3 T3;
38503
38504 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38505 const details::operator_type& operation,
38506 expression_node_ptr (&branch)[2])
38507 {
38508
38509 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
38510
38511 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
38512 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38513 const Type& v1 = vovoc->t0();
38514 const Type& v2 = vovoc->t1();
38515 const Type c = vovoc->t2();
38516 const details::operator_type o0 = operation;
38517 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
38518 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
38519
38520 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38521 binary_functor_t f1 = vovoc->f0();
38522 binary_functor_t f2 = vovoc->f1();
38523
38524 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38525
38526 expression_node_ptr result = error_node();
38527
38528 const bool synthesis_result =
38529 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38530 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
38531
38532 if (synthesis_result)
38533 return result;
38534 else if (!expr_gen.valid_operator(o0,f0))
38535 return error_node();
38536
38538
38539 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
38540 }
38541
38542 static inline std::string id(expression_generator<Type>& expr_gen,
38543 const details::operator_type o0,
38544 const details::operator_type o1,
38545 const details::operator_type o2)
38546 {
38547 return details::build_string()
38548 << "t" << expr_gen.to_str(o0)
38549 << "(t" << expr_gen.to_str(o1)
38550 << "(t" << expr_gen.to_str(o2)
38551 << "t))";
38552 }
38553 };
38554
38555 struct synthesize_vovocov_expression1
38556 {
38557 typedef typename vovocov_t::type1 node_type;
38558 typedef typename vovocov_t::sf4_type sf4_type;
38559 typedef typename node_type::T0 T0;
38560 typedef typename node_type::T1 T1;
38561 typedef typename node_type::T2 T2;
38562 typedef typename node_type::T3 T3;
38563
38564 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38565 const details::operator_type& operation,
38566 expression_node_ptr (&branch)[2])
38567 {
38568
38569 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
38570
38571 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
38572 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38573 const Type& v1 = vocov->t0();
38574 const Type c = vocov->t1();
38575 const Type& v2 = vocov->t2();
38576 const details::operator_type o0 = operation;
38577 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
38578 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
38579
38580 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38581 binary_functor_t f1 = vocov->f0();
38582 binary_functor_t f2 = vocov->f1();
38583
38584 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38585
38586 expression_node_ptr result = error_node();
38587
38588 const bool synthesis_result =
38589 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38590 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
38591
38592 if (synthesis_result)
38593 return result;
38594 if (!expr_gen.valid_operator(o0,f0))
38595 return error_node();
38596
38598
38599 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
38600 }
38601
38602 static inline std::string id(expression_generator<Type>& expr_gen,
38603 const details::operator_type o0,
38604 const details::operator_type o1,
38605 const details::operator_type o2)
38606 {
38607 return details::build_string()
38608 << "t" << expr_gen.to_str(o0)
38609 << "(t" << expr_gen.to_str(o1)
38610 << "(t" << expr_gen.to_str(o2)
38611 << "t))";
38612 }
38613 };
38614
38615 struct synthesize_vocovov_expression1
38616 {
38617 typedef typename vocovov_t::type1 node_type;
38618 typedef typename vocovov_t::sf4_type sf4_type;
38619 typedef typename node_type::T0 T0;
38620 typedef typename node_type::T1 T1;
38621 typedef typename node_type::T2 T2;
38622 typedef typename node_type::T3 T3;
38623
38624 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38625 const details::operator_type& operation,
38626 expression_node_ptr (&branch)[2])
38627 {
38628
38629 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
38630
38631 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
38632 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38633 const Type c = covov->t0();
38634 const Type& v1 = covov->t1();
38635 const Type& v2 = covov->t2();
38636 const details::operator_type o0 = operation;
38637 const details::operator_type o1 = expr_gen.get_operator(covov->f0());
38638 const details::operator_type o2 = expr_gen.get_operator(covov->f1());
38639
38640 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38641 binary_functor_t f1 = covov->f0();
38642 binary_functor_t f2 = covov->f1();
38643
38644 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38645
38646 expression_node_ptr result = error_node();
38647
38648 const bool synthesis_result =
38649 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38650 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
38651
38652 if (synthesis_result)
38653 return result;
38654 else if (!expr_gen.valid_operator(o0,f0))
38655 return error_node();
38656
38658
38659 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
38660 }
38661
38662 static inline std::string id(expression_generator<Type>& expr_gen,
38663 const details::operator_type o0,
38664 const details::operator_type o1,
38665 const details::operator_type o2)
38666 {
38667 return details::build_string()
38668 << "t" << expr_gen.to_str(o0)
38669 << "(t" << expr_gen.to_str(o1)
38670 << "(t" << expr_gen.to_str(o2)
38671 << "t))";
38672 }
38673 };
38674
38675 struct synthesize_covovov_expression1
38676 {
38677 typedef typename covovov_t::type1 node_type;
38678 typedef typename covovov_t::sf4_type sf4_type;
38679 typedef typename node_type::T0 T0;
38680 typedef typename node_type::T1 T1;
38681 typedef typename node_type::T2 T2;
38682 typedef typename node_type::T3 T3;
38683
38684 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38685 const details::operator_type& operation,
38686 expression_node_ptr (&branch)[2])
38687 {
38688
38689 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
38690
38691 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
38692 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
38693 const Type& v0 = vovov->t0();
38694 const Type& v1 = vovov->t1();
38695 const Type& v2 = vovov->t2();
38696 const details::operator_type o0 = operation;
38697 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
38698 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
38699
38700 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38701 binary_functor_t f1 = vovov->f0();
38702 binary_functor_t f2 = vovov->f1();
38703
38704 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38705 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38706
38707 expression_node_ptr result = error_node();
38708
38709 const bool synthesis_result =
38710 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38711 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
38712
38713 if (synthesis_result)
38714 return result;
38715 if (!expr_gen.valid_operator(o0,f0))
38716 return error_node();
38717
38719
38720 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
38721 }
38722
38723 static inline std::string id(expression_generator<Type>& expr_gen,
38724 const details::operator_type o0,
38725 const details::operator_type o1,
38726 const details::operator_type o2)
38727 {
38728 return details::build_string()
38729 << "t" << expr_gen.to_str(o0)
38730 << "(t" << expr_gen.to_str(o1)
38731 << "(t" << expr_gen.to_str(o2)
38732 << "t))";
38733 }
38734 };
38735
38736 struct synthesize_covocov_expression1
38737 {
38738 typedef typename covocov_t::type1 node_type;
38739 typedef typename covocov_t::sf4_type sf4_type;
38740 typedef typename node_type::T0 T0;
38741 typedef typename node_type::T1 T1;
38742 typedef typename node_type::T2 T2;
38743 typedef typename node_type::T3 T3;
38744
38745 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38746 const details::operator_type& operation,
38747 expression_node_ptr (&branch)[2])
38748 {
38749
38750 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
38751
38752 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
38753 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
38754 const Type& v0 = vocov->t0();
38755 const Type c1 = vocov->t1();
38756 const Type& v1 = vocov->t2();
38757 const details::operator_type o0 = operation;
38758 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
38759 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
38760
38761 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38762 binary_functor_t f1 = vocov->f0();
38763 binary_functor_t f2 = vocov->f1();
38764
38765 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38766 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38767
38768 expression_node_ptr result = error_node();
38769
38770 const bool synthesis_result =
38771 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38772 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
38773
38774 if (synthesis_result)
38775 return result;
38776 else if (!expr_gen.valid_operator(o0,f0))
38777 return error_node();
38778
38780
38781 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
38782 }
38783
38784 static inline std::string id(expression_generator<Type>& expr_gen,
38785 const details::operator_type o0,
38786 const details::operator_type o1,
38787 const details::operator_type o2)
38788 {
38789 return details::build_string()
38790 << "t" << expr_gen.to_str(o0)
38791 << "(t" << expr_gen.to_str(o1)
38792 << "(t" << expr_gen.to_str(o2)
38793 << "t))";
38794 }
38795 };
38796
38797 struct synthesize_vocovoc_expression1
38798 {
38799 typedef typename vocovoc_t::type1 node_type;
38800 typedef typename vocovoc_t::sf4_type sf4_type;
38801 typedef typename node_type::T0 T0;
38802 typedef typename node_type::T1 T1;
38803 typedef typename node_type::T2 T2;
38804 typedef typename node_type::T3 T3;
38805
38806 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38807 const details::operator_type& operation,
38808 expression_node_ptr (&branch)[2])
38809 {
38810
38811 typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
38812
38813 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
38814 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38815 const Type c0 = covoc->t0();
38816 const Type& v1 = covoc->t1();
38817 const Type c1 = covoc->t2();
38818 const details::operator_type o0 = operation;
38819 const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
38820 const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
38821
38822 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38823 binary_functor_t f1 = covoc->f0();
38824 binary_functor_t f2 = covoc->f1();
38825
38826 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38827
38828 expression_node_ptr result = error_node();
38829
38830 const bool synthesis_result =
38831 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38832 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
38833
38834 if (synthesis_result)
38835 return result;
38836 else if (!expr_gen.valid_operator(o0,f0))
38837 return error_node();
38838
38840
38841 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
38842 }
38843
38844 static inline std::string id(expression_generator<Type>& expr_gen,
38845 const details::operator_type o0,
38846 const details::operator_type o1,
38847 const details::operator_type o2)
38848 {
38849 return details::build_string()
38850 << "t" << expr_gen.to_str(o0)
38851 << "(t" << expr_gen.to_str(o1)
38852 << "(t" << expr_gen.to_str(o2)
38853 << "t))";
38854 }
38855 };
38856
38857 struct synthesize_covovoc_expression1
38858 {
38859 typedef typename covovoc_t::type1 node_type;
38860 typedef typename covovoc_t::sf4_type sf4_type;
38861 typedef typename node_type::T0 T0;
38862 typedef typename node_type::T1 T1;
38863 typedef typename node_type::T2 T2;
38864 typedef typename node_type::T3 T3;
38865 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38866 const details::operator_type& operation,
38867 expression_node_ptr (&branch)[2])
38868 {
38869
38870 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
38871
38872 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
38873 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
38874 const Type& v0 = vovoc->t0();
38875 const Type& v1 = vovoc->t1();
38876 const Type c1 = vovoc->t2();
38877 const details::operator_type o0 = operation;
38878 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
38879 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
38880
38881 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38882 binary_functor_t f1 = vovoc->f0();
38883 binary_functor_t f2 = vovoc->f1();
38884
38885 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38886 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38887
38888 expression_node_ptr result = error_node();
38889
38890 const bool synthesis_result =
38891 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38892 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
38893
38894 if (synthesis_result)
38895 return result;
38896 else if (!expr_gen.valid_operator(o0,f0))
38897 return error_node();
38898
38900
38901 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
38902 }
38903
38904 static inline std::string id(expression_generator<Type>& expr_gen,
38905 const details::operator_type o0,
38906 const details::operator_type o1,
38907 const details::operator_type o2)
38908 {
38909 return details::build_string()
38910 << "t" << expr_gen.to_str(o0)
38911 << "(t" << expr_gen.to_str(o1)
38912 << "(t" << expr_gen.to_str(o2)
38913 << "t))";
38914 }
38915 };
38916
38917 struct synthesize_vococov_expression1
38918 {
38919 typedef typename vococov_t::type1 node_type;
38920 typedef typename vococov_t::sf4_type sf4_type;
38921 typedef typename node_type::T0 T0;
38922 typedef typename node_type::T1 T1;
38923 typedef typename node_type::T2 T2;
38924 typedef typename node_type::T3 T3;
38925
38926 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38927 const details::operator_type& operation,
38928 expression_node_ptr (&branch)[2])
38929 {
38930
38931 typedef typename synthesize_cocov_expression1::node_type lcl_cocov_t;
38932
38933 const lcl_cocov_t* cocov = static_cast<const lcl_cocov_t*>(branch[1]);
38934 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38935 const Type c0 = cocov->t0();
38936 const Type c1 = cocov->t1();
38937 const Type& v1 = cocov->t2();
38938 const details::operator_type o0 = operation;
38939 const details::operator_type o1 = expr_gen.get_operator(cocov->f0());
38940 const details::operator_type o2 = expr_gen.get_operator(cocov->f1());
38941
38942 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38943 binary_functor_t f1 = cocov->f0();
38944 binary_functor_t f2 = cocov->f1();
38945
38946 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38947
38948 expression_node_ptr result = error_node();
38949
38950 const bool synthesis_result =
38951 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38952 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
38953
38954 if (synthesis_result)
38955 return result;
38956 else if (!expr_gen.valid_operator(o0,f0))
38957 return error_node();
38958
38960
38961 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
38962 }
38963
38964 static inline std::string id(expression_generator<Type>& expr_gen,
38965 const details::operator_type o0,
38966 const details::operator_type o1,
38967 const details::operator_type o2)
38968 {
38969 return details::build_string()
38970 << "t" << expr_gen.to_str(o0)
38971 << "(t" << expr_gen.to_str(o1)
38972 << "(t" << expr_gen.to_str(o2)
38973 << "t))";
38974 }
38975 };
38976
38977 struct synthesize_vovovov_expression2
38978 {
38979 typedef typename vovovov_t::type2 node_type;
38980 typedef typename vovovov_t::sf4_type sf4_type;
38981 typedef typename node_type::T0 T0;
38982 typedef typename node_type::T1 T1;
38983 typedef typename node_type::T2 T2;
38984 typedef typename node_type::T3 T3;
38985
38986 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38987 const details::operator_type& operation,
38988 expression_node_ptr (&branch)[2])
38989 {
38990
38991 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
38992
38993 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
38994 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38995 const Type& v1 = vovov->t0();
38996 const Type& v2 = vovov->t1();
38997 const Type& v3 = vovov->t2();
38998 const details::operator_type o0 = operation;
38999 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
39000 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
39001
39002 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39003 binary_functor_t f1 = vovov->f0();
39004 binary_functor_t f2 = vovov->f1();
39005
39006 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39007
39008 expression_node_ptr result = error_node();
39009
39010 const bool synthesis_result =
39011 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39012 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
39013
39014 if (synthesis_result)
39015 return result;
39016 else if (!expr_gen.valid_operator(o0,f0))
39017 return error_node();
39018
39020
39021 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
39022 }
39023
39024 static inline std::string id(expression_generator<Type>& expr_gen,
39025 const details::operator_type o0,
39026 const details::operator_type o1,
39027 const details::operator_type o2)
39028 {
39029 return details::build_string()
39030 << "t" << expr_gen.to_str(o0)
39031 << "((t" << expr_gen.to_str(o1)
39032 << "t)" << expr_gen.to_str(o2)
39033 << "t)";
39034 }
39035 };
39036
39037 struct synthesize_vovovoc_expression2
39038 {
39039 typedef typename vovovoc_t::type2 node_type;
39040 typedef typename vovovoc_t::sf4_type sf4_type;
39041 typedef typename node_type::T0 T0;
39042 typedef typename node_type::T1 T1;
39043 typedef typename node_type::T2 T2;
39044 typedef typename node_type::T3 T3;
39045
39046 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39047 const details::operator_type& operation,
39048 expression_node_ptr (&branch)[2])
39049 {
39050
39051 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
39052
39053 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
39054 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39055 const Type& v1 = vovoc->t0();
39056 const Type& v2 = vovoc->t1();
39057 const Type c = vovoc->t2();
39058 const details::operator_type o0 = operation;
39059 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
39060 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
39061
39062 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39063 binary_functor_t f1 = vovoc->f0();
39064 binary_functor_t f2 = vovoc->f1();
39065
39066 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39067
39068 expression_node_ptr result = error_node();
39069
39070 const bool synthesis_result =
39071 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39072 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
39073
39074 if (synthesis_result)
39075 return result;
39076 else if (!expr_gen.valid_operator(o0,f0))
39077 return error_node();
39078
39080
39081 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
39082 }
39083
39084 static inline std::string id(expression_generator<Type>& expr_gen,
39085 const details::operator_type o0,
39086 const details::operator_type o1,
39087 const details::operator_type o2)
39088 {
39089 return details::build_string()
39090 << "t" << expr_gen.to_str(o0)
39091 << "((t" << expr_gen.to_str(o1)
39092 << "t)" << expr_gen.to_str(o2)
39093 << "t)";
39094 }
39095 };
39096
39097 struct synthesize_vovocov_expression2
39098 {
39099 typedef typename vovocov_t::type2 node_type;
39100 typedef typename vovocov_t::sf4_type sf4_type;
39101 typedef typename node_type::T0 T0;
39102 typedef typename node_type::T1 T1;
39103 typedef typename node_type::T2 T2;
39104 typedef typename node_type::T3 T3;
39105
39106 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39107 const details::operator_type& operation,
39108 expression_node_ptr (&branch)[2])
39109 {
39110
39111 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39112
39113 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
39114 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39115 const Type& v1 = vocov->t0();
39116 const Type c = vocov->t1();
39117 const Type& v2 = vocov->t2();
39118 const details::operator_type o0 = operation;
39119 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
39120 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
39121
39122 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39123 binary_functor_t f1 = vocov->f0();
39124 binary_functor_t f2 = vocov->f1();
39125
39126 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39127
39128 expression_node_ptr result = error_node();
39129
39130 const bool synthesis_result =
39131 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39132 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
39133
39134 if (synthesis_result)
39135 return result;
39136 else if (!expr_gen.valid_operator(o0,f0))
39137 return error_node();
39138
39140
39141 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
39142 }
39143
39144 static inline std::string id(expression_generator<Type>& expr_gen,
39145 const details::operator_type o0,
39146 const details::operator_type o1,
39147 const details::operator_type o2)
39148 {
39149 return details::build_string()
39150 << "t" << expr_gen.to_str(o0)
39151 << "((t" << expr_gen.to_str(o1)
39152 << "t)" << expr_gen.to_str(o2)
39153 << "t)";
39154 }
39155 };
39156
39157 struct synthesize_vocovov_expression2
39158 {
39159 typedef typename vocovov_t::type2 node_type;
39160 typedef typename vocovov_t::sf4_type sf4_type;
39161 typedef typename node_type::T0 T0;
39162 typedef typename node_type::T1 T1;
39163 typedef typename node_type::T2 T2;
39164 typedef typename node_type::T3 T3;
39165
39166 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39167 const details::operator_type& operation,
39168 expression_node_ptr (&branch)[2])
39169 {
39170
39171 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
39172
39173 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
39174 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39175 const Type c = covov->t0();
39176 const Type& v1 = covov->t1();
39177 const Type& v2 = covov->t2();
39178 const details::operator_type o0 = operation;
39179 const details::operator_type o1 = expr_gen.get_operator(covov->f0());
39180 const details::operator_type o2 = expr_gen.get_operator(covov->f1());
39181
39182 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39183 binary_functor_t f1 = covov->f0();
39184 binary_functor_t f2 = covov->f1();
39185
39186 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39187
39188 expression_node_ptr result = error_node();
39189
39190 const bool synthesis_result =
39191 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39192 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
39193
39194 if (synthesis_result)
39195 return result;
39196 else if (!expr_gen.valid_operator(o0,f0))
39197 return error_node();
39198
39200
39201 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
39202 }
39203
39204 static inline std::string id(expression_generator<Type>& expr_gen,
39205 const details::operator_type o0,
39206 const details::operator_type o1,
39207 const details::operator_type o2)
39208 {
39209 return details::build_string()
39210 << "t" << expr_gen.to_str(o0)
39211 << "((t" << expr_gen.to_str(o1)
39212 << "t)" << expr_gen.to_str(o2)
39213 << "t)";
39214 }
39215 };
39216
39217 struct synthesize_covovov_expression2
39218 {
39219 typedef typename covovov_t::type2 node_type;
39220 typedef typename covovov_t::sf4_type sf4_type;
39221 typedef typename node_type::T0 T0;
39222 typedef typename node_type::T1 T1;
39223 typedef typename node_type::T2 T2;
39224 typedef typename node_type::T3 T3;
39225
39226 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39227 const details::operator_type& operation,
39228 expression_node_ptr (&branch)[2])
39229 {
39230
39231 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
39232
39233 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
39234 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
39235 const Type& v0 = vovov->t0();
39236 const Type& v1 = vovov->t1();
39237 const Type& v2 = vovov->t2();
39238 const details::operator_type o0 = operation;
39239 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
39240 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
39241
39242 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39243 binary_functor_t f1 = vovov->f0();
39244 binary_functor_t f2 = vovov->f1();
39245
39246 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39247 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39248
39249 expression_node_ptr result = error_node();
39250
39251 const bool synthesis_result =
39252 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39253 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
39254
39255 if (synthesis_result)
39256 return result;
39257 else if (!expr_gen.valid_operator(o0,f0))
39258 return error_node();
39259
39261
39262 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
39263 }
39264
39265 static inline std::string id(expression_generator<Type>& expr_gen,
39266 const details::operator_type o0,
39267 const details::operator_type o1,
39268 const details::operator_type o2)
39269 {
39270 return details::build_string()
39271 << "t" << expr_gen.to_str(o0)
39272 << "((t" << expr_gen.to_str(o1)
39273 << "t)" << expr_gen.to_str(o2)
39274 << "t)";
39275 }
39276 };
39277
39278 struct synthesize_covocov_expression2
39279 {
39280 typedef typename covocov_t::type2 node_type;
39281 typedef typename covocov_t::sf4_type sf4_type;
39282 typedef typename node_type::T0 T0;
39283 typedef typename node_type::T1 T1;
39284 typedef typename node_type::T2 T2;
39285 typedef typename node_type::T3 T3;
39286
39287 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39288 const details::operator_type& operation,
39289 expression_node_ptr (&branch)[2])
39290 {
39291
39292 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39293
39294 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
39295 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
39296 const Type& v0 = vocov->t0();
39297 const Type c1 = vocov->t1();
39298 const Type& v1 = vocov->t2();
39299 const details::operator_type o0 = operation;
39300 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
39301 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
39302
39303 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39304 binary_functor_t f1 = vocov->f0();
39305 binary_functor_t f2 = vocov->f1();
39306
39307 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39308 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39309
39310 expression_node_ptr result = error_node();
39311
39312 const bool synthesis_result =
39313 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39314 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
39315
39316 if (synthesis_result)
39317 return result;
39318 else if (!expr_gen.valid_operator(o0,f0))
39319 return error_node();
39320
39322
39323 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
39324 }
39325
39326 static inline std::string id(expression_generator<Type>& expr_gen,
39327 const details::operator_type o0,
39328 const details::operator_type o1,
39329 const details::operator_type o2)
39330 {
39331 return details::build_string()
39332 << "t" << expr_gen.to_str(o0)
39333 << "((t" << expr_gen.to_str(o1)
39334 << "t)" << expr_gen.to_str(o2)
39335 << "t)";
39336 }
39337 };
39338
39339 struct synthesize_vocovoc_expression2
39340 {
39341 typedef typename vocovoc_t::type2 node_type;
39342 typedef typename vocovoc_t::sf4_type sf4_type;
39343 typedef typename node_type::T0 T0;
39344 typedef typename node_type::T1 T1;
39345 typedef typename node_type::T2 T2;
39346 typedef typename node_type::T3 T3;
39347
39348 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39349 const details::operator_type& operation,
39350 expression_node_ptr (&branch)[2])
39351 {
39352
39353 typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
39354
39355 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
39356 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39357 const Type c0 = covoc->t0();
39358 const Type& v1 = covoc->t1();
39359 const Type c1 = covoc->t2();
39360 const details::operator_type o0 = operation;
39361 const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
39362 const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
39363
39364 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39365 binary_functor_t f1 = covoc->f0();
39366 binary_functor_t f2 = covoc->f1();
39367
39368 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39369
39370 expression_node_ptr result = error_node();
39371
39372 const bool synthesis_result =
39373 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39374 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
39375
39376 if (synthesis_result)
39377 return result;
39378 else if (!expr_gen.valid_operator(o0,f0))
39379 return error_node();
39380
39382
39383 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
39384 }
39385
39386 static inline std::string id(expression_generator<Type>& expr_gen,
39387 const details::operator_type o0,
39388 const details::operator_type o1,
39389 const details::operator_type o2)
39390 {
39391 return details::build_string()
39392 << "t" << expr_gen.to_str(o0)
39393 << "((t" << expr_gen.to_str(o1)
39394 << "t)" << expr_gen.to_str(o2)
39395 << "t)";
39396 }
39397 };
39398
39399 struct synthesize_covovoc_expression2
39400 {
39401 typedef typename covovoc_t::type2 node_type;
39402 typedef typename covovoc_t::sf4_type sf4_type;
39403 typedef typename node_type::T0 T0;
39404 typedef typename node_type::T1 T1;
39405 typedef typename node_type::T2 T2;
39406 typedef typename node_type::T3 T3;
39407
39408 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39409 const details::operator_type& operation,
39410 expression_node_ptr (&branch)[2])
39411 {
39412
39413 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
39414
39415 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
39416 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
39417 const Type& v0 = vovoc->t0();
39418 const Type& v1 = vovoc->t1();
39419 const Type c1 = vovoc->t2();
39420 const details::operator_type o0 = operation;
39421 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
39422 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
39423
39424 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39425 binary_functor_t f1 = vovoc->f0();
39426 binary_functor_t f2 = vovoc->f1();
39427
39428 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39429 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39430
39431 expression_node_ptr result = error_node();
39432
39433 const bool synthesis_result =
39434 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39435 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
39436
39437 if (synthesis_result)
39438 return result;
39439 else if (!expr_gen.valid_operator(o0,f0))
39440 return error_node();
39441
39443
39444 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
39445 }
39446
39447 static inline std::string id(expression_generator<Type>& expr_gen,
39448 const details::operator_type o0,
39449 const details::operator_type o1,
39450 const details::operator_type o2)
39451 {
39452 return details::build_string()
39453 << "t" << expr_gen.to_str(o0)
39454 << "((t" << expr_gen.to_str(o1)
39455 << "t)" << expr_gen.to_str(o2)
39456 << "t)";
39457 }
39458 };
39459
39460 struct synthesize_vococov_expression2
39461 {
39462 typedef typename vococov_t::type2 node_type;
39463 static inline expression_node_ptr
process(expression_generator<Type>&,
39464 const details::operator_type&,
39465 expression_node_ptr (&)[2])
39466 {
39467
39468 exprtk_debug((
"v0 o0 ((c0 o1 c1) o2 v1) - Not possible\n"));
39469 return error_node();
39470 }
39471
39472 static inline std::string id(expression_generator<Type>&,
39473 const details::operator_type,
39474 const details::operator_type,
39475 const details::operator_type)
39476 {
39477 return "INVALID";
39478 }
39479 };
39480
39481 struct synthesize_vovovov_expression3
39482 {
39483 typedef typename vovovov_t::type3 node_type;
39484 typedef typename vovovov_t::sf4_type sf4_type;
39485 typedef typename node_type::T0 T0;
39486 typedef typename node_type::T1 T1;
39487 typedef typename node_type::T2 T2;
39488 typedef typename node_type::T3 T3;
39489
39490 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39491 const details::operator_type& operation,
39492 expression_node_ptr (&branch)[2])
39493 {
39494
39495 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
39496
39497 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
39498 const Type& v0 = vovov->t0();
39499 const Type& v1 = vovov->t1();
39500 const Type& v2 = vovov->t2();
39501 const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39502 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
39503 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
39504 const details::operator_type o2 = operation;
39505
39506 binary_functor_t f0 = vovov->f0();
39507 binary_functor_t f1 = vovov->f1();
39508 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39509
39510 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39511
39512 expression_node_ptr result = error_node();
39513
39514 const bool synthesis_result =
39515 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39516 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
39517
39518 if (synthesis_result)
39519 return result;
39520 else if (!expr_gen.valid_operator(o2,f2))
39521 return error_node();
39522
39524
39525 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
39526 }
39527
39528 static inline std::string id(expression_generator<Type>& expr_gen,
39529 const details::operator_type o0,
39530 const details::operator_type o1,
39531 const details::operator_type o2)
39532 {
39533 return details::build_string()
39534 << "((t" << expr_gen.to_str(o0)
39535 << "t)" << expr_gen.to_str(o1)
39536 << "t)" << expr_gen.to_str(o2)
39537 << "t";
39538 }
39539 };
39540
39541 struct synthesize_vovovoc_expression3
39542 {
39543 typedef typename vovovoc_t::type3 node_type;
39544 typedef typename vovovoc_t::sf4_type sf4_type;
39545 typedef typename node_type::T0 T0;
39546 typedef typename node_type::T1 T1;
39547 typedef typename node_type::T2 T2;
39548 typedef typename node_type::T3 T3;
39549
39550 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39551 const details::operator_type& operation,
39552 expression_node_ptr (&branch)[2])
39553 {
39554
39555 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
39556
39557 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
39558 const Type& v0 = vovov->t0();
39559 const Type& v1 = vovov->t1();
39560 const Type& v2 = vovov->t2();
39561 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
39562 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
39563 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
39564 const details::operator_type o2 = operation;
39565
39566 binary_functor_t f0 = vovov->f0();
39567 binary_functor_t f1 = vovov->f1();
39568 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39569
39570 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39571 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39572
39573 expression_node_ptr result = error_node();
39574
39575 const bool synthesis_result =
39576 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39577 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
39578
39579 if (synthesis_result)
39580 return result;
39581 else if (!expr_gen.valid_operator(o2,f2))
39582 return error_node();
39583
39585
39586 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
39587 }
39588
39589 static inline std::string id(expression_generator<Type>& expr_gen,
39590 const details::operator_type o0,
39591 const details::operator_type o1,
39592 const details::operator_type o2)
39593 {
39594 return details::build_string()
39595 << "((t" << expr_gen.to_str(o0)
39596 << "t)" << expr_gen.to_str(o1)
39597 << "t)" << expr_gen.to_str(o2)
39598 << "t";
39599 }
39600 };
39601
39602 struct synthesize_vovocov_expression3
39603 {
39604 typedef typename vovocov_t::type3 node_type;
39605 typedef typename vovocov_t::sf4_type sf4_type;
39606 typedef typename node_type::T0 T0;
39607 typedef typename node_type::T1 T1;
39608 typedef typename node_type::T2 T2;
39609 typedef typename node_type::T3 T3;
39610
39611 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39612 const details::operator_type& operation,
39613 expression_node_ptr (&branch)[2])
39614 {
39615
39616 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
39617
39618 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
39619 const Type& v0 = vovoc->t0();
39620 const Type& v1 = vovoc->t1();
39621 const Type c = vovoc->t2();
39622 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39623 const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
39624 const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
39625 const details::operator_type o2 = operation;
39626
39627 binary_functor_t f0 = vovoc->f0();
39628 binary_functor_t f1 = vovoc->f1();
39629 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39630
39631 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39632
39633 expression_node_ptr result = error_node();
39634
39635 const bool synthesis_result =
39636 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39637 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
39638
39639 if (synthesis_result)
39640 return result;
39641 else if (!expr_gen.valid_operator(o2,f2))
39642 return error_node();
39643
39645
39646 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
39647 }
39648
39649 static inline std::string id(expression_generator<Type>& expr_gen,
39650 const details::operator_type o0,
39651 const details::operator_type o1,
39652 const details::operator_type o2)
39653 {
39654 return details::build_string()
39655 << "((t" << expr_gen.to_str(o0)
39656 << "t)" << expr_gen.to_str(o1)
39657 << "t)" << expr_gen.to_str(o2)
39658 << "t";
39659 }
39660 };
39661
39662 struct synthesize_vocovov_expression3
39663 {
39664 typedef typename vocovov_t::type3 node_type;
39665 typedef typename vocovov_t::sf4_type sf4_type;
39666 typedef typename node_type::T0 T0;
39667 typedef typename node_type::T1 T1;
39668 typedef typename node_type::T2 T2;
39669 typedef typename node_type::T3 T3;
39670
39671 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39672 const details::operator_type& operation,
39673 expression_node_ptr (&branch)[2])
39674 {
39675
39676 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39677
39678 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
39679 const Type& v0 = vocov->t0();
39680 const Type c = vocov->t1();
39681 const Type& v1 = vocov->t2();
39682 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39683 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
39684 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
39685 const details::operator_type o2 = operation;
39686
39687 binary_functor_t f0 = vocov->f0();
39688 binary_functor_t f1 = vocov->f1();
39689 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39690
39691 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39692
39693 expression_node_ptr result = error_node();
39694
39695 const bool synthesis_result =
39696 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39697 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
39698
39699 if (synthesis_result)
39700 return result;
39701 else if (!expr_gen.valid_operator(o2,f2))
39702 return error_node();
39703
39705
39706 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
39707 }
39708
39709 static inline std::string id(expression_generator<Type>& expr_gen,
39710 const details::operator_type o0,
39711 const details::operator_type o1,
39712 const details::operator_type o2)
39713 {
39714 return details::build_string()
39715 << "((t" << expr_gen.to_str(o0)
39716 << "t)" << expr_gen.to_str(o1)
39717 << "t)" << expr_gen.to_str(o2)
39718 << "t";
39719 }
39720 };
39721
39722 struct synthesize_covovov_expression3
39723 {
39724 typedef typename covovov_t::type3 node_type;
39725 typedef typename covovov_t::sf4_type sf4_type;
39726 typedef typename node_type::T0 T0;
39727 typedef typename node_type::T1 T1;
39728 typedef typename node_type::T2 T2;
39729 typedef typename node_type::T3 T3;
39730
39731 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39732 const details::operator_type& operation,
39733 expression_node_ptr (&branch)[2])
39734 {
39735
39736 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
39737
39738 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
39739 const Type c = covov->t0();
39740 const Type& v0 = covov->t1();
39741 const Type& v1 = covov->t2();
39742 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39743 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
39744 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
39745 const details::operator_type o2 = operation;
39746
39747 binary_functor_t f0 = covov->f0();
39748 binary_functor_t f1 = covov->f1();
39749 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39750
39751 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39752
39753 expression_node_ptr result = error_node();
39754
39755 const bool synthesis_result =
39756 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39757 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
39758
39759 if (synthesis_result)
39760 return result;
39761 else if (!expr_gen.valid_operator(o2,f2))
39762 return error_node();
39763
39765
39766 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
39767 }
39768
39769 static inline std::string id(expression_generator<Type>& expr_gen,
39770 const details::operator_type o0,
39771 const details::operator_type o1,
39772 const details::operator_type o2)
39773 {
39774 return details::build_string()
39775 << "((t" << expr_gen.to_str(o0)
39776 << "t)" << expr_gen.to_str(o1)
39777 << "t)" << expr_gen.to_str(o2)
39778 << "t";
39779 }
39780 };
39781
39782 struct synthesize_covocov_expression3
39783 {
39784 typedef typename covocov_t::type3 node_type;
39785 typedef typename covocov_t::sf4_type sf4_type;
39786 typedef typename node_type::T0 T0;
39787 typedef typename node_type::T1 T1;
39788 typedef typename node_type::T2 T2;
39789 typedef typename node_type::T3 T3;
39790
39791 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39792 const details::operator_type& operation,
39793 expression_node_ptr (&branch)[2])
39794 {
39795
39796 typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
39797
39798 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
39799 const Type c0 = covoc->t0();
39800 const Type& v0 = covoc->t1();
39801 const Type c1 = covoc->t2();
39802 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39803 const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
39804 const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
39805 const details::operator_type o2 = operation;
39806
39807 binary_functor_t f0 = covoc->f0();
39808 binary_functor_t f1 = covoc->f1();
39809 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39810
39811 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39812
39813 expression_node_ptr result = error_node();
39814
39815 const bool synthesis_result =
39816 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39817 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
39818
39819 if (synthesis_result)
39820 return result;
39821 else if (!expr_gen.valid_operator(o2,f2))
39822 return error_node();
39823
39825
39826 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
39827 }
39828
39829 static inline std::string id(expression_generator<Type>& expr_gen,
39830 const details::operator_type o0,
39831 const details::operator_type o1,
39832 const details::operator_type o2)
39833 {
39834 return details::build_string()
39835 << "((t" << expr_gen.to_str(o0)
39836 << "t)" << expr_gen.to_str(o1)
39837 << "t)" << expr_gen.to_str(o2)
39838 << "t";
39839 }
39840 };
39841
39842 struct synthesize_vocovoc_expression3
39843 {
39844 typedef typename vocovoc_t::type3 node_type;
39845 typedef typename vocovoc_t::sf4_type sf4_type;
39846 typedef typename node_type::T0 T0;
39847 typedef typename node_type::T1 T1;
39848 typedef typename node_type::T2 T2;
39849 typedef typename node_type::T3 T3;
39850
39851 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39852 const details::operator_type& operation,
39853 expression_node_ptr (&branch)[2])
39854 {
39855
39856 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39857
39858 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
39859 const Type& v0 = vocov->t0();
39860 const Type c0 = vocov->t1();
39861 const Type& v1 = vocov->t2();
39862 const Type c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
39863 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
39864 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
39865 const details::operator_type o2 = operation;
39866
39867 binary_functor_t f0 = vocov->f0();
39868 binary_functor_t f1 = vocov->f1();
39869 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39870
39871 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39872 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39873
39874 expression_node_ptr result = error_node();
39875
39876 const bool synthesis_result =
39877 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39878 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
39879
39880 if (synthesis_result)
39881 return result;
39882 else if (!expr_gen.valid_operator(o2,f2))
39883 return error_node();
39884
39886
39887 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
39888 }
39889
39890 static inline std::string id(expression_generator<Type>& expr_gen,
39891 const details::operator_type o0,
39892 const details::operator_type o1,
39893 const details::operator_type o2)
39894 {
39895 return details::build_string()
39896 << "((t" << expr_gen.to_str(o0)
39897 << "t)" << expr_gen.to_str(o1)
39898 << "t)" << expr_gen.to_str(o2)
39899 << "t";
39900 }
39901 };
39902
39903 struct synthesize_covovoc_expression3
39904 {
39905 typedef typename covovoc_t::type3 node_type;
39906 typedef typename covovoc_t::sf4_type sf4_type;
39907 typedef typename node_type::T0 T0;
39908 typedef typename node_type::T1 T1;
39909 typedef typename node_type::T2 T2;
39910 typedef typename node_type::T3 T3;
39911
39912 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39913 const details::operator_type& operation,
39914 expression_node_ptr (&branch)[2])
39915 {
39916
39917 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
39918
39919 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
39920 const Type c0 = covov->t0();
39921 const Type& v0 = covov->t1();
39922 const Type& v1 = covov->t2();
39923 const Type c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
39924 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
39925 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
39926 const details::operator_type o2 = operation;
39927
39928 binary_functor_t f0 = covov->f0();
39929 binary_functor_t f1 = covov->f1();
39930 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39931
39932 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39933 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39934
39935 expression_node_ptr result = error_node();
39936
39937 const bool synthesis_result =
39938 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39939 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
39940
39941 if (synthesis_result)
39942 return result;
39943 else if (!expr_gen.valid_operator(o2,f2))
39944 return error_node();
39945
39947
39948 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
39949 }
39950
39951 static inline std::string id(expression_generator<Type>& expr_gen,
39952 const details::operator_type o0,
39953 const details::operator_type o1,
39954 const details::operator_type o2)
39955 {
39956 return details::build_string()
39957 << "((t" << expr_gen.to_str(o0)
39958 << "t)" << expr_gen.to_str(o1)
39959 << "t)" << expr_gen.to_str(o2)
39960 << "t";
39961 }
39962 };
39963
39964 struct synthesize_vococov_expression3
39965 {
39966 typedef typename vococov_t::type3 node_type;
39967 typedef typename vococov_t::sf4_type sf4_type;
39968 typedef typename node_type::T0 T0;
39969 typedef typename node_type::T1 T1;
39970 typedef typename node_type::T2 T2;
39971 typedef typename node_type::T3 T3;
39972
39973 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
39974 const details::operator_type& operation,
39975 expression_node_ptr (&branch)[2])
39976 {
39977
39978 typedef typename synthesize_vococ_expression0::node_type lcl_vococ_t;
39979
39980 const lcl_vococ_t* vococ = static_cast<const lcl_vococ_t*>(branch[0]);
39981 const Type& v0 = vococ->t0();
39982 const Type c0 = vococ->t1();
39983 const Type c1 = vococ->t2();
39984 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39985 const details::operator_type o0 = expr_gen.get_operator(vococ->f0());
39986 const details::operator_type o1 = expr_gen.get_operator(vococ->f1());
39987 const details::operator_type o2 = operation;
39988
39989 binary_functor_t f0 = vococ->f0();
39990 binary_functor_t f1 = vococ->f1();
39991 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39992
39993 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39994
39995 expression_node_ptr result = error_node();
39996
39997 const bool synthesis_result =
39998 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39999 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
40000
40001 if (synthesis_result)
40002 return result;
40003 else if (!expr_gen.valid_operator(o2,f2))
40004 return error_node();
40005
40007
40008 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
40009 }
40010
40011 static inline std::string id(expression_generator<Type>& expr_gen,
40012 const details::operator_type o0,
40013 const details::operator_type o1,
40014 const details::operator_type o2)
40015 {
40016 return details::build_string()
40017 << "((t" << expr_gen.to_str(o0)
40018 << "t)" << expr_gen.to_str(o1)
40019 << "t)" << expr_gen.to_str(o2)
40020 << "t";
40021 }
40022 };
40023
40024 struct synthesize_vovovov_expression4
40025 {
40026 typedef typename vovovov_t::type4 node_type;
40027 typedef typename vovovov_t::sf4_type sf4_type;
40028 typedef typename node_type::T0 T0;
40029 typedef typename node_type::T1 T1;
40030 typedef typename node_type::T2 T2;
40031 typedef typename node_type::T3 T3;
40032
40033 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
40034 const details::operator_type& operation,
40035 expression_node_ptr (&branch)[2])
40036 {
40037
40038 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
40039
40040 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
40041 const Type& v0 = vovov->t0();
40042 const Type& v1 = vovov->t1();
40043 const Type& v2 = vovov->t2();
40044 const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40045 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
40046 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
40047 const details::operator_type o2 = operation;
40048
40049 binary_functor_t f0 = vovov->f0();
40050 binary_functor_t f1 = vovov->f1();
40051 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40052
40053 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40054
40055 expression_node_ptr result = error_node();
40056
40057 const bool synthesis_result =
40058 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40059 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
40060
40061 if (synthesis_result)
40062 return result;
40063 else if (!expr_gen.valid_operator(o2,f2))
40064 return error_node();
40065
40067
40068 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
40069 }
40070
40071 static inline std::string id(expression_generator<Type>& expr_gen,
40072 const details::operator_type o0,
40073 const details::operator_type o1,
40074 const details::operator_type o2)
40075 {
40076 return details::build_string()
40077 << "(t" << expr_gen.to_str(o0)
40078 << "(t" << expr_gen.to_str(o1)
40079 << "t)" << expr_gen.to_str(o2)
40080 << "t";
40081 }
40082 };
40083
40084 struct synthesize_vovovoc_expression4
40085 {
40086 typedef typename vovovoc_t::type4 node_type;
40087 typedef typename vovovoc_t::sf4_type sf4_type;
40088 typedef typename node_type::T0 T0;
40089 typedef typename node_type::T1 T1;
40090 typedef typename node_type::T2 T2;
40091 typedef typename node_type::T3 T3;
40092
40093 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
40094 const details::operator_type& operation,
40095 expression_node_ptr (&branch)[2])
40096 {
40097
40098 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
40099
40100 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
40101 const Type& v0 = vovov->t0();
40102 const Type& v1 = vovov->t1();
40103 const Type& v2 = vovov->t2();
40104 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
40105 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
40106 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
40107 const details::operator_type o2 = operation;
40108
40109 binary_functor_t f0 = vovov->f0();
40110 binary_functor_t f1 = vovov->f1();
40111 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40112
40113 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40114 details::free_node(*(expr_gen.node_allocator_),branch[1]);
40115
40116 expression_node_ptr result = error_node();
40117
40118 const bool synthesis_result =
40119 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40120 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
40121
40122 if (synthesis_result)
40123 return result;
40124 else if (!expr_gen.valid_operator(o2,f2))
40125 return error_node();
40126
40128
40129 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
40130 }
40131
40132 static inline std::string id(expression_generator<Type>& expr_gen,
40133 const details::operator_type o0,
40134 const details::operator_type o1,
40135 const details::operator_type o2)
40136 {
40137 return details::build_string()
40138 << "(t" << expr_gen.to_str(o0)
40139 << "(t" << expr_gen.to_str(o1)
40140 << "t)" << expr_gen.to_str(o2)
40141 << "t";
40142 }
40143 };
40144
40145 struct synthesize_vovocov_expression4
40146 {
40147 typedef typename vovocov_t::type4 node_type;
40148 typedef typename vovocov_t::sf4_type sf4_type;
40149 typedef typename node_type::T0 T0;
40150 typedef typename node_type::T1 T1;
40151 typedef typename node_type::T2 T2;
40152 typedef typename node_type::T3 T3;
40153
40154 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
40155 const details::operator_type& operation,
40156 expression_node_ptr (&branch)[2])
40157 {
40158
40159 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
40160
40161 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
40162 const Type& v0 = vovoc->t0();
40163 const Type& v1 = vovoc->t1();
40164 const Type c = vovoc->t2();
40165 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40166 const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
40167 const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
40168 const details::operator_type o2 = operation;
40169
40170 binary_functor_t f0 = vovoc->f0();
40171 binary_functor_t f1 = vovoc->f1();
40172 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40173
40174 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40175
40176 expression_node_ptr result = error_node();
40177
40178 const bool synthesis_result =
40179 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40180 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
40181
40182 if (synthesis_result)
40183 return result;
40184 else if (!expr_gen.valid_operator(o2,f2))
40185 return error_node();
40186
40188
40189 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
40190 }
40191
40192 static inline std::string id(expression_generator<Type>& expr_gen,
40193 const details::operator_type o0,
40194 const details::operator_type o1,
40195 const details::operator_type o2)
40196 {
40197 return details::build_string()
40198 << "(t" << expr_gen.to_str(o0)
40199 << "(t" << expr_gen.to_str(o1)
40200 << "t)" << expr_gen.to_str(o2)
40201 << "t";
40202 }
40203 };
40204
40205 struct synthesize_vocovov_expression4
40206 {
40207 typedef typename vocovov_t::type4 node_type;
40208 typedef typename vocovov_t::sf4_type sf4_type;
40209 typedef typename node_type::T0 T0;
40210 typedef typename node_type::T1 T1;
40211 typedef typename node_type::T2 T2;
40212 typedef typename node_type::T3 T3;
40213
40214 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
40215 const details::operator_type& operation,
40216 expression_node_ptr (&branch)[2])
40217 {
40218
40219 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
40220
40221 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
40222 const Type& v0 = vocov->t0();
40223 const Type c = vocov->t1();
40224 const Type& v1 = vocov->t2();
40225 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40226 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
40227 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
40228 const details::operator_type o2 = operation;
40229
40230 binary_functor_t f0 = vocov->f0();
40231 binary_functor_t f1 = vocov->f1();
40232 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40233
40234 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40235 expression_node_ptr result = error_node();
40236
40237 const bool synthesis_result =
40238 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40239 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
40240
40241 if (synthesis_result)
40242 return result;
40243 else if (!expr_gen.valid_operator(o2,f2))
40244 return error_node();
40245
40247
40248 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
40249 }
40250
40251 static inline std::string id(expression_generator<Type>& expr_gen,
40252 const details::operator_type o0,
40253 const details::operator_type o1,
40254 const details::operator_type o2)
40255 {
40256 return details::build_string()
40257 << "(t" << expr_gen.to_str(o0)
40258 << "(t" << expr_gen.to_str(o1)
40259 << "t)" << expr_gen.to_str(o2)
40260 << "t";
40261 }
40262 };
40263
40264 struct synthesize_covovov_expression4
40265 {
40266 typedef typename covovov_t::type4 node_type;
40267 typedef typename covovov_t::sf4_type sf4_type;
40268 typedef typename node_type::T0 T0;
40269 typedef typename node_type::T1 T1;
40270 typedef typename node_type::T2 T2;
40271 typedef typename node_type::T3 T3;
40272
40273 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
40274 const details::operator_type& operation,
40275 expression_node_ptr (&branch)[2])
40276 {
40277
40278 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
40279
40280 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
40281 const Type c = covov->t0();
40282 const Type& v0 = covov->t1();
40283 const Type& v1 = covov->t2();
40284 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40285 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
40286 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
40287 const details::operator_type o2 = operation;
40288
40289 binary_functor_t f0 = covov->f0();
40290 binary_functor_t f1 = covov->f1();
40291 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40292
40293 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40294
40295 expression_node_ptr result = error_node();
40296
40297 const bool synthesis_result =
40298 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40299 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
40300
40301 if (synthesis_result)
40302 return result;
40303 else if (!expr_gen.valid_operator(o2,f2))
40304 return error_node();
40305
40307
40308 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
40309 }
40310
40311 static inline std::string id(expression_generator<Type>& expr_gen,
40312 const details::operator_type o0,
40313 const details::operator_type o1,
40314 const details::operator_type o2)
40315 {
40316 return details::build_string()
40317 << "(t" << expr_gen.to_str(o0)
40318 << "(t" << expr_gen.to_str(o1)
40319 << "t)" << expr_gen.to_str(o2)
40320 << "t";
40321 }
40322 };
40323
40324 struct synthesize_covocov_expression4
40325 {
40326 typedef typename covocov_t::type4 node_type;
40327 typedef typename covocov_t::sf4_type sf4_type;
40328 typedef typename node_type::T0 T0;
40329 typedef typename node_type::T1 T1;
40330 typedef typename node_type::T2 T2;
40331 typedef typename node_type::T3 T3;
40332
40333 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
40334 const details::operator_type& operation,
40335 expression_node_ptr (&branch)[2])
40336 {
40337
40338 typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
40339
40340 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
40341 const Type c0 = covoc->t0();
40342 const Type& v0 = covoc->t1();
40343 const Type c1 = covoc->t2();
40344 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40345 const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
40346 const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
40347 const details::operator_type o2 = operation;
40348
40349 binary_functor_t f0 = covoc->f0();
40350 binary_functor_t f1 = covoc->f1();
40351 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40352
40353 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40354
40355 expression_node_ptr result = error_node();
40356
40357 const bool synthesis_result =
40358 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40359 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
40360
40361 if (synthesis_result)
40362 return result;
40363 else if (!expr_gen.valid_operator(o2,f2))
40364 return error_node();
40365
40367
40368 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
40369 }
40370
40371 static inline std::string id(expression_generator<Type>& expr_gen,
40372 const details::operator_type o0,
40373 const details::operator_type o1,
40374 const details::operator_type o2)
40375 {
40376 return details::build_string()
40377 << "(t" << expr_gen.to_str(o0)
40378 << "(t" << expr_gen.to_str(o1)
40379 << "t)" << expr_gen.to_str(o2)
40380 << "t";
40381 }
40382 };
40383
40384 struct synthesize_vocovoc_expression4
40385 {
40386 typedef typename vocovoc_t::type4 node_type;
40387 typedef typename vocovoc_t::sf4_type sf4_type;
40388 typedef typename node_type::T0 T0;
40389 typedef typename node_type::T1 T1;
40390 typedef typename node_type::T2 T2;
40391 typedef typename node_type::T3 T3;
40392
40393 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
40394 const details::operator_type& operation,
40395 expression_node_ptr (&branch)[2])
40396 {
40397
40398 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
40399
40400 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
40401 const Type& v0 = vocov->t0();
40402 const Type c0 = vocov->t1();
40403 const Type& v1 = vocov->t2();
40404 const Type c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
40405 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
40406 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
40407 const details::operator_type o2 = operation;
40408
40409 binary_functor_t f0 = vocov->f0();
40410 binary_functor_t f1 = vocov->f1();
40411 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40412
40413 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40414 details::free_node(*(expr_gen.node_allocator_),branch[1]);
40415
40416 expression_node_ptr result = error_node();
40417
40418 const bool synthesis_result =
40419 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40420 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
40421
40422 if (synthesis_result)
40423 return result;
40424 else if (!expr_gen.valid_operator(o2,f2))
40425 return error_node();
40426
40428
40429 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
40430 }
40431
40432 static inline std::string id(expression_generator<Type>& expr_gen,
40433 const details::operator_type o0,
40434 const details::operator_type o1,
40435 const details::operator_type o2)
40436 {
40437 return details::build_string()
40438 << "(t" << expr_gen.to_str(o0)
40439 << "(t" << expr_gen.to_str(o1)
40440 << "t)" << expr_gen.to_str(o2)
40441 << "t";
40442 }
40443 };
40444
40445 struct synthesize_covovoc_expression4
40446 {
40447 typedef typename covovoc_t::type4 node_type;
40448 typedef typename covovoc_t::sf4_type sf4_type;
40449 typedef typename node_type::T0 T0;
40450 typedef typename node_type::T1 T1;
40451 typedef typename node_type::T2 T2;
40452 typedef typename node_type::T3 T3;
40453
40454 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
40455 const details::operator_type& operation,
40456 expression_node_ptr (&branch)[2])
40457 {
40458
40459 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
40460
40461 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
40462 const Type c0 = covov->t0();
40463 const Type& v0 = covov->t1();
40464 const Type& v1 = covov->t2();
40465 const Type c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
40466 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
40467 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
40468 const details::operator_type o2 = operation;
40469
40470 binary_functor_t f0 = covov->f0();
40471 binary_functor_t f1 = covov->f1();
40472 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40473
40474 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40475 details::free_node(*(expr_gen.node_allocator_),branch[1]);
40476
40477 expression_node_ptr result = error_node();
40478
40479 const bool synthesis_result =
40480 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40481 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
40482
40483 if (synthesis_result)
40484 return result;
40485 else if (!expr_gen.valid_operator(o2,f2))
40486 return error_node();
40487
40489
40490 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
40491 }
40492
40493 static inline std::string id(expression_generator<Type>& expr_gen,
40494 const details::operator_type o0,
40495 const details::operator_type o1,
40496 const details::operator_type o2)
40497 {
40498 return details::build_string()
40499 << "(t" << expr_gen.to_str(o0)
40500 << "(t" << expr_gen.to_str(o1)
40501 << "t)" << expr_gen.to_str(o2)
40502 << "t";
40503 }
40504 };
40505
40506 struct synthesize_vococov_expression4
40507 {
40508 typedef typename vococov_t::type4 node_type;
40509 static inline expression_node_ptr
process(expression_generator<Type>&,
40510 const details::operator_type&,
40511 expression_node_ptr (&)[2])
40512 {
40513
40514 exprtk_debug((
"((v0 o0 (c0 o1 c1)) o2 v1) - Not possible\n"));
40515 return error_node();
40516 }
40517
40518 static inline std::string id(expression_generator<Type>&,
40519 const details::operator_type,
40520 const details::operator_type,
40521 const details::operator_type)
40522 {
40523 return "INVALID";
40524 }
40525 };
40526 #endif
40527
40528 inline expression_node_ptr synthesize_uvouv_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
40529 {
40530
40531 details::operator_type o0 = static_cast<details::uv_base_node<Type>*>(branch[0])->operation();
40532 details::operator_type o1 = static_cast<details::uv_base_node<Type>*>(branch[1])->operation();
40533 const Type& v0 = static_cast<details::uv_base_node<Type>*>(branch[0])->v();
40534 const Type& v1 = static_cast<details::uv_base_node<Type>*>(branch[1])->v();
40535 unary_functor_t u0 = reinterpret_cast<unary_functor_t> (0);
40536 unary_functor_t u1 = reinterpret_cast<unary_functor_t> (0);
40537 binary_functor_t f = reinterpret_cast<binary_functor_t>(0);
40538
40539 if (!valid_operator(o0,u0))
40540 return error_node();
40541 else if (!valid_operator(o1,u1))
40542 return error_node();
40543 else if (!valid_operator(operation,f))
40544 return error_node();
40545
40546 expression_node_ptr result = error_node();
40547
40548 if (
40549 (details::e_neg == o0) &&
40550 (details::e_neg == o1)
40551 )
40552 {
40553 switch (operation)
40554 {
40555
40556 case details::e_add : result = (*this)(details::e_neg,
40557 node_allocator_->
40558 allocate_rr<typename details::
40559 vov_node<Type,details::add_op<Type> > >(v0, v1));
40561 break;
40562
40563
40564 case details::e_sub : result = node_allocator_->
40565 allocate_rr<typename details::
40566 vov_node<Type,details::sub_op<Type> > >(v1, v0);
40568 break;
40569
40570
40571 case details::e_mul : result = node_allocator_->
40572 allocate_rr<typename details::
40573 vov_node<Type,details::mul_op<Type> > >(v0, v1);
40575 break;
40576
40577
40578 case details::e_div : result = node_allocator_->
40579 allocate_rr<typename details::
40580 vov_node<Type,details::div_op<Type> > >(v0, v1);
40582 break;
40583
40584 default : break;
40585 }
40586 }
40587
40588 if (0 == result)
40589 {
40590 result = node_allocator_->
40591 allocate_rrrrr<typename details::uvouv_node<Type> >(v0, v1, u0, u1, f);
40592 }
40593
40594 details::free_all_nodes(*node_allocator_,branch);
40595 return result;
40596 }
40597
40598 #undef basic_opr_switch_statements
40599 #undef extended_opr_switch_statements
40600 #undef unary_opr_switch_statements
40601
40602 #ifndef exprtk_disable_string_capabilities
40603
40604 #define string_opr_switch_statements \
40605 case_stmt(details::e_lt , details::lt_op ) \
40606 case_stmt(details::e_lte , details::lte_op ) \
40607 case_stmt(details::e_gt , details::gt_op ) \
40608 case_stmt(details::e_gte , details::gte_op ) \
40609 case_stmt(details::e_eq , details::eq_op ) \
40610 case_stmt(details::e_ne , details::ne_op ) \
40611 case_stmt(details::e_in , details::in_op ) \
40612 case_stmt(details::e_like , details::like_op ) \
40613 case_stmt(details::e_ilike , details::ilike_op) \
40614
40615 template <typename T0, typename T1>
40616 inline expression_node_ptr synthesize_str_xrox_expression_impl(const details::operator_type& opr,
40617 T0 s0, T1 s1,
40618 range_t rp0)
40619 {
40620 switch (opr)
40621 {
40622 #define case_stmt(op0, op1) \
40623 case op0 : return node_allocator_-> \
40624 allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
40625 (s0, s1, rp0); \
40626
40628 #undef case_stmt
40629 default : return error_node();
40630 }
40631 }
40632
40633 template <typename T0, typename T1>
40634 inline expression_node_ptr synthesize_str_xoxr_expression_impl(const details::operator_type& opr,
40635 T0 s0, T1 s1,
40636 range_t rp1)
40637 {
40638 switch (opr)
40639 {
40640 #define case_stmt(op0, op1) \
40641 case op0 : return node_allocator_-> \
40642 allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
40643 (s0, s1, rp1); \
40644
40646 #undef case_stmt
40647 default : return error_node();
40648 }
40649 }
40650
40651 template <typename T0, typename T1>
40652 inline expression_node_ptr synthesize_str_xroxr_expression_impl(const details::operator_type& opr,
40653 T0 s0, T1 s1,
40654 range_t rp0, range_t rp1)
40655 {
40656 switch (opr)
40657 {
40658 #define case_stmt(op0, op1) \
40659 case op0 : return node_allocator_-> \
40660 allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
40661 (s0, s1, rp0, rp1); \
40662
40664 #undef case_stmt
40665 default : return error_node();
40666 }
40667 }
40668
40669 template <typename T0, typename T1>
40670 inline expression_node_ptr synthesize_sos_expression_impl(const details::operator_type& opr, T0 s0, T1 s1)
40671 {
40672 switch (opr)
40673 {
40674 #define case_stmt(op0, op1) \
40675 case op0 : return node_allocator_-> \
40676 allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0, s1); \
40677
40679 #undef case_stmt
40680 default : return error_node();
40681 }
40682 }
40683
40684 inline expression_node_ptr synthesize_sos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40685 {
40686 std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
40687 std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
40688
40689 return synthesize_sos_expression_impl<std::string&,std::string&>(opr, s0, s1);
40690 }
40691
40692 inline expression_node_ptr synthesize_sros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40693 {
40694 std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
40695 std::string& s1 = static_cast<details::stringvar_node<Type>*> (branch[1])->ref ();
40696 range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
40697
40698 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
40699
40700 details::free_node(*node_allocator_,branch[0]);
40701
40702 return synthesize_str_xrox_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0);
40703 }
40704
40705 inline expression_node_ptr synthesize_sosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40706 {
40707 std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
40708 std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
40709 range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
40710
40711 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
40712
40713 details::free_node(*node_allocator_,branch[1]);
40714
40715 return synthesize_str_xoxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp1);
40716 }
40717
40718 inline expression_node_ptr synthesize_socsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40719 {
40720 std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
40721 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40722 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40723
40724 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40725
40726 details::free_node(*node_allocator_,branch[1]);
40727
40728 return synthesize_str_xoxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp1);
40729 }
40730
40731 inline expression_node_ptr synthesize_srosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40732 {
40733 std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
40734 std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
40735 range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
40736 range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
40737
40738 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
40739 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
40740
40741 details::free_node(*node_allocator_,branch[0]);
40742 details::free_node(*node_allocator_,branch[1]);
40743
40744 return synthesize_str_xroxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0, rp1);
40745 }
40746
40747 inline expression_node_ptr synthesize_socs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40748 {
40749 std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
40750 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
40751
40752 details::free_node(*node_allocator_,branch[1]);
40753
40754 return synthesize_sos_expression_impl<std::string&, const std::string>(opr, s0, s1);
40755 }
40756
40757 inline expression_node_ptr synthesize_csos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40758 {
40759 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
40760 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
40761
40762 details::free_node(*node_allocator_,branch[0]);
40763
40764 return synthesize_sos_expression_impl<const std::string,std::string&>(opr, s0, s1);
40765 }
40766
40767 inline expression_node_ptr synthesize_csosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40768 {
40769 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str ();
40770 std::string& s1 = static_cast<details::string_range_node<Type>* >(branch[1])->ref ();
40771 range_t rp1 = static_cast<details::string_range_node<Type>* >(branch[1])->range();
40772
40773 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
40774
40775 details::free_node(*node_allocator_,branch[0]);
40776 details::free_node(*node_allocator_,branch[1]);
40777
40778 return synthesize_str_xoxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp1);
40779 }
40780
40781 inline expression_node_ptr synthesize_srocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40782 {
40783 std::string& s0 = static_cast<details::string_range_node<Type>* >(branch[0])->ref ();
40784 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str ();
40785 range_t rp0 = static_cast<details::string_range_node<Type>* >(branch[0])->range();
40786
40787 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
40788
40789 details::free_node(*node_allocator_,branch[0]);
40790 details::free_node(*node_allocator_,branch[1]);
40791
40792 return synthesize_str_xrox_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0);
40793 }
40794
40795 inline expression_node_ptr synthesize_srocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40796 {
40797 std::string& s0 = static_cast<details::string_range_node<Type>* >(branch[0])->ref ();
40798 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40799 range_t rp0 = static_cast<details::string_range_node<Type>* >(branch[0])->range();
40800 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40801
40802 static_cast<details::string_range_node<Type>*> (branch[0])->range_ref().clear();
40803 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40804
40805 details::free_node(*node_allocator_,branch[0]);
40806 details::free_node(*node_allocator_,branch[1]);
40807
40808 return synthesize_str_xroxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0, rp1);
40809 }
40810
40811 inline expression_node_ptr synthesize_csocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40812 {
40813 const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
40814 const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
40815
40816 expression_node_ptr result = error_node();
40817
40818 if (details::e_add == opr)
40819 result = node_allocator_->allocate_c<details::string_literal_node<Type> >(s0 + s1);
40820 else if (details::e_in == opr)
40821 result = node_allocator_->allocate_c<details::literal_node<Type> >(details::in_op <Type>::process(s0,s1));
40822 else if (details::e_like == opr)
40823 result = node_allocator_->allocate_c<details::literal_node<Type> >(details::like_op <Type>::process(s0,s1));
40824 else if (details::e_ilike == opr)
40825 result = node_allocator_->allocate_c<details::literal_node<Type> >(details::ilike_op<Type>::process(s0,s1));
40826 else
40827 {
40828 expression_node_ptr temp = synthesize_sos_expression_impl<const std::string, const std::string>(opr, s0, s1);
40829
40830 const Type v = temp->value();
40831
40832 details::free_node(*node_allocator_,temp);
40833
40834 result = node_allocator_->allocate<literal_node_t>(v);
40835 }
40836
40837 details::free_all_nodes(*node_allocator_,branch);
40838
40839 return result;
40840 }
40841
40842 inline expression_node_ptr synthesize_csocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40843 {
40844 const std::string s0 = static_cast<details::string_literal_node<Type>* >(branch[0])->str ();
40845 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40846 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40847
40848 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40849
40850 details::free_node(*node_allocator_,branch[0]);
40851 details::free_node(*node_allocator_,branch[1]);
40852
40853 return synthesize_str_xoxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp1);
40854 }
40855
40856 inline expression_node_ptr synthesize_csros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40857 {
40858 std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40859 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref ();
40860 range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40861
40862 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40863
40864 details::free_node(*node_allocator_,branch[0]);
40865
40866 return synthesize_str_xrox_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0);
40867 }
40868
40869 inline expression_node_ptr synthesize_csrosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40870 {
40871 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40872 std::string& s1 = static_cast<details::string_range_node<Type>* >(branch[1])->ref ();
40873 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40874 const range_t rp1 = static_cast<details::string_range_node<Type>* >(branch[1])->range();
40875
40876 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40877 static_cast<details::string_range_node<Type>*> (branch[1])->range_ref().clear();
40878
40879 details::free_node(*node_allocator_,branch[0]);
40880 details::free_node(*node_allocator_,branch[1]);
40881
40882 return synthesize_str_xroxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0, rp1);
40883 }
40884
40885 inline expression_node_ptr synthesize_csrocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40886 {
40887 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40888 const std::string s1 = static_cast<details::string_literal_node<Type>* >(branch[1])->str ();
40889 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40890
40891 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40892
40893 details::free_all_nodes(*node_allocator_,branch);
40894
40895 return synthesize_str_xrox_expression_impl<const std::string,std::string>(opr, s0, s1, rp0);
40896 }
40897
40898 inline expression_node_ptr synthesize_csrocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40899 {
40900 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40901 const std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40902 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40903 const range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40904
40905 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40906 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40907
40908 details::free_all_nodes(*node_allocator_,branch);
40909
40910 return synthesize_str_xroxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp0, rp1);
40911 }
40912
40913 inline expression_node_ptr synthesize_strogen_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40914 {
40915 switch (opr)
40916 {
40917 #define case_stmt(op0, op1) \
40918 case op0 : return node_allocator_-> \
40919 allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > > \
40920 (opr, branch[0], branch[1]); \
40921
40923 #undef case_stmt
40924 default : return error_node();
40925 }
40926 }
40927
40928 #undef string_opr_switch_statements
40929 #endif
40930
40931 #ifndef exprtk_disable_string_capabilities
40932 inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40933 {
40934 if ((0 == branch[0]) || (0 == branch[1]))
40935 {
40936 details::free_all_nodes(*node_allocator_,branch);
40937
40938 return error_node();
40939 }
40940
40941 const bool b0_is_s = details::is_string_node (branch[0]);
40942 const bool b0_is_cs = details::is_const_string_node (branch[0]);
40943 const bool b0_is_sr = details::is_string_range_node (branch[0]);
40944 const bool b0_is_csr = details::is_const_string_range_node(branch[0]);
40945
40946 const bool b1_is_s = details::is_string_node (branch[1]);
40947 const bool b1_is_cs = details::is_const_string_node (branch[1]);
40948 const bool b1_is_sr = details::is_string_range_node (branch[1]);
40949 const bool b1_is_csr = details::is_const_string_range_node(branch[1]);
40950
40951 const bool b0_is_gen = details::is_string_assignment_node (branch[0]) ||
40952 details::is_genricstring_range_node(branch[0]) ||
40953 details::is_string_concat_node (branch[0]) ||
40954 details::is_string_function_node (branch[0]) ||
40955 details::is_string_condition_node (branch[0]) ||
40956 details::is_string_ccondition_node (branch[0]) ||
40957 details::is_string_vararg_node (branch[0]) ;
40958
40959 const bool b1_is_gen = details::is_string_assignment_node (branch[1]) ||
40960 details::is_genricstring_range_node(branch[1]) ||
40961 details::is_string_concat_node (branch[1]) ||
40962 details::is_string_function_node (branch[1]) ||
40963 details::is_string_condition_node (branch[1]) ||
40964 details::is_string_ccondition_node (branch[1]) ||
40965 details::is_string_vararg_node (branch[1]) ;
40966
40967 if (details::e_add == opr)
40968 {
40969 if (!b0_is_cs || !b1_is_cs)
40970 {
40971 return synthesize_expression<string_concat_node_t,2>(opr,branch);
40972 }
40973 }
40974
40975 if (b0_is_gen || b1_is_gen)
40976 {
40977 return synthesize_strogen_expression(opr,branch);
40978 }
40979 else if (b0_is_s)
40980 {
40981 if (b1_is_s ) return synthesize_sos_expression (opr,branch);
40982 else if (b1_is_cs ) return synthesize_socs_expression (opr,branch);
40983 else if (b1_is_sr ) return synthesize_sosr_expression (opr,branch);
40984 else if (b1_is_csr) return synthesize_socsr_expression (opr,branch);
40985 }
40986 else if (b0_is_cs)
40987 {
40988 if (b1_is_s ) return synthesize_csos_expression (opr,branch);
40989 else if (b1_is_cs ) return synthesize_csocs_expression (opr,branch);
40990 else if (b1_is_sr ) return synthesize_csosr_expression (opr,branch);
40991 else if (b1_is_csr) return synthesize_csocsr_expression(opr,branch);
40992 }
40993 else if (b0_is_sr)
40994 {
40995 if (b1_is_s ) return synthesize_sros_expression (opr,branch);
40996 else if (b1_is_sr ) return synthesize_srosr_expression (opr,branch);
40997 else if (b1_is_cs ) return synthesize_srocs_expression (opr,branch);
40998 else if (b1_is_csr) return synthesize_srocsr_expression(opr,branch);
40999 }
41000 else if (b0_is_csr)
41001 {
41002 if (b1_is_s ) return synthesize_csros_expression (opr,branch);
41003 else if (b1_is_sr ) return synthesize_csrosr_expression (opr,branch);
41004 else if (b1_is_cs ) return synthesize_csrocs_expression (opr,branch);
41005 else if (b1_is_csr) return synthesize_csrocsr_expression(opr,branch);
41006 }
41007
41008 return error_node();
41009 }
41010 #else
41011 inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[2])
41012 {
41013 details::free_all_nodes(*node_allocator_,branch);
41014 return error_node();
41015 }
41016 #endif
41017
41018 #ifndef exprtk_disable_string_capabilities
41019 inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[3])
41020 {
41021 if (details::e_inrange != opr)
41022 return error_node();
41023 else if ((0 == branch[0]) || (0 == branch[1]) || (0 == branch[2]))
41024 {
41025 details::free_all_nodes(*node_allocator_,branch);
41026
41027 return error_node();
41028 }
41029 else if (
41030 details::is_const_string_node(branch[0]) &&
41031 details::is_const_string_node(branch[1]) &&
41032 details::is_const_string_node(branch[2])
41033 )
41034 {
41035 const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
41036 const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
41037 const std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
41038
41039 const Type v = (((s0 <= s1) && (s1 <= s2)) ? Type(1) : Type(0));
41040
41041 details::free_all_nodes(*node_allocator_,branch);
41042
41043 return node_allocator_->allocate_c<details::literal_node<Type> >(v);
41044 }
41045 else if (
41046 details::is_string_node(branch[0]) &&
41047 details::is_string_node(branch[1]) &&
41048 details::is_string_node(branch[2])
41049 )
41050 {
41051 std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
41052 std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
41053 std::string& s2 = static_cast<details::stringvar_node<Type>*>(branch[2])->ref();
41054
41055 typedef typename details::sosos_node<Type, std::string&, std::string&, std::string&, details::inrange_op<Type> > inrange_t;
41056
41057 return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string&>(s0, s1, s2);
41058 }
41059 else if (
41060 details::is_const_string_node(branch[0]) &&
41061 details::is_string_node(branch[1]) &&
41062 details::is_const_string_node(branch[2])
41063 )
41064 {
41065 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
41066 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
41067 std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
41068
41069 typedef typename details::sosos_node<Type, std::string, std::string&, std::string, details::inrange_op<Type> > inrange_t;
41070
41071 details::free_node(*node_allocator_,branch[0]);
41072 details::free_node(*node_allocator_,branch[2]);
41073
41074 return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string>(s0, s1, s2);
41075 }
41076 else if (
41077 details::is_string_node(branch[0]) &&
41078 details::is_const_string_node(branch[1]) &&
41079 details::is_string_node(branch[2])
41080 )
41081 {
41082 std::string& s0 = static_cast<details::stringvar_node<Type>* >(branch[0])->ref();
41083 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
41084 std::string& s2 = static_cast<details::stringvar_node<Type>* >(branch[2])->ref();
41085
41086 typedef typename details::sosos_node<Type, std::string&, std::string, std::string&, details::inrange_op<Type> > inrange_t;
41087
41088 details::free_node(*node_allocator_,branch[1]);
41089
41090 return node_allocator_->allocate_type<inrange_t, std::string&, std::string, std::string&>(s0, s1, s2);
41091 }
41092 else if (
41093 details::is_string_node(branch[0]) &&
41094 details::is_string_node(branch[1]) &&
41095 details::is_const_string_node(branch[2])
41096 )
41097 {
41098 std::string& s0 = static_cast<details::stringvar_node<Type>* >(branch[0])->ref();
41099 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
41100 std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
41101
41102 typedef typename details::sosos_node<Type, std::string&, std::string&, std::string, details::inrange_op<Type> > inrange_t;
41103
41104 details::free_node(*node_allocator_,branch[2]);
41105
41106 return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string>(s0, s1, s2);
41107 }
41108 else if (
41109 details::is_const_string_node(branch[0]) &&
41110 details:: is_string_node(branch[1]) &&
41111 details:: is_string_node(branch[2])
41112 )
41113 {
41114 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
41115 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
41116 std::string& s2 = static_cast<details::stringvar_node<Type>* >(branch[2])->ref();
41117
41118 typedef typename details::sosos_node<Type, std::string, std::string&, std::string&, details::inrange_op<Type> > inrange_t;
41119
41120 details::free_node(*node_allocator_,branch[0]);
41121
41122 return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string&>(s0, s1, s2);
41123 }
41124 else
41125 return error_node();
41126 }
41127 #else
41128 inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[3])
41129 {
41130 details::free_all_nodes(*node_allocator_,branch);
41131 return error_node();
41132 }
41133 #endif
41134
41135 inline expression_node_ptr synthesize_null_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
41136 {
41137
41138
41139
41140
41141
41142
41143
41144
41145
41146
41147
41148 typedef typename details::null_eq_node<T> nulleq_node_t;
41149
41150 const bool b0_null = details::is_null_node(branch[0]);
41151 const bool b1_null = details::is_null_node(branch[1]);
41152
41153 if (b0_null && b1_null)
41154 {
41155 expression_node_ptr result = error_node();
41156
41157 if (details::e_eq == operation)
41158 result = node_allocator_->allocate_c<literal_node_t>(T(1));
41159 else if (details::e_ne == operation)
41160 result = node_allocator_->allocate_c<literal_node_t>(T(0));
41161
41162 if (result)
41163 {
41164 details::free_node(*node_allocator_,branch[0]);
41165 details::free_node(*node_allocator_,branch[1]);
41166
41167 return result;
41168 }
41169
41170 details::free_node(*node_allocator_,branch[1]);
41171
41172 return branch[0];
41173 }
41174 else if (details::e_eq == operation)
41175 {
41176 expression_node_ptr result = node_allocator_->
41177 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],true);
41178
41179 details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
41180
41181 return result;
41182 }
41183 else if (details::e_ne == operation)
41184 {
41185 expression_node_ptr result = node_allocator_->
41186 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],false);
41187
41188 details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
41189
41190 return result;
41191 }
41192 else if (b0_null)
41193 {
41194 details::free_node(*node_allocator_,branch[0]);
41195 branch[0] = branch[1];
41196 branch[1] = error_node();
41197 }
41198 else if (b1_null)
41199 {
41200 details::free_node(*node_allocator_,branch[1]);
41201 branch[1] = error_node();
41202 }
41203
41204 if (
41205 (details::e_add == operation) || (details::e_sub == operation) ||
41206 (details::e_mul == operation) || (details::e_div == operation) ||
41207 (details::e_mod == operation) || (details::e_pow == operation)
41208 )
41209 {
41210 return branch[0];
41211 }
41212
41213 details::free_node(*node_allocator_, branch[0]);
41214
41215 if (
41216 (details::e_lt == operation) || (details::e_lte == operation) ||
41217 (details::e_gt == operation) || (details::e_gte == operation) ||
41218 (details::e_and == operation) || (details::e_nand == operation) ||
41219 (details::e_or == operation) || (details::e_nor == operation) ||
41220 (details::e_xor == operation) || (details::e_xnor == operation) ||
41221 (details::e_in == operation) || (details::e_like == operation) ||
41222 (details::e_ilike == operation)
41223 )
41224 {
41225 return node_allocator_->allocate_c<literal_node_t>(T(0));
41226 }
41227
41228 return node_allocator_->allocate<details::null_node<Type> >();
41229 }
41230
41231 template <typename NodeType, std::size_t N>
41232 inline expression_node_ptr synthesize_expression(const details::operator_type& operation, expression_node_ptr (&branch)[N])
41233 {
41234 if (
41235 (details::e_in == operation) ||
41236 (details::e_like == operation) ||
41237 (details::e_ilike == operation)
41238 )
41239 {
41241
41242 return error_node();
41243 }
41244 else if (!details::all_nodes_valid<N>(branch))
41245 {
41247
41248 return error_node();
41249 }
41250 else if ((details::e_default != operation))
41251 {
41252
41253 expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(operation,branch);
41254
41255 if (is_constant_foldable<N>(branch))
41256 {
41257 const Type v = expression_point->value();
41258 details::free_node(*node_allocator_,expression_point);
41259
41260 return node_allocator_->allocate<literal_node_t>(v);
41261 }
41262
41263 if (expression_point && expression_point->valid())
41264 {
41265 return expression_point;
41266 }
41267
41268 parser_->set_error(parser_error::make_error(
41269 parser_error::e_parser,
41270 token_t(),
41271 "ERR273 - Failed to synthesize node: NodeType",
41273
41274 details::free_node(*node_allocator_, expression_point);
41275 }
41276
41277 return error_node();
41278 }
41279
41280 template <typename NodeType, std::size_t N>
41281 inline expression_node_ptr synthesize_expression(F* f, expression_node_ptr (&branch)[N])
41282 {
41283 if (!details::all_nodes_valid<N>(branch))
41284 {
41286
41287 return error_node();
41288 }
41289
41290 typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
41291
41292
41293
41294 expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
41295 function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(expression_point);
41296
41297 if (0 == func_node_ptr)
41298 {
41300
41301 return error_node();
41302 }
41303 else
41304 func_node_ptr->init_branches(branch);
41305
41306 if (is_constant_foldable<N>(branch) && !f->has_side_effects())
41307 {
41308 Type v = expression_point->value();
41309 details::free_node(*node_allocator_,expression_point);
41310
41311 return node_allocator_->allocate<literal_node_t>(v);
41312 }
41313
41314 parser_->state_.activate_side_effect("synthesize_expression(function<NT,N>)");
41315
41316 return expression_point;
41317 }
41318
41319 bool strength_reduction_enabled_;
41320 details::node_allocator* node_allocator_;
41321 synthesize_map_t synthesize_map_;
41322 unary_op_map_t* unary_op_map_;
41323 binary_op_map_t* binary_op_map_;
41324 inv_binary_op_map_t* inv_binary_op_map_;
41325 sf3_map_t* sf3_map_;
41326 sf4_map_t* sf4_map_;
41327 parser_t* parser_;
41328 };
41329
41330 inline void set_error(const parser_error::type& error_type)
41331 {
41332 error_list_.push_back(error_type);
41333 }
41334
41335 inline void remove_last_error()
41336 {
41337 if (!error_list_.empty())
41338 {
41339 error_list_.pop_back();
41340 }
41341 }
41342
41343 inline void set_synthesis_error(const std::string& synthesis_error_message)
41344 {
41345 if (synthesis_error_.empty())
41346 {
41347 synthesis_error_ = synthesis_error_message;
41348 }
41349 }
41350
41351 inline void register_local_vars(expression<T>& e)
41352 {
41353 for (std::size_t i = 0; i < sem_.size(); ++i)
41354 {
41355 scope_element& se = sem_.get_element(i);
41356
41357 exprtk_debug((
"register_local_vars() - se[%s]\n", se.name.c_str()));
41358
41359 if (
41360 (scope_element::e_variable == se.type) ||
41361 (scope_element::e_literal == se.type) ||
41362 (scope_element::e_vecelem == se.type)
41363 )
41364 {
41365 if (se.var_node)
41366 {
41367 e.register_local_var(se.var_node);
41368 }
41369
41370 if (se.data)
41371 {
41372 e.register_local_data(se.data, 1, 0);
41373 }
41374 }
41375 else if (scope_element::e_vector == se.type)
41376 {
41377 if (se.vec_node)
41378 {
41379 e.register_local_var(se.vec_node);
41380 }
41381
41382 if (se.data)
41383 {
41384 e.register_local_data(se.data, se.size, 1);
41385 }
41386 }
41387 #ifndef exprtk_disable_string_capabilities
41388 else if (scope_element::e_string == se.type)
41389 {
41390 if (se.str_node)
41391 {
41392 e.register_local_var(se.str_node);
41393 }
41394
41395 if (se.data)
41396 {
41397 e.register_local_data(se.data, se.size, 2);
41398 }
41399 }
41400 #endif
41401
41402 se.var_node = 0;
41403 se.vec_node = 0;
41404 #ifndef exprtk_disable_string_capabilities
41405 se.str_node = 0;
41406 #endif
41407 se.data = 0;
41408 se.ref_count = 0;
41409 se.active = false;
41410 }
41411 }
41412
41413 inline void register_return_results(expression<T>& e)
41414 {
41415 e.register_return_results(results_context_);
41416 results_context_ = 0;
41417 }
41418
41419 inline void load_unary_operations_map(unary_op_map_t& m)
41420 {
41421 #define register_unary_op(Op, UnaryFunctor) \
41422 m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \
41423
41463 #undef register_unary_op
41464 }
41465
41466 inline void load_binary_operations_map(binary_op_map_t& m)
41467 {
41468 typedef typename binary_op_map_t::value_type value_type;
41469
41470 #define register_binary_op(Op, BinaryFunctor) \
41471 m.insert(value_type(Op,BinaryFunctor<T>::process)); \
41472
41491 #undef register_binary_op
41492 }
41493
41494 inline void load_inv_binary_operations_map(inv_binary_op_map_t& m)
41495 {
41496 typedef typename inv_binary_op_map_t::value_type value_type;
41497
41498 #define register_binary_op(Op, BinaryFunctor) \
41499 m.insert(value_type(BinaryFunctor<T>::process,Op)); \
41500
41519 #undef register_binary_op
41520 }
41521
41522 inline void load_sf3_map(sf3_map_t& sf3_map)
41523 {
41524 typedef std::pair<trinary_functor_t,details::operator_type> pair_t;
41525
41526 #define register_sf3(Op) \
41527 sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
41528
41537 #undef register_sf3
41538
41539 #define register_sf3_extid(Id, Op) \
41540 sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
41541
41543 #undef register_sf3_extid
41544 }
41545
41546 inline void load_sf4_map(sf4_map_t& sf4_map)
41547 {
41548 typedef std::pair<quaternary_functor_t,details::operator_type> pair_t;
41549
41550 #define register_sf4(Op) \
41551 sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
41552
41562 #undef register_sf4
41563
41564 #define register_sf4ext(Op) \
41565 sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \
41566
41583 #undef register_sf4ext
41584 }
41585
41586 inline results_context_t& results_ctx()
41587 {
41588 if (0 == results_context_)
41589 {
41590 results_context_ = new results_context_t();
41591 }
41592
41593 return (*results_context_);
41594 }
41595
41596 inline void return_cleanup()
41597 {
41598 #ifndef exprtk_disable_return_statement
41599 if (results_context_)
41600 {
41601 delete results_context_;
41602 results_context_ = 0;
41603 }
41604
41605 state_.return_stmt_present = false;
41606 #endif
41607 }
41608
41609 private:
41610
41613
41614 settings_store settings_;
41615 expression_generator<T> expression_generator_;
41616 details::node_allocator node_allocator_;
41617 symtab_store symtab_store_;
41618 dependent_entity_collector dec_;
41619 std::deque<parser_error::type> error_list_;
41620 std::deque<bool> brkcnt_list_;
41621 parser_state state_;
41622 bool resolve_unknown_symbol_;
41623 results_context_t* results_context_;
41624 unknown_symbol_resolver* unknown_symbol_resolver_;
41625 unknown_symbol_resolver default_usr_;
41626 base_ops_map_t base_ops_map_;
41627 unary_op_map_t unary_op_map_;
41628 binary_op_map_t binary_op_map_;
41629 inv_binary_op_map_t inv_binary_op_map_;
41630 sf3_map_t sf3_map_;
41631 sf4_map_t sf4_map_;
41632 std::string synthesis_error_;
41633 scope_element_manager sem_;
41634 std::vector<state_t> current_state_stack_;
41635
41636 immutable_memory_map_t immutable_memory_map_;
41637 immutable_symtok_map_t immutable_symtok_map_;
41638
41639 lexer::helper::helper_assembly helper_assembly_;
41640
41641 lexer::helper::commutative_inserter commutative_inserter_;
41642 lexer::helper::operator_joiner operator_joiner_2_;
41643 lexer::helper::operator_joiner operator_joiner_3_;
41644 lexer::helper::symbol_replacer symbol_replacer_;
41645 lexer::helper::bracket_checker bracket_checker_;
41646 lexer::helper::numeric_checker<T> numeric_checker_;
41647 lexer::helper::sequence_validator sequence_validator_;
41648 lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_;
41649
41654 std::set<std::string> assert_ids_;
41655
41656 template <typename ParserType>
41657 friend void details::disable_type_checking(ParserType& p);
41658 };
41659
41660 namespace details
41661 {
41662 template <typename T>
41663 struct collector_helper
41664 {
41668 typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
41669 typedef typename parser_t::unknown_symbol_resolver usr_t;
41670
41671 struct resolve_as_vector : public usr_t
41672 {
41674
41675 using usr_t::process;
41676
41677 resolve_as_vector()
41678 : usr_t(usr_t::e_usrmode_extended)
41679 {}
41680
41681 virtual bool process(
const std::string& unknown_symbol,
41682 symbol_table_t& symbol_table,
41684 {
41685 static T v[1];
41686 symbol_table.add_vector(unknown_symbol,v);
41687 return true;
41688 }
41689 };
41690
41691 static inline bool collection_pass(const std::string& expression_string,
41692 std::set<std::string>& symbol_set,
41693 const bool collect_variables,
41694 const bool collect_functions,
41695 const bool vector_pass,
41696 symbol_table_t& ext_symbol_table)
41697 {
41698 symbol_table_t symbol_table;
41699 expression_t expression;
41700 parser_t parser;
41701
41702 resolve_as_vector vect_resolver;
41703
41704 expression.register_symbol_table(symbol_table );
41705 expression.register_symbol_table(ext_symbol_table);
41706
41707 if (vector_pass)
41708 parser.enable_unknown_symbol_resolver(&vect_resolver);
41709 else
41710 parser.enable_unknown_symbol_resolver();
41711
41712 if (collect_variables)
41713 parser.dec().collect_variables() = true;
41714
41715 if (collect_functions)
41716 parser.dec().collect_functions() = true;
41717
41718 bool pass_result = false;
41719
41720 details::disable_type_checking(parser);
41721
41722 if (parser.compile(expression_string, expression))
41723 {
41724 pass_result = true;
41725
41726 std::deque<symbol_t> symb_list;
41727 parser.dec().symbols(symb_list);
41728
41729 for (std::size_t i = 0; i < symb_list.size(); ++i)
41730 {
41731 symbol_set.insert(symb_list[i].first);
41732 }
41733 }
41734
41735 return pass_result;
41736 }
41737 };
41738 }
41739
41740 template <typename Allocator,
41741 template <typename, typename> class Sequence>
41743 Sequence<std::string, Allocator>& symbol_list)
41744 {
41745 typedef double T;
41746 typedef details::collector_helper<T> collect_t;
41747
41748 collect_t::symbol_table_t null_symbol_table;
41749
41750 std::set<std::string> symbol_set;
41751
41752 const bool variable_pass = collect_t::collection_pass
41753 (expression, symbol_set, true, false, false, null_symbol_table);
41754 const bool vector_pass = collect_t::collection_pass
41755 (expression, symbol_set, true, false, true, null_symbol_table);
41756
41757 if (!variable_pass && !vector_pass)
41758 return false;
41759
41760 std::set<std::string>::iterator itr = symbol_set.begin();
41761
41762 while (symbol_set.end() != itr)
41763 {
41764 symbol_list.push_back(*itr);
41765 ++itr;
41766 }
41767
41768 return true;
41769 }
41770
41771 template <typename T,
41772 typename Allocator,
41773 template <typename, typename> class Sequence>
41776 Sequence<std::string, Allocator>& symbol_list)
41777 {
41778 typedef details::collector_helper<T> collect_t;
41779
41780 std::set<std::string> symbol_set;
41781
41782 const bool variable_pass = collect_t::collection_pass
41783 (expression, symbol_set, true, false, false, extrnl_symbol_table);
41784 const bool vector_pass = collect_t::collection_pass
41785 (expression, symbol_set, true, false, true, extrnl_symbol_table);
41786
41787 if (!variable_pass && !vector_pass)
41788 return false;
41789
41790 std::set<std::string>::iterator itr = symbol_set.begin();
41791
41792 while (symbol_set.end() != itr)
41793 {
41794 symbol_list.push_back(*itr);
41795 ++itr;
41796 }
41797
41798 return true;
41799 }
41800
41801 template <typename Allocator,
41802 template <typename, typename> class Sequence>
41804 Sequence<std::string, Allocator>& symbol_list)
41805 {
41806 typedef double T;
41807 typedef details::collector_helper<T> collect_t;
41808
41809 collect_t::symbol_table_t null_symbol_table;
41810
41811 std::set<std::string> symbol_set;
41812
41813 const bool variable_pass = collect_t::collection_pass
41814 (expression, symbol_set, false, true, false, null_symbol_table);
41815 const bool vector_pass = collect_t::collection_pass
41816 (expression, symbol_set, false, true, true, null_symbol_table);
41817
41818 if (!variable_pass && !vector_pass)
41819 return false;
41820
41821 std::set<std::string>::iterator itr = symbol_set.begin();
41822
41823 while (symbol_set.end() != itr)
41824 {
41825 symbol_list.push_back(*itr);
41826 ++itr;
41827 }
41828
41829 return true;
41830 }
41831
41832 template <typename T,
41833 typename Allocator,
41834 template <typename, typename> class Sequence>
41837 Sequence<std::string, Allocator>& symbol_list)
41838 {
41839 typedef details::collector_helper<T> collect_t;
41840
41841 std::set<std::string> symbol_set;
41842
41843 const bool variable_pass = collect_t::collection_pass
41844 (expression, symbol_set, false, true, false, extrnl_symbol_table);
41845 const bool vector_pass = collect_t::collection_pass
41846 (expression, symbol_set, false, true, true, extrnl_symbol_table);
41847
41848 if (!variable_pass && !vector_pass)
41849 return false;
41850
41851 std::set<std::string>::iterator itr = symbol_set.begin();
41852
41853 while (symbol_set.end() != itr)
41854 {
41855 symbol_list.push_back(*itr);
41856 ++itr;
41857 }
41858
41859 return true;
41860 }
41861
41862 template <typename T>
41863 inline T
integrate(
const expression<T>& e,
41864 T& x,
41865 const T& r0, const T& r1,
41866 const std::size_t number_of_intervals = 1000000)
41867 {
41868 if (r0 > r1)
41869 return T(0);
41870
41871 const T h = (r1 - r0) / (T(2) * number_of_intervals);
41872 T total_area = T(0);
41873
41874 for (std::size_t i = 0; i < number_of_intervals; ++i)
41875 {
41876 x = r0 + T(2) * i * h;
41877 const T y0 =
e.value(); x += h;
41878 const T y1 =
e.value(); x += h;
41879 const T y2 =
e.value(); x += h;
41880 total_area += h * (y0 + T(4) * y1 + y2) / T(3);
41881 }
41882
41883 return total_area;
41884 }
41885
41886 template <typename T>
41887 inline T
integrate(
const expression<T>& e,
41888 const std::string& variable_name,
41889 const T& r0, const T& r1,
41890 const std::size_t number_of_intervals = 1000000)
41891 {
41892 const symbol_table<T>& sym_table =
e.get_symbol_table();
41893
41894 if (!sym_table.valid())
41895 {
41896 return std::numeric_limits<T>::quiet_NaN();
41897 }
41898
41899 details::variable_node<T>* var = sym_table.get_variable(variable_name);
41900
41901 if (var)
41902 {
41903 T& x = var->ref();
41904 const T x_original = x;
41905 const T result =
integrate(e, x, r0, r1, number_of_intervals);
41906 x = x_original;
41907
41908 return result;
41909 }
41910
41911 return std::numeric_limits<T>::quiet_NaN();
41912 }
41913
41914 template <typename T>
41916 T& x,
41917 const T& h = T(0.00000001))
41918 {
41919 const T x_init = x;
41920 const T _2h = T(2) * h;
41921
41922 x = x_init + _2h;
41923 const T y0 =
e.value();
41924 x = x_init + h;
41925 const T y1 =
e.value();
41926 x = x_init - h;
41927 const T y2 =
e.value();
41928 x = x_init - _2h;
41929 const T y3 =
e.value();
41930 x = x_init;
41931
41932 return (-y0 + T(8) * (y1 - y2) + y3) / (T(12) * h);
41933 }
41934
41935 template <typename T>
41937 T& x,
41938 const T& h = T(0.00001))
41939 {
41940 const T x_init = x;
41941 const T _2h = T(2) * h;
41942
41943 const T y =
e.value();
41944 x = x_init + _2h;
41945 const T y0 =
e.value();
41946 x = x_init + h;
41947 const T y1 =
e.value();
41948 x = x_init - h;
41949 const T y2 =
e.value();
41950 x = x_init - _2h;
41951 const T y3 =
e.value();
41952 x = x_init;
41953
41954 return (-y0 + T(16) * (y1 + y2) - T(30) * y - y3) / (T(12) * h * h);
41955 }
41956
41957 template <typename T>
41959 T& x,
41960 const T& h = T(0.0001))
41961 {
41962 const T x_init = x;
41963 const T _2h = T(2) * h;
41964
41965 x = x_init + _2h;
41966 const T y0 =
e.value();
41967 x = x_init + h;
41968 const T y1 =
e.value();
41969 x = x_init - h;
41970 const T y2 =
e.value();
41971 x = x_init - _2h;
41972 const T y3 =
e.value();
41973 x = x_init;
41974
41975 return (y0 + T(2) * (y2 - y1) - y3) / (T(2) * h * h * h);
41976 }
41977
41978 template <typename T>
41980 const std::string& variable_name,
41981 const T& h = T(0.00000001))
41982 {
41983 const symbol_table<T>& sym_table =
e.get_symbol_table();
41984
41985 if (!sym_table.valid())
41986 {
41987 return std::numeric_limits<T>::quiet_NaN();
41988 }
41989
41990 details::variable_node<T>* var = sym_table.get_variable(variable_name);
41991
41992 if (var)
41993 {
41994 T& x = var->ref();
41995 const T x_original = x;
41997 x = x_original;
41998
41999 return result;
42000 }
42001
42002 return std::numeric_limits<T>::quiet_NaN();
42003 }
42004
42005 template <typename T>
42007 const std::string& variable_name,
42008 const T& h = T(0.00001))
42009 {
42010 const symbol_table<T>& sym_table =
e.get_symbol_table();
42011
42012 if (!sym_table.valid())
42013 {
42014 return std::numeric_limits<T>::quiet_NaN();
42015 }
42016
42017 details::variable_node<T>* var = sym_table.get_variable(variable_name);
42018
42019 if (var)
42020 {
42021 T& x = var->ref();
42022 const T x_original = x;
42024 x = x_original;
42025
42026 return result;
42027 }
42028
42029 return std::numeric_limits<T>::quiet_NaN();
42030 }
42031
42032 template <typename T>
42034 const std::string& variable_name,
42035 const T& h = T(0.0001))
42036 {
42037 const symbol_table<T>& sym_table =
e.get_symbol_table();
42038
42039 if (!sym_table.valid())
42040 {
42041 return std::numeric_limits<T>::quiet_NaN();
42042 }
42043
42044 details::variable_node<T>* var = sym_table.get_variable(variable_name);
42045
42046 if (var)
42047 {
42048 T& x = var->ref();
42049 const T x_original = x;
42051 x = x_original;
42052
42053 return result;
42054 }
42055
42056 return std::numeric_limits<T>::quiet_NaN();
42057 }
42058
42059
42060
42061
42062
42063
42064
42065
42066
42067
42068
42069 template <typename T>
42070 inline bool compute(
const std::string& expression_string, T& result)
42071 {
42072
42073 symbol_table<T> symbol_table;
42074 symbol_table.add_constants();
42075
42076 expression<T> expression;
42077 expression.register_symbol_table(symbol_table);
42078
42079 parser<T> parser;
42080
42081 if (parser.compile(expression_string,expression))
42082 {
42083 result = expression.value();
42084
42085 return true;
42086 }
42087 else
42088 return false;
42089 }
42090
42091 template <typename T>
42092 inline bool compute(
const std::string& expression_string,
42093 const T& x,
42094 T& result)
42095 {
42096
42097 static const std::string x_var("x");
42098
42099 symbol_table<T> symbol_table;
42100 symbol_table.add_constants();
42101 symbol_table.add_constant(x_var,x);
42102
42103 expression<T> expression;
42104 expression.register_symbol_table(symbol_table);
42105
42106 parser<T> parser;
42107
42108 if (parser.compile(expression_string,expression))
42109 {
42110 result = expression.value();
42111
42112 return true;
42113 }
42114 else
42115 return false;
42116 }
42117
42118 template <typename T>
42119 inline bool compute(
const std::string& expression_string,
42120 const T&x, const T& y,
42121 T& result)
42122 {
42123
42124 static const std::string x_var("x");
42125 static const std::string y_var("y");
42126
42127 symbol_table<T> symbol_table;
42128 symbol_table.add_constants();
42129 symbol_table.add_constant(x_var,x);
42130 symbol_table.add_constant(y_var,y);
42131
42132 expression<T> expression;
42133 expression.register_symbol_table(symbol_table);
42134
42135 parser<T> parser;
42136
42137 if (parser.compile(expression_string,expression))
42138 {
42139 result = expression.value();
42140
42141 return true;
42142 }
42143 else
42144 return false;
42145 }
42146
42147 template <typename T>
42148 inline bool compute(
const std::string& expression_string,
42149 const T& x, const T& y, const T& z,
42150 T& result)
42151 {
42152
42153 static const std::string x_var("x");
42154 static const std::string y_var("y");
42155 static const std::string z_var("z");
42156
42157 symbol_table<T> symbol_table;
42158 symbol_table.add_constants();
42159 symbol_table.add_constant(x_var,x);
42160 symbol_table.add_constant(y_var,y);
42161 symbol_table.add_constant(z_var,z);
42162
42163 expression<T> expression;
42164 expression.register_symbol_table(symbol_table);
42165
42166 parser<T> parser;
42167
42168 if (parser.compile(expression_string,expression))
42169 {
42170 result = expression.value();
42171
42172 return true;
42173 }
42174 else
42175 return false;
42176 }
42177
42178 template <typename T, std::size_t N>
42180 {
42181 private:
42182
42183 template <typename Type, std::size_t NumberOfCoefficients>
42184 struct poly_impl { };
42185
42186 template <typename Type>
42187 struct poly_impl <Type,12>
42188 {
42189 static inline T evaluate(const Type x,
42190 const Type c12, const Type c11, const Type c10, const Type c9, const Type c8,
42191 const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
42192 const Type c2, const Type c1, const Type c0)
42193 {
42194
42195 return ((((((((((((c12 * x + c11) * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42196 }
42197 };
42198
42199 template <typename Type>
42200 struct poly_impl <Type,11>
42201 {
42202 static inline T evaluate(const Type x,
42203 const Type c11, const Type c10, const Type c9, const Type c8, const Type c7,
42204 const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
42205 const Type c1, const Type c0)
42206 {
42207
42208 return (((((((((((c11 * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42209 }
42210 };
42211
42212 template <typename Type>
42213 struct poly_impl <Type,10>
42214 {
42215 static inline T evaluate(const Type x,
42216 const Type c10, const Type c9, const Type c8, const Type c7, const Type c6,
42217 const Type c5, const Type c4, const Type c3, const Type c2, const Type c1,
42218 const Type c0)
42219 {
42220
42221 return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42222 }
42223 };
42224
42225 template <typename Type>
42226 struct poly_impl <Type,9>
42227 {
42228 static inline T evaluate(const Type x,
42229 const Type c9, const Type c8, const Type c7, const Type c6, const Type c5,
42230 const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
42231 {
42232
42233 return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42234 }
42235 };
42236
42237 template <typename Type>
42238 struct poly_impl <Type,8>
42239 {
42240 static inline T evaluate(const Type x,
42241 const Type c8, const Type c7, const Type c6, const Type c5, const Type c4,
42242 const Type c3, const Type c2, const Type c1, const Type c0)
42243 {
42244
42245 return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42246 }
42247 };
42248
42249 template <typename Type>
42250 struct poly_impl <Type,7>
42251 {
42252 static inline T evaluate(const Type x,
42253 const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
42254 const Type c2, const Type c1, const Type c0)
42255 {
42256
42257 return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42258 }
42259 };
42260
42261 template <typename Type>
42262 struct poly_impl <Type,6>
42263 {
42264 static inline T evaluate(const Type x,
42265 const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
42266 const Type c1, const Type c0)
42267 {
42268
42269 return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42270 }
42271 };
42272
42273 template <typename Type>
42274 struct poly_impl <Type,5>
42275 {
42276 static inline T evaluate(const Type x,
42277 const Type c5, const Type c4, const Type c3, const Type c2,
42278 const Type c1, const Type c0)
42279 {
42280
42281 return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42282 }
42283 };
42284
42285 template <typename Type>
42286 struct poly_impl <Type,4>
42287 {
42288 static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
42289 {
42290
42291 return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0);
42292 }
42293 };
42294
42295 template <typename Type>
42296 struct poly_impl <Type,3>
42297 {
42298 static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
42299 {
42300
42301 return (((c3 * x + c2) * x + c1) * x + c0);
42302 }
42303 };
42304
42305 template <typename Type>
42306 struct poly_impl <Type,2>
42307 {
42308 static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
42309 {
42310
42311 return ((c2 * x + c1) * x + c0);
42312 }
42313 };
42314
42315 template <typename Type>
42316 struct poly_impl <Type,1>
42317 {
42318 static inline T evaluate(const Type x, const Type c1, const Type c0)
42319 {
42320
42321 return (c1 * x + c0);
42322 }
42323 };
42324
42325 public:
42326
42327 using ifunction<T>::operator();
42328
42330 : ifunction<T>((N+2 <= 20) ? (N + 2) :
std::numeric_limits<
std::size_t>::
max())
42331 {
42333 }
42334
42335 virtual ~polynomial()
42336 {}
42337
42338 #define poly_rtrn(NN) \
42339 return (NN != N) ? std::numeric_limits<T>::quiet_NaN() :
42340
42341 inline virtual T operator() (
const T& x,
const T& c1,
const T& c0)
exprtk_override
42342 {
42343 poly_rtrn(1) (poly_impl<T,1>::evaluate(x, c1, c0));
42344 }
42345
42346 inline virtual T operator() (
const T& x,
const T& c2,
const T& c1,
const T& c0)
exprtk_override
42347 {
42348 poly_rtrn(2) (poly_impl<T,2>::evaluate(x, c2, c1, c0));
42349 }
42350
42351 inline virtual T operator() (
const T& x,
const T& c3,
const T& c2,
const T& c1,
const T& c0)
exprtk_override
42352 {
42353 poly_rtrn(3) (poly_impl<T,3>::evaluate(x, c3, c2, c1, c0));
42354 }
42355
42356 inline virtual T operator() (const T& x, const T& c4, const T& c3, const T& c2, const T& c1,
42358 {
42359 poly_rtrn(4) (poly_impl<T,4>::evaluate(x, c4, c3, c2, c1, c0));
42360 }
42361
42362 inline virtual T operator() (const T& x, const T& c5, const T& c4, const T& c3, const T& c2,
42364 {
42365 poly_rtrn(5) (poly_impl<T,5>::evaluate(x, c5, c4, c3, c2, c1, c0));
42366 }
42367
42368 inline virtual T operator() (const T& x, const T& c6, const T& c5, const T& c4, const T& c3,
42370 {
42371 poly_rtrn(6) (poly_impl<T,6>::evaluate(x, c6, c5, c4, c3, c2, c1, c0));
42372 }
42373
42374 inline virtual T operator() (const T& x, const T& c7, const T& c6, const T& c5, const T& c4,
42376 {
42377 poly_rtrn(7) (poly_impl<T,7>::evaluate(x, c7, c6, c5, c4, c3, c2, c1, c0));
42378 }
42379
42380 inline virtual T operator() (const T& x, const T& c8, const T& c7, const T& c6, const T& c5,
42381 const T& c4,
const T& c3,
const T& c2,
const T& c1,
const T& c0)
exprtk_override
42382 {
42383 poly_rtrn(8) (poly_impl<T,8>::evaluate(x, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42384 }
42385
42386 inline virtual T operator() (const T& x, const T& c9, const T& c8, const T& c7, const T& c6,
42387 const T& c5, const T& c4, const T& c3, const T& c2, const T& c1,
42389 {
42390 poly_rtrn(9) (poly_impl<T,9>::evaluate(x, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42391 }
42392
42393 inline virtual T operator() (const T& x, const T& c10, const T& c9, const T& c8, const T& c7,
42394 const T& c6, const T& c5, const T& c4, const T& c3, const T& c2,
42396 {
42397 poly_rtrn(10) (poly_impl<T,10>::evaluate(x, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42398 }
42399
42400 inline virtual T operator() (const T& x, const T& c11, const T& c10, const T& c9, const T& c8,
42401 const T& c7, const T& c6, const T& c5, const T& c4, const T& c3,
42403 {
42404 poly_rtrn(11) (poly_impl<T,11>::evaluate(x, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42405 }
42406
42407 inline virtual T operator() (const T& x, const T& c12, const T& c11, const T& c10, const T& c9,
42408 const T& c8, const T& c7, const T& c6, const T& c5, const T& c4,
42410 {
42411 poly_rtrn(12) (poly_impl<T,12>::evaluate(x, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42412 }
42413
42414 #undef poly_rtrn
42415
42417 {
42418 return std::numeric_limits<T>::quiet_NaN();
42419 }
42420
42422 {
42423 return std::numeric_limits<T>::quiet_NaN();
42424 }
42425
42427 {
42428 return std::numeric_limits<T>::quiet_NaN();
42429 }
42430 };
42431
42432 template <typename T>
42433 class function_compositor
42434 {
42435 public:
42436
42440 typedef typename parser_t::settings_store settings_t;
42441
42442 struct function
42443 {
42444 function()
42445 {}
42446
42447 function(const std::string& n)
42448 : name_(n)
42449 {}
42450
42451 function(const std::string& name,
42452 const std::string& expression)
42453 : name_(name)
42454 , expression_(expression)
42455 {}
42456
42457 function(const std::string& name,
42458 const std::string& expression,
42459 const std::string& v0)
42460 : name_(name)
42461 , expression_(expression)
42462 {
42463 v_.push_back(v0);
42464 }
42465
42466 function(const std::string& name,
42467 const std::string& expression,
42468 const std::string& v0, const std::string& v1)
42469 : name_(name)
42470 , expression_(expression)
42471 {
42472 v_.push_back(v0); v_.push_back(v1);
42473 }
42474
42475 function(const std::string& name,
42476 const std::string& expression,
42477 const std::string& v0, const std::string& v1,
42478 const std::string& v2)
42479 : name_(name)
42480 , expression_(expression)
42481 {
42482 v_.push_back(v0); v_.push_back(v1);
42483 v_.push_back(v2);
42484 }
42485
42486 function(const std::string& name,
42487 const std::string& expression,
42488 const std::string& v0, const std::string& v1,
42489 const std::string& v2, const std::string& v3)
42490 : name_(name)
42491 , expression_(expression)
42492 {
42493 v_.push_back(v0); v_.push_back(v1);
42494 v_.push_back(v2); v_.push_back(v3);
42495 }
42496
42497 function(const std::string& name,
42498 const std::string& expression,
42499 const std::string& v0, const std::string& v1,
42500 const std::string& v2, const std::string& v3,
42501 const std::string& v4)
42502 : name_(name)
42503 , expression_(expression)
42504 {
42505 v_.push_back(v0); v_.push_back(v1);
42506 v_.push_back(v2); v_.push_back(v3);
42507 v_.push_back(v4);
42508 }
42509
42510 inline function& name(const std::string& n)
42511 {
42512 name_ = n;
42513 return (*this);
42514 }
42515
42516 inline function& expression(const std::string& e)
42517 {
42519 return (*this);
42520 }
42521
42522 inline function& var(const std::string& v)
42523 {
42524 v_.push_back(v);
42525 return (*this);
42526 }
42527
42528 inline function& vars(const std::string& v0,
42529 const std::string& v1)
42530 {
42531 v_.push_back(v0);
42532 v_.push_back(v1);
42533 return (*this);
42534 }
42535
42536 inline function& vars(const std::string& v0,
42537 const std::string& v1,
42538 const std::string& v2)
42539 {
42540 v_.push_back(v0);
42541 v_.push_back(v1);
42542 v_.push_back(v2);
42543 return (*this);
42544 }
42545
42546 inline function& vars(const std::string& v0,
42547 const std::string& v1,
42548 const std::string& v2,
42549 const std::string& v3)
42550 {
42551 v_.push_back(v0);
42552 v_.push_back(v1);
42553 v_.push_back(v2);
42554 v_.push_back(v3);
42555 return (*this);
42556 }
42557
42558 inline function& vars(const std::string& v0,
42559 const std::string& v1,
42560 const std::string& v2,
42561 const std::string& v3,
42562 const std::string& v4)
42563 {
42564 v_.push_back(v0);
42565 v_.push_back(v1);
42566 v_.push_back(v2);
42567 v_.push_back(v3);
42568 v_.push_back(v4);
42569 return (*this);
42570 }
42571
42572 std::string name_;
42573 std::string expression_;
42574 std::deque<std::string> v_;
42575 };
42576
42577 private:
42578
42580 {
42581 typedef const T& type;
42583 typedef std::vector<T*> varref_t;
42584 typedef std::vector<T> var_t;
42585 typedef std::vector<std::string> str_t;
42586 typedef std::pair<T*,std::size_t> lvarref_t;
42587 typedef std::vector<lvarref_t> lvr_vec_t;
42588 typedef std::vector<std::string*> lstr_vec_t;
42589
42591
42593 :
exprtk::ifunction<T>(pc)
42594 , local_var_stack_size(0)
42595 , stack_depth(0)
42596 {
42597 v.resize(pc);
42598 }
42599
42601 {}
42602
42603 #define exprtk_assign(Index) \
42604 (*v[Index]) = v##Index; \
42605
42606 inline void update(const T& v0)
42607 {
42609 }
42610
42611 inline void update(const T& v0, const T& v1)
42612 {
42614 }
42615
42616 inline void update(const T& v0, const T& v1, const T& v2)
42617 {
42620 }
42621
42622 inline void update(const T& v0, const T& v1, const T& v2, const T& v3)
42623 {
42626 }
42627
42628 inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
42629 {
42633 }
42634
42635 inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
42636 {
42640 }
42641
42642 #ifdef exprtk_assign
42643 #undef exprtk_assign
42644 #endif
42645
42646 inline function_t& setup(expression_t& expr)
42647 {
42648 expression = expr;
42649
42650 typedef typename expression_t::control_block ctrlblk_t;
42651 typedef typename ctrlblk_t::local_data_list_t ldl_t;
42652 typedef typename ctrlblk_t::data_type data_t;
42653 typedef typename ldl_t::value_type ldl_value_type;
42654
42655 const ldl_t ldl = expr.local_data_list();
42656
42657 std::vector<std::pair<std::size_t,data_t> > index_list;
42658
42659 for (std::size_t i = 0; i < ldl.size(); ++i)
42660 {
42661 exprtk_debug((
"base_func::setup() - element[%02d] type: %s size: %d\n",
42662 static_cast<int>(i),
42663 expression_t::control_block::to_str(ldl[i].type).c_str(),
42664 static_cast<int>(ldl[i].size)));
42665
42666 switch (ldl[i].type)
42667 {
42668 case ctrlblk_t::e_unknown : continue;
42669 case ctrlblk_t::e_expr : continue;
42670 case ctrlblk_t::e_vecholder : continue;
42671 default : break;
42672 }
42673
42674 if (ldl[i].size)
42675 {
42676 index_list.push_back(std::make_pair(i,ldl[i].type));
42677 }
42678 }
42679
42680 std::size_t input_param_count = 0;
42681
42682 for (std::size_t i = 0; i < index_list.size(); ++i)
42683 {
42684 const std::size_t index = index_list[i].first;
42685 const ldl_value_type& local_var = ldl[index];
42686
42687 assert(local_var.pointer);
42688
42689 if (i < (index_list.size() - v.size()))
42690 {
42691 if (local_var.type == ctrlblk_t::e_string)
42692 {
42693 local_str_vars.push_back(
42694 reinterpret_cast<std::string*>(local_var.pointer));
42695 }
42696 else if (
42697 (local_var.type == ctrlblk_t::e_data ) ||
42698 (local_var.type == ctrlblk_t::e_vecdata)
42699 )
42700 {
42701 local_vars.push_back(std::make_pair(
42702 reinterpret_cast<T*>(local_var.pointer),
42703 local_var.size));
42704
42705 local_var_stack_size += local_var.size;
42706 }
42707 }
42708 else
42709 {
42710 v[input_param_count++] = reinterpret_cast<T*>(local_var.pointer);
42711 }
42712 }
42713
42714 clear_stack();
42715
42716 return (*this);
42717 }
42718
42719 inline void pre()
42720 {
42721 if (stack_depth++)
42722 {
42723 if (!v.empty())
42724 {
42725 var_t var_stack(v.size(),T(0));
42726 copy(v,var_stack);
42727 input_params_stack.push_back(var_stack);
42728 }
42729
42730 if (!local_vars.empty())
42731 {
42732 var_t local_vec_frame(local_var_stack_size,T(0));
42733 copy(local_vars,local_vec_frame);
42734 local_var_stack.push_back(local_vec_frame);
42735 }
42736
42737 if (!local_str_vars.empty())
42738 {
42739 str_t local_str_frame(local_str_vars.size());
42740 copy(local_str_vars,local_str_frame);
42741 local_str_stack.push_back(local_str_frame);
42742 }
42743 }
42744 }
42745
42746 inline void post()
42747 {
42748 if (--stack_depth)
42749 {
42750 if (!v.empty())
42751 {
42752 copy(input_params_stack.back(), v);
42753 input_params_stack.pop_back();
42754 }
42755
42756 if (!local_vars.empty())
42757 {
42758 copy(local_var_stack.back(), local_vars);
42759 local_var_stack.pop_back();
42760 }
42761
42762 if (!local_str_vars.empty())
42763 {
42764 copy(local_str_stack.back(), local_str_vars);
42765 local_str_stack.pop_back();
42766 }
42767 }
42768 }
42769
42770 void copy(const varref_t& src_v, var_t& dest_v)
42771 {
42772 for (std::size_t i = 0; i < src_v.size(); ++i)
42773 {
42774 dest_v[i] = (*src_v[i]);
42775 }
42776 }
42777
42778 void copy(const lstr_vec_t& src_v, str_t& dest_v)
42779 {
42780 for (std::size_t i = 0; i < src_v.size(); ++i)
42781 {
42782 dest_v[i] = (*src_v[i]);
42783 }
42784 }
42785
42786 void copy(const var_t& src_v, varref_t& dest_v)
42787 {
42788 for (std::size_t i = 0; i < src_v.size(); ++i)
42789 {
42790 (*dest_v[i]) = src_v[i];
42791 }
42792 }
42793
42794 void copy(const lvr_vec_t& src_v, var_t& dest_v)
42795 {
42796 typename var_t::iterator itr = dest_v.begin();
42797 typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
42798
42799 for (std::size_t i = 0; i < src_v.size(); ++i)
42800 {
42801 lvarref_t vr = src_v[i];
42802
42803 if (1 == vr.second)
42804 *itr++ = (*vr.first);
42805 else
42806 {
42807 std::copy(vr.first, vr.first + vr.second, itr);
42808 itr += static_cast<diff_t>(vr.second);
42809 }
42810 }
42811 }
42812
42813 void copy(const var_t& src_v, lvr_vec_t& dest_v)
42814 {
42815 typename var_t::const_iterator itr = src_v.begin();
42816 typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
42817
42818 for (std::size_t i = 0; i < dest_v.size(); ++i)
42819 {
42820 lvarref_t& vr = dest_v[i];
42821
42822 assert(vr.first != 0);
42823 assert(vr.second > 0);
42824
42825 if (1 == vr.second)
42826 (*vr.first) = *itr++;
42827 else
42828 {
42829 std::copy(itr, itr + static_cast<diff_t>(vr.second), vr.first);
42830 itr += static_cast<diff_t>(vr.second);
42831 }
42832 }
42833 }
42834
42835 void copy(const str_t& src_str, lstr_vec_t& dest_str)
42836 {
42837 assert(src_str.size() == dest_str.size());
42838
42839 for (std::size_t i = 0; i < dest_str.size(); ++i)
42840 {
42841 *dest_str[i] = src_str[i];
42842 }
42843 }
42844
42845 inline void clear_stack()
42846 {
42847 for (std::size_t i = 0; i < v.size(); ++i)
42848 {
42849 (*v[i]) = 0;
42850 }
42851 }
42852
42853 inline virtual T
value(expression_t& e)
42854 {
42856 }
42857
42858 expression_t expression;
42859 varref_t v;
42860 lvr_vec_t local_vars;
42861 lstr_vec_t local_str_vars;
42862 std::size_t local_var_stack_size;
42863 std::size_t stack_depth;
42864 std::deque<var_t> input_params_stack;
42865 std::deque<var_t> local_var_stack;
42866 std::deque<str_t> local_str_stack;
42867 };
42868
42869 typedef std::map<std::string,base_func*> funcparam_t;
42870
42871 typedef const T& type;
42872
42873 template <typename BaseFuncType>
42874 struct scoped_bft
42875 {
42876 explicit scoped_bft(BaseFuncType& bft)
42877 : bft_(bft)
42878 {
42879 bft_.pre ();
42880 }
42881
42882 ~scoped_bft()
42883 {
42884 bft_.post();
42885 }
42886
42887 BaseFuncType& bft_;
42888
42889 private:
42890
42893 };
42894
42896 {
42898
42900
42902 {
42903 scoped_bft<func_0param> sb(*this);
42904 return this->
value(base_func::expression);
42905 }
42906 };
42907
42909 {
42911
42913
42915 {
42916 scoped_bft<func_1param> sb(*this);
42917 base_func::update(v0);
42918 return this->
value(base_func::expression);
42919 }
42920 };
42921
42923 {
42925
42927
42929 {
42930 scoped_bft<func_2param> sb(*this);
42931 base_func::update(v0, v1);
42932 return this->
value(base_func::expression);
42933 }
42934 };
42935
42937 {
42939
42941
42943 {
42944 scoped_bft<func_3param> sb(*this);
42945 base_func::update(v0, v1, v2);
42946 return this->
value(base_func::expression);
42947 }
42948 };
42949
42951 {
42953
42955
42956 inline T operator() (type v0, type v1, type v2, type v3)
exprtk_override
42957 {
42958 scoped_bft<func_4param> sb(*this);
42959 base_func::update(v0, v1, v2, v3);
42960 return this->
value(base_func::expression);
42961 }
42962 };
42963
42965 {
42967
42969
42970 inline T operator() (type v0, type v1, type v2, type v3, type v4)
exprtk_override
42971 {
42972 scoped_bft<func_5param> sb(*this);
42973 base_func::update(v0, v1, v2, v3, v4);
42974 return this->
value(base_func::expression);
42975 }
42976 };
42977
42979 {
42981
42983
42984 inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5)
exprtk_override
42985 {
42986 scoped_bft<func_6param> sb(*this);
42987 base_func::update(v0, v1, v2, v3, v4, v5);
42988 return this->
value(base_func::expression);
42989 }
42990 };
42991
42992 static T return_value(expression_t& e)
42993 {
42995 typedef typename results_context_t::type_store_t type_t;
42996 typedef typename type_t::scalar_view scalar_t;
42997
42998 const T result =
e.value();
42999
43000 if (
e.return_invoked())
43001 {
43002
43003
43004
43005 return scalar_t(
e.results()[0])();
43006 }
43007
43008 return result;
43009 }
43010
43011 #define def_fp_retval(N) \
43012 struct func_##N##param_retval exprtk_final : public func_##N##param \
43013 { \
43014 inline T value(expression_t& e) exprtk_override \
43015 { \
43016 return return_value(e); \
43017 } \
43018 }; \
43019
43027
43028 #undef def_fp_retval
43029
43030 template <typename Allocator,
43031 template <typename, typename> class Sequence>
43032 inline bool add(const std::string& name,
43033 const std::string& expression,
43034 const Sequence<std::string,Allocator>& var_list,
43035 const bool override = false)
43036 {
43037 const typename std::map<std::string,expression_t>::iterator itr = expr_map_.find(name);
43038
43039 if (expr_map_.end() != itr)
43040 {
43041 if (!override)
43042 {
43043 exprtk_debug((
"Compositor error(add): function '%s' already defined\n",
43044 name.c_str()));
43045
43046 return false;
43047 }
43048
43049 remove(name, var_list.size());
43050 }
43051
43052 if (compile_expression(name, expression, var_list))
43053 {
43054 const std::size_t n = var_list.size();
43055
43056 fp_map_[n][name]->setup(expr_map_[name]);
43057
43058 return true;
43059 }
43060 else
43061 {
43062 exprtk_debug((
"Compositor error(add): Failed to compile function '%s'\n",
43063 name.c_str()));
43064
43065 return false;
43066 }
43067 }
43068
43069 public:
43070
43071 function_compositor()
43072 : parser_(settings_t::default_compile_all_opts +
43073 settings_t::e_disable_zero_return)
43074 , fp_map_(7)
43075 , load_variables_(false)
43076 , load_vectors_(false)
43077 {}
43078
43079 explicit function_compositor(const symbol_table_t& st)
43080 : symbol_table_(st)
43081 , parser_(settings_t::default_compile_all_opts +
43082 settings_t::e_disable_zero_return)
43083 , fp_map_(7)
43084 , load_variables_(false)
43085 , load_vectors_(false)
43086 {}
43087
43088 ~function_compositor()
43089 {
43090 clear();
43091 }
43092
43093 inline symbol_table_t& symbol_table()
43094 {
43095 return symbol_table_;
43096 }
43097
43098 inline const symbol_table_t& symbol_table() const
43099 {
43100 return symbol_table_;
43101 }
43102
43103 inline void add_auxiliary_symtab(symbol_table_t& symtab)
43104 {
43105 auxiliary_symtab_list_.push_back(&symtab);
43106 }
43107
43108 void load_variables(const bool load = true)
43109 {
43110 load_variables_ = load;
43111 }
43112
43113 void load_vectors(const bool load = true)
43114 {
43115 load_vectors_ = load;
43116 }
43117
43118 inline void register_loop_runtime_check(loop_runtime_check& lrtchk)
43119 {
43120 parser_.register_loop_runtime_check(lrtchk);
43121 }
43122
43123 inline void register_vector_access_runtime_check(vector_access_runtime_check& vartchk)
43124 {
43125 parser_.register_vector_access_runtime_check(vartchk);
43126 }
43127
43128 inline void register_compilation_timeout_check(compilation_check& compchk)
43129 {
43130 parser_.register_compilation_timeout_check(compchk);
43131 }
43132
43133 inline void clear_loop_runtime_check()
43134 {
43135 parser_.clear_loop_runtime_check();
43136 }
43137
43138 inline void clear_vector_access_runtime_check()
43139 {
43140 parser_.clear_vector_access_runtime_check();
43141 }
43142
43143 inline void clear_compilation_timeout_check()
43144 {
43145 parser_.clear_compilation_timeout_check();
43146 }
43147
43148 void clear()
43149 {
43150 symbol_table_.clear();
43151 expr_map_ .clear();
43152
43153 for (std::size_t i = 0; i < fp_map_.size(); ++i)
43154 {
43155 typename funcparam_t::iterator itr = fp_map_[i].begin();
43156 typename funcparam_t::iterator end = fp_map_[i].end ();
43157
43158 while (itr != end)
43159 {
43160 delete itr->second;
43161 ++itr;
43162 }
43163
43164 fp_map_[i].clear();
43165 }
43166
43167 clear_loop_runtime_check ();
43168 clear_vector_access_runtime_check();
43169 clear_compilation_timeout_check ();
43170 }
43171
43172 inline bool add(const function& f, const bool override = false)
43173 {
43174 return add(f.name_, f.expression_, f.v_,override);
43175 }
43176
43177 inline std::string error() const
43178 {
43179 if (!error_list_.empty())
43180 {
43181 return error_list_[0].diagnostic;
43182 }
43183 else
43184 return std::string("No Error");
43185 }
43186
43187 inline std::size_t error_count() const
43188 {
43189 return error_list_.size();
43190 }
43191
43192 inline parser_error::type get_error(const std::size_t& index) const
43193 {
43194 if (index < error_list_.size())
43195 {
43196 return error_list_[index];
43197 }
43198
43199 throw std::invalid_argument("compositor::get_error() - Invalid error index specified");
43200 }
43201
43202 private:
43203
43204 template <typename Allocator,
43205 template <typename, typename> class Sequence>
43206 bool compile_expression(const std::string& name,
43207 const std::string& expression,
43208 const Sequence<std::string,Allocator>& input_var_list,
43209 bool return_present = false)
43210 {
43211 expression_t compiled_expression;
43212 symbol_table_t local_symbol_table;
43213
43214 local_symbol_table.load_from(symbol_table_);
43215 local_symbol_table.add_constants();
43216
43217 if (load_variables_)
43218 {
43219 local_symbol_table.load_variables_from(symbol_table_);
43220 }
43221
43222 if (load_vectors_)
43223 {
43224 local_symbol_table.load_vectors_from(symbol_table_);
43225 }
43226
43227 error_list_.clear();
43228
43229 if (!valid(name,input_var_list.size()))
43230 {
43231 parser_error::type error =
43232 parser_error::make_error(
43233 parser_error::e_parser,
43234 lexer::token(),
43235 "ERR274 - Function '" + name + "' is an invalid overload",
43237
43238 error_list_.push_back(error);
43239 return false;
43240 }
43241
43242 if (!forward(name,
43243 input_var_list.size(),
43244 local_symbol_table,
43245 return_present))
43246 return false;
43247
43248 compiled_expression.register_symbol_table(local_symbol_table);
43249
43250 for (std::size_t i = 0; i < auxiliary_symtab_list_.size(); ++i)
43251 {
43252 compiled_expression.register_symbol_table((*auxiliary_symtab_list_[i]));
43253 }
43254
43255 std::string mod_expression;
43256
43257 for (std::size_t i = 0; i < input_var_list.size(); ++i)
43258 {
43259 mod_expression += " var " + input_var_list[i] + "{};\n";
43260 }
43261
43262 if (
43263 ('{' == details::front(expression)) &&
43264 ('}' == details::back (expression))
43265 )
43266 mod_expression += "~" + expression + ";";
43267 else
43268 mod_expression += "~{" + expression + "};";
43269
43270 if (!parser_.compile(mod_expression,compiled_expression))
43271 {
43272 exprtk_debug((
"Compositor Error: %s\n", parser_.error().c_str()));
43273 exprtk_debug((
"Compositor modified expression: \n%s\n", mod_expression.c_str()));
43274
43275 remove(name,input_var_list.size());
43276
43277 for (std::size_t err_index = 0; err_index < parser_.error_count(); ++err_index)
43278 {
43279 error_list_.push_back(parser_.get_error(err_index));
43280 }
43281
43282 return false;
43283 }
43284
43285 if (!return_present && parser_.dec().return_present())
43286 {
43287 remove(name,input_var_list.size());
43288 return compile_expression(name, expression, input_var_list, true);
43289 }
43290
43291
43292 if (parser_.dec().return_present())
43293 {
43294 typedef std::vector<std::string> str_list_t;
43295
43296 str_list_t ret_param_list = parser_.dec().return_param_type_list();
43297
43298 for (std::size_t i = 0; i < ret_param_list.size(); ++i)
43299 {
43300 const std::string& params = ret_param_list[i];
43301
43302 if (params.empty() || ('T' != params[0]))
43303 {
43304 exprtk_debug((
"Compositor Error: Return statement in function '%s' is invalid\n",
43305 name.c_str()));
43306
43307 remove(name,input_var_list.size());
43308
43309 return false;
43310 }
43311 }
43312 }
43313
43314 expr_map_[name] = compiled_expression;
43315
43317
43318 if (symbol_table_.add_function(name,ifunc))
43319 return true;
43320 else
43321 {
43322 exprtk_debug((
"Compositor Error: Failed to add function '%s' to symbol table\n",
43323 name.c_str()));
43324 return false;
43325 }
43326 }
43327
43328 inline bool symbol_used(const std::string& symbol) const
43329 {
43330 return (
43331 symbol_table_.is_variable (symbol) ||
43332 symbol_table_.is_stringvar (symbol) ||
43333 symbol_table_.is_function (symbol) ||
43334 symbol_table_.is_vector (symbol) ||
43335 symbol_table_.is_vararg_function(symbol)
43336 );
43337 }
43338
43339 inline bool valid(const std::string& name,
43340 const std::size_t& arg_count) const
43341 {
43342 if (arg_count > 6)
43343 return false;
43344 else if (symbol_used(name))
43345 return false;
43346 else if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name))
43347 return false;
43348 else
43349 return true;
43350 }
43351
43352 inline bool forward(const std::string& name,
43353 const std::size_t& arg_count,
43354 symbol_table_t& sym_table,
43355 const bool ret_present = false)
43356 {
43357 switch (arg_count)
43358 {
43359 #define case_stmt(N) \
43360 case N : (fp_map_[arg_count])[name] = \
43361 (!ret_present) ? static_cast<base_func*> \
43362 (new func_##N##param) : \
43363 static_cast<base_func*> \
43364 (new func_##N##param_retval) ; \
43365 break; \
43366
43370 #undef case_stmt
43371 }
43372
43374
43375 return sym_table.add_function(name,ifunc);
43376 }
43377
43378 inline void remove(const std::string& name, const std::size_t& arg_count)
43379 {
43380 if (arg_count > 6)
43381 return;
43382
43383 const typename std::map<std::string,expression_t>::iterator em_itr = expr_map_.find(name);
43384
43385 if (expr_map_.end() != em_itr)
43386 {
43387 expr_map_.erase(em_itr);
43388 }
43389
43390 const typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name);
43391
43392 if (fp_map_[arg_count].end() != fp_itr)
43393 {
43394 delete fp_itr->second;
43395 fp_map_[arg_count].erase(fp_itr);
43396 }
43397
43398 symbol_table_.remove_function(name);
43399 }
43400
43401 private:
43402
43403 symbol_table_t symbol_table_;
43404 parser_t parser_;
43405 std::map<std::string,expression_t> expr_map_;
43406 std::vector<funcparam_t> fp_map_;
43407 std::vector<symbol_table_t*> auxiliary_symtab_list_;
43408 std::deque<parser_error::type> error_list_;
43409 bool load_variables_;
43410 bool load_vectors_;
43411 };
43412
43413}
43414
43415#if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43416# ifndef NOMINMAX
43417# define NOMINMAX
43418# endif
43419# ifndef WIN32_LEAN_AND_MEAN
43420# define WIN32_LEAN_AND_MEAN
43421# endif
43422# include <windows.h>
43423# include <ctime>
43424#else
43425# include <ctime>
43426# include <sys/time.h>
43427# include <sys/types.h>
43428#endif
43429
43431{
43432 class timer
43433 {
43434 public:
43435
43436 #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43437 timer()
43438 : in_use_(false)
43439 , start_time_{ 0 }
43440 , stop_time_ { 0 }
43441 {
43442 QueryPerformanceFrequency(&clock_frequency_);
43443 }
43444
43445 inline void start()
43446 {
43447 in_use_ = true;
43448 QueryPerformanceCounter(&start_time_);
43449 }
43450
43451 inline void stop()
43452 {
43453 QueryPerformanceCounter(&stop_time_);
43454 in_use_ = false;
43455 }
43456
43457 inline double time() const
43458 {
43459 return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart);
43460 }
43461
43462 #else
43463
43464 timer()
43465 : in_use_(false)
43466 {
43467 start_time_.tv_sec = 0;
43468 start_time_.tv_usec = 0;
43469
43470 stop_time_.tv_sec = 0;
43471 stop_time_.tv_usec = 0;
43472 }
43473
43474 inline void start()
43475 {
43476 in_use_ = true;
43477 gettimeofday(&start_time_,0);
43478 }
43479
43480 inline void stop()
43481 {
43482 gettimeofday(&stop_time_, 0);
43483 in_use_ = false;
43484 }
43485
43486 inline unsigned long long int usec_time() const
43487 {
43488 if (!in_use_)
43489 {
43490 if (stop_time_.tv_sec >= start_time_.tv_sec)
43491 {
43492 return 1000000LLU * static_cast<details::_uint64_t>(stop_time_.tv_sec - start_time_.tv_sec ) +
43493 static_cast<details::_uint64_t>(stop_time_.tv_usec - start_time_.tv_usec) ;
43494 }
43495 else
43496 return std::numeric_limits<details::_uint64_t>::max();
43497 }
43498 else
43499 return std::numeric_limits<details::_uint64_t>::max();
43500 }
43501
43502 inline double time() const
43503 {
43504 return usec_time() * 0.000001;
43505 }
43506
43507 #endif
43508
43509 inline bool in_use() const
43510 {
43511 return in_use_;
43512 }
43513
43514 private:
43515
43516 bool in_use_;
43517
43518 #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43519 LARGE_INTEGER start_time_;
43520 LARGE_INTEGER stop_time_;
43521 LARGE_INTEGER clock_frequency_;
43522 #else
43523 struct timeval start_time_;
43524 struct timeval stop_time_;
43525 #endif
43526 };
43527
43528 template <typename T>
43529 struct type_defs
43530 {
43531 typedef symbol_table<T> symbol_table_t;
43532 typedef expression<T> expression_t;
43533 typedef parser<T> parser_t;
43534 typedef parser_error::type error_t;
43535 typedef function_compositor<T> compositor_t;
43536 typedef typename compositor_t::function function_t;
43537 };
43538
43539}
43540
43541#ifndef exprtk_disable_rtl_io
43543{
43544 namespace rtl { namespace io { namespace details
43545 {
43546 template <typename T>
43547 inline void print_type(
const std::string& fmt,
43548 const T v,
43550 {
43551 #if defined(__clang__)
43552 #pragma clang diagnostic push
43553 #pragma clang diagnostic ignored "-Wformat-nonliteral"
43554 #elif defined(__GNUC__) || defined(__GNUG__)
43555 #pragma GCC diagnostic push
43556 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
43557 #elif defined(_MSC_VER)
43558 #endif
43559
43560 printf(fmt.c_str(), v);
43561
43562 #if defined(__clang__)
43563 #pragma clang diagnostic pop
43564 #elif defined(__GNUC__) || defined(__GNUG__)
43565 #pragma GCC diagnostic pop
43566 #elif defined(_MSC_VER)
43567 #endif
43568 }
43569
43570 template <typename T>
43571 struct print_impl
43572 {
43573 typedef typename igeneric_function<T>::generic_type generic_type;
43574 typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
43575 typedef typename generic_type::scalar_view scalar_t;
43576 typedef typename generic_type::vector_view vector_t;
43577 typedef typename generic_type::string_view string_t;
43579
43580 static void process(
const std::string& scalar_format, parameter_list_t parameters)
43581 {
43582 for (std::size_t i = 0; i < parameters.size(); ++i)
43583 {
43584 generic_type& gt = parameters[i];
43585
43586 switch (gt.type)
43587 {
43588 case generic_type::e_scalar : print(scalar_format,scalar_t(gt));
43589 break;
43590
43591 case generic_type::e_vector : print(scalar_format,vector_t(gt));
43592 break;
43593
43594 case generic_type::e_string : print(string_t(gt));
43595 break;
43596
43597 default : continue;
43598 }
43599 }
43600 }
43601
43602 static inline void print(const std::string& scalar_format, const scalar_t& s)
43603 {
43605 }
43606
43607 static inline void print(const std::string& scalar_format, const vector_t& v)
43608 {
43609 for (std::size_t i = 0; i < v.size(); ++i)
43610 {
43612
43613 if ((i + 1) < v.size())
43614 printf(" ");
43615 }
43616 }
43617
43618 static inline void print(const string_t& s)
43619 {
43620 printf(
"%s",
to_str(s).c_str());
43621 }
43622 };
43623
43624 }
43625
43626 template <typename T>
43628 {
43629 typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
43630
43632
43633 explicit print(const std::string& scalar_format = "%10.5f")
43634 : scalar_format_(scalar_format)
43635 {
43637 }
43638
43640 {
43641 details::print_impl<T>::process(scalar_format_,parameters);
43642 return T(0);
43643 }
43644
43645 std::string scalar_format_;
43646 };
43647
43648 template <typename T>
43650 {
43651 typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
43652
43654
43655 explicit println(const std::string& scalar_format = "%10.5f")
43656 : scalar_format_(scalar_format)
43657 {
43659 }
43660
43662 {
43663 details::print_impl<T>::process(scalar_format_,parameters);
43664 printf("\n");
43665 return T(0);
43666 }
43667
43668 std::string scalar_format_;
43669 };
43670
43671 template <typename T>
43672 struct package
43673 {
43674 print <T> p;
43675 println<T> pl;
43676
43678 {
43679 #define exprtk_register_function(FunctionName, FunctionType) \
43680 if (!symtab.add_function(FunctionName,FunctionType)) \
43681 { \
43682 exprtk_debug(( \
43683 "exprtk::rtl::io::register_package - Failed to add function: %s\n", \
43684 FunctionName)); \
43685 return false; \
43686 } \
43687
43690 #undef exprtk_register_function
43691
43692 return true;
43693 }
43694 };
43695
43696 }
43697 }
43698}
43699#endif
43700
43701#ifndef exprtk_disable_rtl_io_file
43702#include <fstream>
43704{
43705 namespace rtl { namespace io { namespace file { namespace details
43706 {
43707 using ::exprtk::details::char_ptr;
43708 using ::exprtk::details::char_cptr;
43709
43711 {
43716 };
43717
43718 struct file_descriptor
43719 {
43720 file_descriptor(const std::string& fname, const std::string& access)
43721 : stream_ptr(0)
43722 , mode(get_file_mode(access))
43723 , file_name(fname)
43724 {}
43725
43726 void* stream_ptr;
43728 std::string file_name;
43729
43730 bool open()
43731 {
43732 if (e_read == mode)
43733 {
43734 std::ifstream* stream = new std::ifstream(file_name.c_str(),std::ios::binary);
43735
43736 if (!(*stream))
43737 {
43738 file_name.clear();
43739 delete stream;
43740
43741 return false;
43742 }
43743
43744 stream_ptr = stream;
43745
43746 return true;
43747 }
43748 else if (e_write == mode)
43749 {
43750 std::ofstream* stream = new std::ofstream(file_name.c_str(),std::ios::binary);
43751
43752 if (!(*stream))
43753 {
43754 file_name.clear();
43755 delete stream;
43756
43757 return false;
43758 }
43759
43760 stream_ptr = stream;
43761
43762 return true;
43763 }
43764 else if (e_rdwrt == mode)
43765 {
43766 std::fstream* stream = new std::fstream(file_name.c_str(),std::ios::binary);
43767
43768 if (!(*stream))
43769 {
43770 file_name.clear();
43771 delete stream;
43772
43773 return false;
43774 }
43775
43776 stream_ptr = stream;
43777
43778 return true;
43779 }
43780
43781 return false;
43782 }
43783
43784 template <typename Stream, typename Ptr>
43785 void close(Ptr& p)
43786 {
43787 Stream* stream = reinterpret_cast<Stream*>(p);
43788 stream->close();
43789 delete stream;
43790 p = reinterpret_cast<Ptr>(0);
43791 }
43792
43793 bool close()
43794 {
43795 switch (mode)
43796 {
43797 case e_read : close<std::ifstream>(stream_ptr);
43798 break;
43799
43800 case e_write : close<std::ofstream>(stream_ptr);
43801 break;
43802
43803 case e_rdwrt : close<std::fstream> (stream_ptr);
43804 break;
43805
43806 default : return false;
43807 }
43808
43809 return true;
43810 }
43811
43812 template <typename View>
43813 bool write(const View& view, const std::size_t amount, const std::size_t offset = 0)
43814 {
43815 switch (mode)
43816 {
43817 case e_write :
reinterpret_cast<std::ofstream*
>(stream_ptr)->
43818 write(
reinterpret_cast<char_cptr>(view.begin() + offset), amount *
sizeof(
typename View::value_t));
43819 break;
43820
43821 case e_rdwrt :
reinterpret_cast<std::fstream*
>(stream_ptr)->
43822 write(
reinterpret_cast<char_cptr>(view.begin() + offset) , amount *
sizeof(
typename View::value_t));
43823 break;
43824
43825 default : return false;
43826 }
43827
43828 return true;
43829 }
43830
43831 template <typename View>
43832 bool read(View& view, const std::size_t amount, const std::size_t offset = 0)
43833 {
43834 switch (mode)
43835 {
43836 case e_read :
reinterpret_cast<std::ifstream*
>(stream_ptr)->
43837 read(
reinterpret_cast<char_ptr>(view.begin() + offset), amount *
sizeof(
typename View::value_t));
43838 break;
43839
43840 case e_rdwrt :
reinterpret_cast<std::fstream*
>(stream_ptr)->
43841 read(
reinterpret_cast<char_ptr>(view.begin() + offset) , amount *
sizeof(
typename View::value_t));
43842 break;
43843
43844 default : return false;
43845 }
43846
43847 return true;
43848 }
43849
43850 bool getline(std::string& s)
43851 {
43852 switch (mode)
43853 {
43854 case e_read :
return (!!std::getline(*
reinterpret_cast<std::ifstream*
>(stream_ptr),s));
43855 case e_rdwrt :
return (!!std::getline(*
reinterpret_cast<std::fstream*
>(stream_ptr),s));
43856 default : return false;
43857 }
43858 }
43859
43860 bool eof() const
43861 {
43862 switch (mode)
43863 {
43864 case e_read :
return reinterpret_cast<std::ifstream*
>(stream_ptr)->eof();
43865 case e_write :
return reinterpret_cast<std::ofstream*
>(stream_ptr)->eof();
43866 case e_rdwrt :
return reinterpret_cast<std::fstream*
>(stream_ptr)->eof();
43867 default : return true;
43868 }
43869 }
43870
43871 file_mode get_file_mode(
const std::string& access)
const
43872 {
43873 if (access.empty() || access.size() > 2)
43875
43876 std::size_t w_cnt = 0;
43877 std::size_t r_cnt = 0;
43878
43879 for (std::size_t i = 0; i < access.size(); ++i)
43880 {
43881 switch (std::tolower(access[i]))
43882 {
43883 case 'r' : r_cnt++; break;
43884 case 'w' : w_cnt++; break;
43886 }
43887 }
43888
43889 if ((0 == r_cnt) && (0 == w_cnt))
43891 else if ((r_cnt > 1) || (w_cnt > 1))
43893 else if ((1 == r_cnt) && (1 == w_cnt))
43895 else if (1 == r_cnt)
43897 else
43899 }
43900 };
43901
43902 template <typename T>
43904 {
43905 const std::size_t fd_size = sizeof(details::file_descriptor*);
43906 details::file_descriptor* fd = reinterpret_cast<file_descriptor*>(0);
43907
43908 std::memcpy(
reinterpret_cast<char_ptr >(&fd),
43910 fd_size);
43911 return fd;
43912 }
43913
43914 template <typename T>
43916 {
43917 #ifdef _MSC_VER
43918 #pragma warning(push)
43919 #pragma warning(disable: 4127)
43920 #endif
43921 if (sizeof(T) < sizeof(void*))
43922 {
43923 throw std::runtime_error("exprtk::rtl::io::file - Error - pointer size larger than holder.");
43924 }
43925 #ifdef _MSC_VER
43926 #pragma warning(pop)
43927 #endif
43928 assert(sizeof(T) <= sizeof(void*));
43929 }
43930
43931 }
43932
43933 template <typename T>
43935 {
43936 public:
43937
43939 typedef typename igfun_t::parameter_list_t parameter_list_t;
43940 typedef typename igfun_t::generic_type generic_type;
43941 typedef typename generic_type::string_view string_t;
43942
43943 using igfun_t::operator();
43944
43945 open()
43946 :
exprtk::igeneric_function<T>(
"S|SS")
43947 { details::perform_check<T>(); }
43948
43949 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43950 {
43951 const std::string file_name =
to_str(string_t(parameters[0]));
43952
43953 if (file_name.empty())
43954 {
43955 return T(0);
43956 }
43957
43958 if ((1 == ps_index) && (0 == string_t(parameters[1]).size()))
43959 {
43960 return T(0);
43961 }
43962
43963 const std::string access =
43964 (0 == ps_index) ?
"r" :
to_str(string_t(parameters[1]));
43965
43966 details::file_descriptor* fd = new details::file_descriptor(file_name,access);
43967
43968 if (fd->open())
43969 {
43970 T t = T(0);
43971
43972 const std::size_t fd_size = sizeof(details::file_descriptor*);
43973
43974 std::memcpy(reinterpret_cast<char*>(&t ),
43975 reinterpret_cast<char*>(&fd),
43976 fd_size);
43977 return t;
43978 }
43979 else
43980 {
43981 delete fd;
43982 return T(0);
43983 }
43984 }
43985 };
43986
43987 template <typename T>
43989 {
43991
43992 close()
43993 :
exprtk::ifunction<T>(1)
43994 { details::perform_check<T>(); }
43995
43997 {
43998 details::file_descriptor* fd = details::make_handle(v);
43999
44000 if (!fd->close())
44001 return T(0);
44002
44003 delete fd;
44004
44005 return T(1);
44006 }
44007 };
44008
44009 template <typename T>
44011 {
44012 public:
44013
44015 typedef typename igfun_t::parameter_list_t parameter_list_t;
44016 typedef typename igfun_t::generic_type generic_type;
44017 typedef typename generic_type::string_view string_t;
44018 typedef typename generic_type::scalar_view scalar_t;
44019 typedef typename generic_type::vector_view vector_t;
44020
44021 using igfun_t::operator();
44022
44023 write()
44024 : igfun_t("TS|TST|TV|TVT")
44025 { details::perform_check<T>(); }
44026
44027 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44028 {
44029 details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
44030
44031 switch (ps_index)
44032 {
44033 case 0 : {
44034 const string_t buffer(parameters[1]);
44035 const std::size_t amount = buffer.size();
44036 return T(fd->write(buffer, amount) ? 1 : 0);
44037 }
44038
44039 case 1 : {
44040 const string_t buffer(parameters[1]);
44041 const std::size_t amount =
44042 std::min(buffer.size(),
44043 static_cast<std::size_t>(scalar_t(parameters[2])()));
44044 return T(fd->write(buffer, amount) ? 1 : 0);
44045 }
44046
44047 case 2 : {
44048 const vector_t vec(parameters[1]);
44049 const std::size_t amount = vec.size();
44050 return T(fd->write(vec, amount) ? 1 : 0);
44051 }
44052
44053 case 3 : {
44054 const vector_t vec(parameters[1]);
44055 const std::size_t amount =
44056 std::min(vec.size(),
44057 static_cast<std::size_t>(scalar_t(parameters[2])()));
44058 return T(fd->write(vec, amount) ? 1 : 0);
44059 }
44060 }
44061
44062 return T(0);
44063 }
44064 };
44065
44066 template <typename T>
44068 {
44069 public:
44070
44072 typedef typename igfun_t::parameter_list_t parameter_list_t;
44073 typedef typename igfun_t::generic_type generic_type;
44074 typedef typename generic_type::string_view string_t;
44075 typedef typename generic_type::scalar_view scalar_t;
44076 typedef typename generic_type::vector_view vector_t;
44077
44078 using igfun_t::operator();
44079
44080 read()
44081 : igfun_t("TS|TST|TV|TVT")
44082 { details::perform_check<T>(); }
44083
44084 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44085 {
44086 details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
44087
44088 switch (ps_index)
44089 {
44090 case 0 : {
44091 string_t buffer(parameters[1]);
44092 const std::size_t amount = buffer.size();
44093 return T(fd->read(buffer,amount) ? 1 : 0);
44094 }
44095
44096 case 1 : {
44097 string_t buffer(parameters[1]);
44098 const std::size_t amount =
44099 std::min(buffer.size(),
44100 static_cast<std::size_t>(scalar_t(parameters[2])()));
44101 return T(fd->read(buffer,amount) ? 1 : 0);
44102 }
44103
44104 case 2 : {
44105 vector_t vec(parameters[1]);
44106 const std::size_t amount = vec.size();
44107 return T(fd->read(vec,amount) ? 1 : 0);
44108 }
44109
44110 case 3 : {
44111 vector_t vec(parameters[1]);
44112 const std::size_t amount =
44113 std::min(vec.size(),
44114 static_cast<std::size_t>(scalar_t(parameters[2])()));
44115 return T(fd->read(vec,amount) ? 1 : 0);
44116 }
44117 }
44118
44119 return T(0);
44120 }
44121 };
44122
44123 template <typename T>
44125 {
44126 public:
44127
44129 typedef typename igfun_t::parameter_list_t parameter_list_t;
44130 typedef typename igfun_t::generic_type generic_type;
44131 typedef typename generic_type::string_view string_t;
44132 typedef typename generic_type::scalar_view scalar_t;
44133
44134 using igfun_t::operator();
44135
44136 getline()
44137 : igfun_t("T",igfun_t::e_rtrn_string)
44138 { details::perform_check<T>(); }
44139
44140 inline T operator() (std::string& result, parameter_list_t parameters)
exprtk_override
44141 {
44142 details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
44143 return T(fd->getline(result) ? 1 : 0);
44144 }
44145 };
44146
44147 template <typename T>
44149 {
44151
44152 eof()
44153 :
exprtk::ifunction<T>(1)
44154 { details::perform_check<T>(); }
44155
44157 {
44158 details::file_descriptor* fd = details::make_handle(v);
44159 return (fd->eof() ? T(1) : T(0));
44160 }
44161 };
44162
44163 template <typename T>
44164 struct package
44165 {
44166 open <T> o;
44167 close <T> c;
44168 write <T> w;
44169 read <T> r;
44170 getline<T> g;
44172
44174 {
44175 #define exprtk_register_function(FunctionName, FunctionType) \
44176 if (!symtab.add_function(FunctionName,FunctionType)) \
44177 { \
44178 exprtk_debug(( \
44179 "exprtk::rtl::io::file::register_package - Failed to add function: %s\n", \
44180 FunctionName)); \
44181 return false; \
44182 } \
44183
44190 #undef exprtk_register_function
44191
44192 return true;
44193 }
44194 };
44195
44196 }
44197 }
44198 }
44199}
44200#endif
44201
44202#ifndef exprtk_disable_rtl_vecops
44204{
44205 namespace rtl { namespace vecops {
44206
44207 namespace helper
44208 {
44209 template <typename Vector>
44210 inline bool invalid_range(
const Vector& v,
const std::size_t r0,
const std::size_t r1)
44211 {
44212 if (r0 > (v.size() - 1))
44213 return true;
44214 else if (r1 > (v.size() - 1))
44215 return true;
44216 else if (r1 < r0)
44217 return true;
44218 else
44219 return false;
44220 }
44221
44222 template <typename T>
44223 struct load_vector_range
44224 {
44226 typedef typename igfun_t::parameter_list_t parameter_list_t;
44227 typedef typename igfun_t::generic_type generic_type;
44228 typedef typename generic_type::scalar_view scalar_t;
44229 typedef typename generic_type::vector_view vector_t;
44230
44231 static inline bool process(parameter_list_t& parameters,
44232 std::size_t& r0, std::size_t& r1,
44233 const std::size_t& r0_prmidx,
44234 const std::size_t& r1_prmidx,
44235 const std::size_t vec_idx = 0)
44236 {
44237 if (r0_prmidx >= parameters.size())
44238 return false;
44239
44240 if (r1_prmidx >= parameters.size())
44241 return false;
44242
44243 if (!scalar_t(parameters[r0_prmidx]).to_uint(r0))
44244 return false;
44245
44246 if (!scalar_t(parameters[r1_prmidx]).to_uint(r1))
44247 return false;
44248
44249 return !
invalid_range(vector_t(parameters[vec_idx]), r0, r1);
44250 }
44251 };
44252 }
44253
44254 namespace details
44255 {
44256 template <typename T>
44257 inline void kahan_sum(T& sum, T& error,
const T v)
44258 {
44259 const T x = v - error;
44260 const T y = sum + x;
44261 error = (y - sum) - x;
44262 sum = y;
44263 }
44264
44265 }
44266
44267 template <typename T>
44269 {
44270 public:
44271
44273 typedef typename igfun_t::parameter_list_t parameter_list_t;
44274 typedef typename igfun_t::generic_type generic_type;
44275 typedef typename generic_type::scalar_view scalar_t;
44276 typedef typename generic_type::vector_view vector_t;
44277
44278 using igfun_t::operator();
44279
44280 all_true()
44281 :
exprtk::igeneric_function<T>(
"V|VTT|T*")
44282
44283
44284
44285
44286
44287
44288 {}
44289
44290 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44291 {
44292 if (2 == ps_index)
44293 {
44294 for (std::size_t i = 0; i < parameters.size(); ++i)
44295 {
44296 if (scalar_t(parameters[i])() == T(0))
44297 {
44298 return T(0);
44299 }
44300 }
44301 }
44302 else
44303 {
44304 const vector_t vec(parameters[0]);
44305
44306 std::size_t r0 = 0;
44307 std::size_t r1 = vec.size() - 1;
44308
44309 if (
44310 (1 == ps_index) &&
44311 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44312 )
44313 {
44314 return std::numeric_limits<T>::quiet_NaN();
44315 }
44316
44317 for (std::size_t i = r0; i <= r1; ++i)
44318 {
44319 if (vec[i] == T(0))
44320 {
44321 return T(0);
44322 }
44323 }
44324 }
44325
44326 return T(1);
44327 }
44328 };
44329
44330 template <typename T>
44332 {
44333 public:
44334
44336 typedef typename igfun_t::parameter_list_t parameter_list_t;
44337 typedef typename igfun_t::generic_type generic_type;
44338 typedef typename generic_type::scalar_view scalar_t;
44339 typedef typename generic_type::vector_view vector_t;
44340
44341 using igfun_t::operator();
44342
44343 all_false()
44344 :
exprtk::igeneric_function<T>(
"V|VTT|T*")
44345
44346
44347
44348
44349
44350
44351 {}
44352
44353 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44354 {
44355 if (2 == ps_index)
44356 {
44357 for (std::size_t i = 0; i < parameters.size(); ++i)
44358 {
44359 if (scalar_t(parameters[i])() != T(0))
44360 {
44361 return T(0);
44362 }
44363 }
44364 }
44365 else
44366 {
44367 const vector_t vec(parameters[0]);
44368
44369 std::size_t r0 = 0;
44370 std::size_t r1 = vec.size() - 1;
44371
44372 if (
44373 (1 == ps_index) &&
44374 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44375 )
44376 {
44377 return std::numeric_limits<T>::quiet_NaN();
44378 }
44379
44380 for (std::size_t i = r0; i <= r1; ++i)
44381 {
44382 if (vec[i] != T(0))
44383 {
44384 return T(0);
44385 }
44386 }
44387 }
44388
44389 return T(1);
44390 }
44391 };
44392
44393 template <typename T>
44395 {
44396 public:
44397
44399 typedef typename igfun_t::parameter_list_t parameter_list_t;
44400 typedef typename igfun_t::generic_type generic_type;
44401 typedef typename generic_type::scalar_view scalar_t;
44402 typedef typename generic_type::vector_view vector_t;
44403
44404 using igfun_t::operator();
44405
44406 any_true()
44407 :
exprtk::igeneric_function<T>(
"V|VTT|T*")
44408
44409
44410
44411
44412
44413
44414 {}
44415
44416 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44417 {
44418 if (2 == ps_index)
44419 {
44420 for (std::size_t i = 0; i < parameters.size(); ++i)
44421 {
44422 if (scalar_t(parameters[i])() != T(0))
44423 {
44424 return T(1);
44425 }
44426 }
44427 }
44428 else
44429 {
44430 const vector_t vec(parameters[0]);
44431
44432 std::size_t r0 = 0;
44433 std::size_t r1 = vec.size() - 1;
44434
44435 if (
44436 (1 == ps_index) &&
44437 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44438 )
44439 {
44440 return std::numeric_limits<T>::quiet_NaN();
44441 }
44442
44443 for (std::size_t i = r0; i <= r1; ++i)
44444 {
44445 if (vec[i] != T(0))
44446 {
44447 return T(1);
44448 }
44449 }
44450 }
44451
44452 return T(0);
44453 }
44454 };
44455
44456 template <typename T>
44458 {
44459 public:
44460
44462 typedef typename igfun_t::parameter_list_t parameter_list_t;
44463 typedef typename igfun_t::generic_type generic_type;
44464 typedef typename generic_type::scalar_view scalar_t;
44465 typedef typename generic_type::vector_view vector_t;
44466
44467 using igfun_t::operator();
44468
44469 any_false()
44470 :
exprtk::igeneric_function<T>(
"V|VTT|T*")
44471
44472
44473
44474
44475
44476
44477 {}
44478
44479 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44480 {
44481 if (2 == ps_index)
44482 {
44483 for (std::size_t i = 0; i < parameters.size(); ++i)
44484 {
44485 if (scalar_t(parameters[i])() == T(0))
44486 {
44487 return T(1);
44488 }
44489 }
44490 }
44491 else
44492 {
44493 const vector_t vec(parameters[0]);
44494
44495 std::size_t r0 = 0;
44496 std::size_t r1 = vec.size() - 1;
44497
44498 if (
44499 (1 == ps_index) &&
44500 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44501 )
44502 {
44503 return std::numeric_limits<T>::quiet_NaN();
44504 }
44505
44506 for (std::size_t i = r0; i <= r1; ++i)
44507 {
44508 if (vec[i] == T(0))
44509 {
44510 return T(1);
44511 }
44512 }
44513 }
44514
44515 return T(0);
44516 }
44517 };
44518
44519 template <typename T>
44521 {
44522 public:
44523
44525 typedef typename igfun_t::parameter_list_t parameter_list_t;
44526 typedef typename igfun_t::generic_type generic_type;
44527 typedef typename generic_type::scalar_view scalar_t;
44528 typedef typename generic_type::vector_view vector_t;
44529
44530 using igfun_t::operator();
44531
44532 count()
44533 :
exprtk::igeneric_function<T>(
"V|VTT|T*")
44534
44535
44536
44537
44538
44539
44540 {}
44541
44542 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44543 {
44544 std::size_t cnt = 0;
44545
44546 if (2 == ps_index)
44547 {
44548 for (std::size_t i = 0; i < parameters.size(); ++i)
44549 {
44550 if (scalar_t(parameters[i])() != T(0)) ++cnt;
44551 }
44552 }
44553 else
44554 {
44555 const vector_t vec(parameters[0]);
44556
44557 std::size_t r0 = 0;
44558 std::size_t r1 = vec.size() - 1;
44559
44560 if (
44561 (1 == ps_index) &&
44562 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44563 )
44564 {
44565 return std::numeric_limits<T>::quiet_NaN();
44566 }
44567
44568 for (std::size_t i = r0; i <= r1; ++i)
44569 {
44570 if (vec[i] != T(0)) ++cnt;
44571 }
44572 }
44573
44574 return T(cnt);
44575 }
44576 };
44577
44578 template <typename T>
44580 {
44581 public:
44582
44584 typedef typename igfun_t::parameter_list_t parameter_list_t;
44585 typedef typename igfun_t::generic_type generic_type;
44586 typedef typename generic_type::scalar_view scalar_t;
44587 typedef typename generic_type::vector_view vector_t;
44588
44589 using igfun_t::operator();
44590
44591 copy()
44592 :
exprtk::igeneric_function<T>(
"VV|VTTVTT")
44593
44594
44595
44596
44597
44598 {}
44599
44600 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44601 {
44602 const vector_t x(parameters[0]);
44603 vector_t y(parameters[(0 == ps_index) ? 1 : 3]);
44604
44605 std::size_t xr0 = 0;
44606 std::size_t xr1 = x.size() - 1;
44607
44608 std::size_t yr0 = 0;
44609 std::size_t yr1 = y.size() - 1;
44610
44611 if (1 == ps_index)
44612 {
44613 if (
44614 !helper::load_vector_range<T>::process(parameters, xr0, xr1, 1, 2, 0) ||
44615 !helper::load_vector_range<T>::process(parameters, yr0, yr1, 4, 5, 3)
44616 )
44617 return T(0);
44618 }
44619
44620 const std::size_t n = std::min(xr1 - xr0 + 1, yr1 - yr0 + 1);
44621
44622 std::copy(
44623 x.begin() + xr0,
44624 x.begin() + xr0 + n,
44625 y.begin() + yr0);
44626
44627 return T(n);
44628 }
44629 };
44630
44631 template <typename T>
44633 {
44634 public:
44635
44637 typedef typename igfun_t::parameter_list_t parameter_list_t;
44638 typedef typename igfun_t::generic_type generic_type;
44639 typedef typename generic_type::scalar_view scalar_t;
44640 typedef typename generic_type::vector_view vector_t;
44641
44642 using igfun_t::operator();
44643
44644 rol()
44645 :
exprtk::igeneric_function<T>(
"VT|VTTT")
44646
44647
44648
44649
44650
44651 {}
44652
44653 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44654 {
44655 vector_t vec(parameters[0]);
44656
44657 std::size_t n = 0;
44658 std::size_t r0 = 0;
44659 std::size_t r1 = vec.size() - 1;
44660
44661 if (!scalar_t(parameters[1]).to_uint(n))
44662 return T(0);
44663
44664 if (
44665 (1 == ps_index) &&
44666 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44667 )
44668 return T(0);
44669
44670 const std::size_t dist = r1 - r0 + 1;
44671 const std::size_t shift = n % dist;
44672
44673 std::rotate(
44674 vec.begin() + r0,
44675 vec.begin() + r0 + shift,
44676 vec.begin() + r1 + 1);
44677
44678 return T(1);
44679 }
44680 };
44681
44682 template <typename T>
44684 {
44685 public:
44686
44688 typedef typename igfun_t::parameter_list_t parameter_list_t;
44689 typedef typename igfun_t::generic_type generic_type;
44690 typedef typename generic_type::scalar_view scalar_t;
44691 typedef typename generic_type::vector_view vector_t;
44692
44693 using igfun_t::operator();
44694
44695 ror()
44696 :
exprtk::igeneric_function<T>(
"VT|VTTT")
44697
44698
44699
44700
44701
44702 {}
44703
44704 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44705 {
44706 vector_t vec(parameters[0]);
44707
44708 std::size_t n = 0;
44709 std::size_t r0 = 0;
44710 std::size_t r1 = vec.size() - 1;
44711
44712 if (!scalar_t(parameters[1]).to_uint(n))
44713 return T(0);
44714
44715 if (
44716 (1 == ps_index) &&
44717 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44718 )
44719 return T(0);
44720
44721 const std::size_t dist = r1 - r0 + 1;
44722 const std::size_t shift = (dist - (n % dist)) % dist;
44723
44724 std::rotate(
44725 vec.begin() + r0,
44726 vec.begin() + r0 + shift,
44727 vec.begin() + r1 + 1);
44728
44729 return T(1);
44730 }
44731 };
44732
44733 template <typename T>
44735 {
44736 public:
44737
44739 typedef typename igfun_t::parameter_list_t parameter_list_t;
44740 typedef typename igfun_t::generic_type generic_type;
44741 typedef typename generic_type::scalar_view scalar_t;
44742 typedef typename generic_type::vector_view vector_t;
44743
44744 using igfun_t::operator();
44745
44746 reverse()
44747 :
exprtk::igeneric_function<T>(
"V|VTT")
44748
44749
44750
44751
44752
44753 {}
44754
44755 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44756 {
44757 vector_t vec(parameters[0]);
44758
44759 std::size_t r0 = 0;
44760 std::size_t r1 = vec.size() - 1;
44761
44762 if (
44763 (1 == ps_index) &&
44764 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44765 )
44766 return T(0);
44767
44768 std::reverse(vec.begin() + r0, vec.begin() + r1 + 1);
44769
44770 return T(1);
44771 }
44772 };
44773
44774 template <typename T>
44776 {
44777 public:
44778
44780 typedef typename igfun_t::parameter_list_t parameter_list_t;
44781 typedef typename igfun_t::generic_type generic_type;
44782 typedef typename generic_type::scalar_view scalar_t;
44783 typedef typename generic_type::vector_view vector_t;
44784
44785 using igfun_t::operator();
44786
44787 shift_left()
44788 :
exprtk::igeneric_function<T>(
"VT|VTTT")
44789
44790
44791
44792
44793
44794 {}
44795
44796 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44797 {
44798 vector_t vec(parameters[0]);
44799
44800 std::size_t n = 0;
44801 std::size_t r0 = 0;
44802 std::size_t r1 = vec.size() - 1;
44803
44804 if (!scalar_t(parameters[1]).to_uint(n))
44805 return T(0);
44806
44807 if (
44808 (1 == ps_index) &&
44809 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44810 )
44811 return T(0);
44812
44813 const std::size_t dist = r1 - r0 + 1;
44814
44815 if (n > dist)
44816 return T(0);
44817
44818 std::rotate(
44819 vec.begin() + r0,
44820 vec.begin() + r0 + n,
44821 vec.begin() + r1 + 1);
44822
44823 for (std::size_t i = r1 - n + 1; i <= r1; ++i)
44824 {
44825 vec[i] = T(0);
44826 }
44827
44828 return T(1);
44829 }
44830 };
44831
44832 template <typename T>
44834 {
44835 public:
44836
44838 typedef typename igfun_t::parameter_list_t parameter_list_t;
44839 typedef typename igfun_t::generic_type generic_type;
44840 typedef typename generic_type::scalar_view scalar_t;
44841 typedef typename generic_type::vector_view vector_t;
44842
44843 using igfun_t::operator();
44844
44845 shift_right()
44846 :
exprtk::igeneric_function<T>(
"VT|VTTT")
44847
44848
44849
44850
44851
44852 {}
44853
44854 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44855 {
44856 vector_t vec(parameters[0]);
44857
44858 std::size_t n = 0;
44859 std::size_t r0 = 0;
44860 std::size_t r1 = vec.size() - 1;
44861
44862 if (!scalar_t(parameters[1]).to_uint(n))
44863 return T(0);
44864
44865 if (
44866 (1 == ps_index) &&
44867 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44868 )
44869 return T(0);
44870
44871 const std::size_t dist = r1 - r0 + 1;
44872
44873 if (n > dist)
44874 return T(0);
44875
44876 const std::size_t shift = (dist - (n % dist)) % dist;
44877
44878 std::rotate(
44879 vec.begin() + r0,
44880 vec.begin() + r0 + shift,
44881 vec.begin() + r1 + 1);
44882
44883 for (std::size_t i = r0; i < r0 + n; ++i)
44884 {
44885 vec[i] = T(0);
44886 }
44887
44888 return T(1);
44889 }
44890 };
44891
44892 template <typename T>
44894 {
44895 public:
44896
44898 typedef typename igfun_t::parameter_list_t parameter_list_t;
44899 typedef typename igfun_t::generic_type generic_type;
44900 typedef typename generic_type::string_view string_t;
44901 typedef typename generic_type::vector_view vector_t;
44902
44903 using igfun_t::operator();
44904
44905 sort()
44906 :
exprtk::igeneric_function<T>(
"V|VTT|VS|VSTT")
44907
44908
44909
44910
44911
44912
44913
44914 {}
44915
44916 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44917 {
44918 vector_t vec(parameters[0]);
44919
44920 std::size_t r0 = 0;
44921 std::size_t r1 = vec.size() - 1;
44922
44923 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0))
44924 return T(0);
44925 if ((3 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
44926 return T(0);
44927
44928 bool ascending = true;
44929
44930 if ((2 == ps_index) || (3 == ps_index))
44931 {
44933 ascending = true;
44935 ascending = false;
44936 else
44937 return T(0);
44938 }
44939
44940 if (ascending)
44941 std::sort(
44942 vec.begin() + r0,
44943 vec.begin() + r1 + 1,
44944 std::less<T>());
44945 else
44946 std::sort(
44947 vec.begin() + r0,
44948 vec.begin() + r1 + 1,
44949 std::greater<T>());
44950
44951 return T(1);
44952 }
44953 };
44954
44955 template <typename T>
44957 {
44958 public:
44959
44961 typedef typename igfun_t::parameter_list_t parameter_list_t;
44962 typedef typename igfun_t::generic_type generic_type;
44963 typedef typename generic_type::scalar_view scalar_t;
44964 typedef typename generic_type::vector_view vector_t;
44965
44966 using igfun_t::operator();
44967
44968 nthelement()
44969 :
exprtk::igeneric_function<T>(
"VT|VTTT")
44970
44971
44972
44973
44974
44975 {}
44976
44977 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44978 {
44979 vector_t vec(parameters[0]);
44980
44981 std::size_t n = 0;
44982 std::size_t r0 = 0;
44983 std::size_t r1 = vec.size() - 1;
44984
44985 if (!scalar_t(parameters[1]).to_uint(n))
44986 return T(0);
44987
44988 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
44989 {
44990 return std::numeric_limits<T>::quiet_NaN();
44991 }
44992
44993 std::nth_element(
44994 vec.begin() + r0,
44995 vec.begin() + r0 + n ,
44996 vec.begin() + r1 + 1);
44997
44998 return T(1);
44999 }
45000 };
45001
45002 template <typename T>
45004 {
45005 public:
45006
45008 typedef typename igfun_t::parameter_list_t parameter_list_t;
45009 typedef typename igfun_t::generic_type generic_type;
45010 typedef typename generic_type::scalar_view scalar_t;
45011 typedef typename generic_type::vector_view vector_t;
45012
45013 using igfun_t::operator();
45014
45015 assign()
45016 :
exprtk::igeneric_function<T>(
"VT|VTTT|VTTTT")
45017
45018
45019
45020
45021
45022
45023 {}
45024
45025 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45026 {
45027 vector_t vec(parameters[0]);
45028
45029 const T assign_value = scalar_t(parameters[1]);
45030
45031 const std::size_t step_size = (2 != ps_index) ? 1 :
45032 static_cast<
std::size_t>(scalar_t(parameters.
back())());
45033
45034 std::size_t r0 = 0;
45035 std::size_t r1 = vec.size() - 1;
45036
45037 if (
45038 ((ps_index == 1) || (ps_index == 2)) &&
45039 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
45040 )
45041 {
45042 return T(0);
45043 }
45044
45045 for (std::size_t i = r0; i <= r1; i += step_size)
45046 {
45047 vec[i] = assign_value;
45048 }
45049
45050 return T(1);
45051 }
45052 };
45053
45054 template <typename T>
45056 {
45057 public:
45058
45060 typedef typename igfun_t::parameter_list_t parameter_list_t;
45061 typedef typename igfun_t::generic_type generic_type;
45062 typedef typename generic_type::scalar_view scalar_t;
45063 typedef typename generic_type::vector_view vector_t;
45064
45065 using igfun_t::operator();
45066
45067 iota()
45068 :
exprtk::igeneric_function<T>(
"VTT|VT|VTTTT|VTTT")
45069
45070
45071
45072
45073
45074
45075
45076
45077
45078
45079
45080 {}
45081
45082 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45083 {
45084 vector_t vec(parameters[0]);
45085
45086 const T start_value = (ps_index <= 1) ?
45087 scalar_t(parameters[1]) :
45088 scalar_t(parameters[3]) ;
45089
45090 const T step_size = ((0 == ps_index) || (2 == ps_index)) ?
45091 scalar_t(parameters.back())() :
45092 T(1) ;
45093
45094 std::size_t r0 = 0;
45095 std::size_t r1 = vec.size() - 1;
45096
45097 if (
45098 ((ps_index == 2) || (ps_index == 3)) &&
45099 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45100 )
45101 {
45102 return T(0);
45103 }
45104
45105 for (std::size_t i = r0; i <= r1; ++i)
45106 {
45107 vec[i] = start_value + ((i - r0) * step_size);
45108 }
45109
45110 return T(1);
45111 }
45112 };
45113
45114 template <typename T>
45116 {
45117 public:
45118
45120 typedef typename igfun_t::parameter_list_t parameter_list_t;
45121 typedef typename igfun_t::generic_type generic_type;
45122 typedef typename generic_type::scalar_view scalar_t;
45123 typedef typename generic_type::vector_view vector_t;
45124
45125 using igfun_t::operator();
45126
45127 sumk()
45128 :
exprtk::igeneric_function<T>(
"V|VTT|VTTT")
45129
45130
45131
45132
45133
45134
45135 {}
45136
45137 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45138 {
45139 const vector_t vec(parameters[0]);
45140
45141 const std::size_t stride = (2 != ps_index) ? 1 :
45142 static_cast<
std::size_t>(scalar_t(parameters[3])());
45143
45144 std::size_t r0 = 0;
45145 std::size_t r1 = vec.size() - 1;
45146
45147 if (
45148 ((1 == ps_index) || (2 == ps_index)) &&
45149 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45150 )
45151 {
45152 return std::numeric_limits<T>::quiet_NaN();
45153 }
45154
45155 T result = T(0);
45156 T error = T(0);
45157
45158 for (std::size_t i = r0; i <= r1; i += stride)
45159 {
45160 details::kahan_sum(result, error, vec[i]);
45161 }
45162
45163 return result;
45164 }
45165 };
45166
45167 template <typename T>
45169 {
45170 public:
45171
45173 typedef typename igfun_t::parameter_list_t parameter_list_t;
45174 typedef typename igfun_t::generic_type generic_type;
45175 typedef typename generic_type::scalar_view scalar_t;
45176 typedef typename generic_type::vector_view vector_t;
45177
45178 using igfun_t::operator();
45179
45180 axpy()
45181 :
exprtk::igeneric_function<T>(
"TVV|TVVTT")
45182
45183
45184
45185
45186
45187
45188 {}
45189
45190 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45191 {
45192 const vector_t x(parameters[1]);
45193 vector_t y(parameters[2]);
45194
45195 std::size_t r0 = 0;
45196 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45197
45198 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 1))
45199 return std::numeric_limits<T>::quiet_NaN();
45200 else if (helper::invalid_range(y, r0, r1))
45201 return std::numeric_limits<T>::quiet_NaN();
45202
45203 const T a = scalar_t(parameters[0])();
45204
45205 for (std::size_t i = r0; i <= r1; ++i)
45206 {
45207 y[i] = (a * x[i]) + y[i];
45208 }
45209
45210 return T(1);
45211 }
45212 };
45213
45214 template <typename T>
45216 {
45217 public:
45218
45220 typedef typename igfun_t::parameter_list_t parameter_list_t;
45221 typedef typename igfun_t::generic_type generic_type;
45222 typedef typename generic_type::scalar_view scalar_t;
45223 typedef typename generic_type::vector_view vector_t;
45224
45225 using igfun_t::operator();
45226
45227 axpby()
45228 :
exprtk::igeneric_function<T>(
"TVTV|TVTVTT")
45229
45230
45231
45232
45233
45234
45235 {}
45236
45237 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45238 {
45239 const vector_t x(parameters[1]);
45240 vector_t y(parameters[3]);
45241
45242 std::size_t r0 = 0;
45243 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45244
45245 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
45246 return std::numeric_limits<T>::quiet_NaN();
45247 else if (helper::invalid_range(y, r0, r1))
45248 return std::numeric_limits<T>::quiet_NaN();
45249
45250 const T a = scalar_t(parameters[0])();
45251 const T b = scalar_t(parameters[2])();
45252
45253 for (std::size_t i = r0; i <= r1; ++i)
45254 {
45255 y[i] = (a * x[i]) + (b * y[i]);
45256 }
45257
45258 return T(1);
45259 }
45260 };
45261
45262 template <typename T>
45264 {
45265 public:
45266
45268 typedef typename igfun_t::parameter_list_t parameter_list_t;
45269 typedef typename igfun_t::generic_type generic_type;
45270 typedef typename generic_type::scalar_view scalar_t;
45271 typedef typename generic_type::vector_view vector_t;
45272
45273 using igfun_t::operator();
45274
45275 axpyz()
45276 :
exprtk::igeneric_function<T>(
"TVVV|TVVVTT")
45277
45278
45279
45280
45281
45282
45283 {}
45284
45285 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45286 {
45287 const vector_t x(parameters[1]);
45288 const vector_t y(parameters[2]);
45289 vector_t z(parameters[3]);
45290
45291 std::size_t r0 = 0;
45292 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45293
45294 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
45295 return std::numeric_limits<T>::quiet_NaN();
45296 else if (helper::invalid_range(y, r0, r1))
45297 return std::numeric_limits<T>::quiet_NaN();
45298 else if (helper::invalid_range(z, r0, r1))
45299 return std::numeric_limits<T>::quiet_NaN();
45300
45301 const T a = scalar_t(parameters[0])();
45302
45303 for (std::size_t i = r0; i <= r1; ++i)
45304 {
45305 z[i] = (a * x[i]) + y[i];
45306 }
45307
45308 return T(1);
45309 }
45310 };
45311
45312 template <typename T>
45314 {
45315 public:
45316
45318 typedef typename igfun_t::parameter_list_t parameter_list_t;
45319 typedef typename igfun_t::generic_type generic_type;
45320 typedef typename generic_type::scalar_view scalar_t;
45321 typedef typename generic_type::vector_view vector_t;
45322
45323 using igfun_t::operator();
45324
45325 axpbyz()
45326 :
exprtk::igeneric_function<T>(
"TVTVV|TVTVVTT")
45327
45328
45329
45330
45331
45332
45333 {}
45334
45335 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45336 {
45337 const vector_t x(parameters[1]);
45338 const vector_t y(parameters[3]);
45339 vector_t z(parameters[4]);
45340
45341 std::size_t r0 = 0;
45342 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45343
45344 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
45345 return std::numeric_limits<T>::quiet_NaN();
45346 else if (helper::invalid_range(y, r0, r1))
45347 return std::numeric_limits<T>::quiet_NaN();
45348 else if (helper::invalid_range(z, r0, r1))
45349 return std::numeric_limits<T>::quiet_NaN();
45350
45351 const T a = scalar_t(parameters[0])();
45352 const T b = scalar_t(parameters[2])();
45353
45354 for (std::size_t i = r0; i <= r1; ++i)
45355 {
45356 z[i] = (a * x[i]) + (b * y[i]);
45357 }
45358
45359 return T(1);
45360 }
45361 };
45362
45363 template <typename T>
45365 {
45366 public:
45367
45369 typedef typename igfun_t::parameter_list_t parameter_list_t;
45370 typedef typename igfun_t::generic_type generic_type;
45371 typedef typename generic_type::scalar_view scalar_t;
45372 typedef typename generic_type::vector_view vector_t;
45373
45374 using igfun_t::operator();
45375
45376 axpbsy()
45377 :
exprtk::igeneric_function<T>(
"TVTTV|TVTTVTT")
45378
45379
45380
45381
45382
45383
45384 {}
45385
45386 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45387 {
45388 const vector_t x(parameters[1]);
45389 vector_t y(parameters[4]);
45390
45391 std::size_t r0 = 0;
45392 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45393
45394 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
45395 return std::numeric_limits<T>::quiet_NaN();
45396 else if (helper::invalid_range(y, r0, r1))
45397 return std::numeric_limits<T>::quiet_NaN();
45398
45399 const T a = scalar_t(parameters[0])();
45400 const T b = scalar_t(parameters[2])();
45401
45402 const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
45403
45404 for (std::size_t i = r0; i <= r1; ++i)
45405 {
45406 y[i] = (a * x[i]) + (b * y[i + s]);
45407 }
45408
45409 return T(1);
45410 }
45411 };
45412
45413 template <typename T>
45415 {
45416 public:
45417
45419 typedef typename igfun_t::parameter_list_t parameter_list_t;
45420 typedef typename igfun_t::generic_type generic_type;
45421 typedef typename generic_type::scalar_view scalar_t;
45422 typedef typename generic_type::vector_view vector_t;
45423
45424 using igfun_t::operator();
45425
45426 axpbsyz()
45427 :
exprtk::igeneric_function<T>(
"TVTTVV|TVTTVVTT")
45428
45429
45430
45431
45432
45433
45434 {}
45435
45436 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45437 {
45438 const vector_t x(parameters[1]);
45439 const vector_t y(parameters[4]);
45440 vector_t z(parameters[5]);
45441
45442 std::size_t r0 = 0;
45443 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45444
45445 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 6, 7, 1))
45446 return std::numeric_limits<T>::quiet_NaN();
45447 else if (helper::invalid_range(y, r0, r1))
45448 return std::numeric_limits<T>::quiet_NaN();
45449 else if (helper::invalid_range(z, r0, r1))
45450 return std::numeric_limits<T>::quiet_NaN();
45451
45452 const T a = scalar_t(parameters[0])();
45453 const T b = scalar_t(parameters[2])();
45454
45455 const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
45456
45457 for (std::size_t i = r0; i <= r1; ++i)
45458 {
45459 z[i] = (a * x[i]) + (b * y[i + s]);
45460 }
45461
45462 return T(1);
45463 }
45464 };
45465
45466 template <typename T>
45468 {
45469 public:
45470
45472 typedef typename igfun_t::parameter_list_t parameter_list_t;
45473 typedef typename igfun_t::generic_type generic_type;
45474 typedef typename generic_type::scalar_view scalar_t;
45475 typedef typename generic_type::vector_view vector_t;
45476
45477 using igfun_t::operator();
45478
45479 axpbz()
45480 :
exprtk::igeneric_function<T>(
"TVTV|TVTVTT")
45481
45482
45483
45484
45485
45486
45487 {}
45488
45489 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45490 {
45491 const vector_t x(parameters[1]);
45492 vector_t z(parameters[3]);
45493
45494 std::size_t r0 = 0;
45495 std::size_t r1 = x.size() - 1;
45496
45497 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
45498 return std::numeric_limits<T>::quiet_NaN();
45499 else if (helper::invalid_range(z, r0, r1))
45500 return std::numeric_limits<T>::quiet_NaN();
45501
45502 const T a = scalar_t(parameters[0])();
45503 const T b = scalar_t(parameters[2])();
45504
45505 for (std::size_t i = r0; i <= r1; ++i)
45506 {
45507 z[i] = (a * x[i]) + b;
45508 }
45509
45510 return T(1);
45511 }
45512 };
45513
45514 template <typename T>
45516 {
45517 public:
45518
45520 typedef typename igfun_t::parameter_list_t parameter_list_t;
45521 typedef typename igfun_t::generic_type generic_type;
45522 typedef typename generic_type::scalar_view scalar_t;
45523 typedef typename generic_type::vector_view vector_t;
45524
45525 using igfun_t::operator();
45526
45527 diff()
45528 :
exprtk::igeneric_function<T>(
"VV|VVT")
45529
45530
45531
45532
45533
45534
45535 {}
45536
45537 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45538 {
45539 const vector_t x(parameters[0]);
45540 vector_t y(parameters[1]);
45541
45542 const std::size_t r0 = 0;
45543 const std::size_t r1 = std::min(x.size(),y.size()) - 1;
45544
45545 const std::size_t stride = (1 != ps_index) ? 1 :
45546 std::
min(r1,static_cast<
std::size_t>(scalar_t(parameters[2])()));
45547
45548 for (std::size_t i = 0; i < stride; ++i)
45549 {
45550 y[i] = std::numeric_limits<T>::quiet_NaN();
45551 }
45552
45553 for (std::size_t i = (r0 + stride); i <= r1; ++i)
45554 {
45555 y[i] = x[i] - x[i - stride];
45556 }
45557
45558 return T(1);
45559 }
45560 };
45561
45562 template <typename T>
45564 {
45565 public:
45566
45568 typedef typename igfun_t::parameter_list_t parameter_list_t;
45569 typedef typename igfun_t::generic_type generic_type;
45570 typedef typename generic_type::scalar_view scalar_t;
45571 typedef typename generic_type::vector_view vector_t;
45572
45573 using igfun_t::operator();
45574
45575 dot()
45576 :
exprtk::igeneric_function<T>(
"VV|VVTT")
45577
45578
45579
45580
45581
45582 {}
45583
45584 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45585 {
45586 const vector_t x(parameters[0]);
45587 const vector_t y(parameters[1]);
45588
45589 std::size_t r0 = 0;
45590 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45591
45592 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
45593 return std::numeric_limits<T>::quiet_NaN();
45594 else if (helper::invalid_range(y, r0, r1))
45595 return std::numeric_limits<T>::quiet_NaN();
45596
45597 T result = T(0);
45598
45599 for (std::size_t i = r0; i <= r1; ++i)
45600 {
45601 result += (x[i] * y[i]);
45602 }
45603
45604 return result;
45605 }
45606 };
45607
45608 template <typename T>
45610 {
45611 public:
45612
45614 typedef typename igfun_t::parameter_list_t parameter_list_t;
45615 typedef typename igfun_t::generic_type generic_type;
45616 typedef typename generic_type::scalar_view scalar_t;
45617 typedef typename generic_type::vector_view vector_t;
45618
45619 using igfun_t::operator();
45620
45621 dotk()
45622 :
exprtk::igeneric_function<T>(
"VV|VVTT")
45623
45624
45625
45626
45627
45628 {}
45629
45630 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45631 {
45632 const vector_t x(parameters[0]);
45633 const vector_t y(parameters[1]);
45634
45635 std::size_t r0 = 0;
45636 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45637
45638 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
45639 return std::numeric_limits<T>::quiet_NaN();
45640 else if (helper::invalid_range(y, r0, r1))
45641 return std::numeric_limits<T>::quiet_NaN();
45642
45643 T result = T(0);
45644 T error = T(0);
45645
45646 for (std::size_t i = r0; i <= r1; ++i)
45647 {
45648 details::kahan_sum(result, error, (x[i] * y[i]));
45649 }
45650
45651 return result;
45652 }
45653 };
45654
45655 template <typename T>
45657 {
45658 public:
45659
45661 typedef typename igfun_t::parameter_list_t parameter_list_t;
45662 typedef typename igfun_t::generic_type generic_type;
45663 typedef typename generic_type::scalar_view scalar_t;
45664 typedef typename generic_type::vector_view vector_t;
45665
45666 using igfun_t::operator();
45667
45668 threshold_below()
45669 :
exprtk::igeneric_function<T>(
"VTT|VTTTT")
45670
45671
45672
45673
45674
45675
45676
45677
45678
45679 {}
45680
45681 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45682 {
45683 vector_t vec(parameters[0]);
45684
45685 const T threshold_value = (0 == ps_index) ?
45686 scalar_t(parameters[1]) :
45687 scalar_t(parameters[3]) ;
45688
45689 const T snap_value = scalar_t(parameters.back());
45690
45691 std::size_t r0 = 0;
45692 std::size_t r1 = vec.size() - 1;
45693
45694 if (
45695 (1 == ps_index) &&
45696 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45697 )
45698 {
45699 return T(0);
45700 }
45701
45702 for (std::size_t i = r0; i <= r1; ++i)
45703 {
45704 if (vec[i] < threshold_value)
45705 {
45706 vec[i] = snap_value;
45707 }
45708 }
45709
45710 return T(1);
45711 }
45712 };
45713
45714 template <typename T>
45716 {
45717 public:
45718
45720 typedef typename igfun_t::parameter_list_t parameter_list_t;
45721 typedef typename igfun_t::generic_type generic_type;
45722 typedef typename generic_type::scalar_view scalar_t;
45723 typedef typename generic_type::vector_view vector_t;
45724
45725 using igfun_t::operator();
45726
45727 threshold_above()
45728 :
exprtk::igeneric_function<T>(
"VTT|VTTTT")
45729
45730
45731
45732
45733
45734
45735
45736
45737
45738 {}
45739
45740 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
45741 {
45742 vector_t vec(parameters[0]);
45743
45744 const T threshold_value = (0 == ps_index) ?
45745 scalar_t(parameters[1]) :
45746 scalar_t(parameters[3]) ;
45747
45748 const T snap_value = scalar_t(parameters.back());
45749
45750 std::size_t r0 = 0;
45751 std::size_t r1 = vec.size() - 1;
45752
45753 if (
45754 (1 == ps_index) &&
45755 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45756 )
45757 {
45758 return T(0);
45759 }
45760
45761 for (std::size_t i = r0; i <= r1; ++i)
45762 {
45763 if (vec[i] > threshold_value)
45764 {
45765 vec[i] = snap_value;
45766 }
45767 }
45768
45769 return T(1);
45770 }
45771 };
45772
45773 template <typename T>
45774 struct package
45775 {
45776 all_true <T> at;
45777 all_false <T> af;
45778 any_true <T> nt;
45779 any_false <T> nf;
45780 count <T> c;
45781 copy <T> cp;
45782 rol <T> rl;
45783 ror <T> rr;
45784 reverse <T> rev;
45785 shift_left <T> sl;
45786 shift_right <T> sr;
45787 sort <T> st;
45788 nthelement <T> ne;
45789 assign <T> an;
45790 iota <T> ia;
45791 sumk <T> sk;
45792 axpy <T> b1_axpy;
45793 axpby <T> b1_axpby;
45794 axpyz <T> b1_axpyz;
45795 axpbyz <T> b1_axpbyz;
45796 axpbsy <T> b1_axpbsy;
45797 axpbsyz <T> b1_axpbsyz;
45798 axpbz <T> b1_axpbz;
45799 diff <T> df;
45800 dot <T> dt;
45801 dotk <T> dtk;
45802 threshold_above<T> ta;
45803 threshold_below<T> tb;
45804
45806 {
45807 #define exprtk_register_function(FunctionName, FunctionType) \
45808 if (!symtab.add_function(FunctionName,FunctionType)) \
45809 { \
45810 exprtk_debug(( \
45811 "exprtk::rtl::vecops::register_package - Failed to add function: %s\n", \
45812 FunctionName)); \
45813 return false; \
45814 } \
45815
45846 #undef exprtk_register_function
45847
45848 return true;
45849 }
45850 };
45851
45852 }
45853 }
45854}
45855#endif
45856
45858{
45859 namespace information
45860 {
45861 using ::exprtk::details::char_cptr;
45862
45865 "572470936999595749669676277240766303535"
45866 "475945713821785251664274274663919320030"
45867 "599218174135966290435729003342952605956";
45870
45871 static inline std::string
data()
45872 {
45873 static const std::string info_str = std::string(library) +
45874 std::string(" v") + std::string(version) +
45875 std::string(
" (") +
date + std::string(
")") +
45876 std::string(
" (") +
min_cpp + std::string(
")");
45877 return info_str;
45878 }
45879
45880 }
45881
45882 #ifdef exprtk_debug
45883 #undef exprtk_debug
45884 #endif
45885
45886 #ifdef exprtk_error_location
45887 #undef exprtk_error_location
45888 #endif
45889
45890 #ifdef exprtk_fallthrough
45891 #undef exprtk_fallthrough
45892 #endif
45893
45894 #ifdef exprtk_override
45895 #undef exprtk_override
45896 #endif
45897
45898 #ifdef exprtk_final
45899 #undef exprtk_final
45900 #endif
45901
45902 #ifdef exprtk_delete
45903 #undef exprtk_delete
45904 #endif
45905
45906}
45907
45908#endif
#define basic_opr_switch_statements
#define register_binary_op(Op, BinaryFunctor)
#define exprtk_register_function(FunctionName, FunctionType)
#define register_unary_op(Op, UnaryFunctor)
#define register_sf4ext(Op)
#define extended_opr_switch_statements
#define exprtk_debug(params)
#define exprtk_error_location
#define string_opr_switch_statements
#define exprtk_assign(Index)
#define register_sf3_extid(Id, Op)
complex_t min(const complex_t v0, const complex_t v1)
complex_t max(const complex_t v0, const complex_t v1)
T process(const operator_type operation, const T arg)
bool imatch(const char_t c1, const char_t c2)
const char_t & back(const std::string &s)
T value(details::expression_node< T > *n)
std::string to_str(int i)
void free_node(NodeAllocator &, expression_node< T > *&node)
void free_all_nodes(NodeAllocator &node_allocator, expression_node< T > *(&b)[N])
bool is_neg_unary_node(const expression_node< T > *node)
void print_type(const std::string &fmt, const T v, exprtk::details::numeric::details::real_type_tag)
file_descriptor * make_handle(T v)
void kahan_sum(T &sum, T &error, const T v)
bool invalid_range(const Vector &v, const std::size_t r0, const std::size_t r1)
void enable_zero_parameters(FunctionType &func)
bool collect_variables(const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
vector_access_runtime_check * vector_access_runtime_check_ptr
void disable_has_side_effects(FunctionType &func)
compilation_check * compilation_check_ptr
assert_check * assert_check_ptr
T third_derivative(const expression< T > &e, T &x, const T &h=T(0.0001))
bool collect_functions(const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
loop_runtime_check * loop_runtime_check_ptr
bool compute(const std::string &expression_string, T &result)
T derivative(const expression< T > &e, T &x, const T &h=T(0.00000001))
T second_derivative(const expression< T > &e, T &x, const T &h=T(0.00001))
T integrate(const expression< T > &e, T &x, const T &r0, const T &r1, const std::size_t number_of_intervals=1000000)