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