33243 {
33244 switch (p)
33245 {
33246 #define case_stmt(cp) \
33247 case cp : return node_allocator_-> \
33248 allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \
33249
33265 #undef case_stmt
33266 default : return error_node();
33267 }
33268 }
33269
33270 inline expression_node_ptr cardinal_pow_optimisation(const T& v, const T& c)
33271 {
33272 const bool not_recipricol = (c >= T(0));
33273 const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
33274
33275 if (0 == p)
33276 return node_allocator_->allocate_c<literal_node_t>(T(1));
33277 else if (std::equal_to<T>()(T(2),c))
33278 {
33279 return node_allocator_->
33280 template allocate_rr<typename details::vov_node<Type,details::mul_op<Type> > >(v,v);
33281 }
33282 else
33283 {
33284 if (not_recipricol)
33285 return cardinal_pow_optimisation_impl<T,details::ipow_node>(v,p);
33286 else
33287 return cardinal_pow_optimisation_impl<T,details::ipowinv_node>(v,p);
33288 }
33289 }
33290
33291 inline bool cardinal_pow_optimisable(const details::operator_type& operation, const T& c) const
33292 {
33293 return (details::e_pow == operation) && (details::numeric::abs(c) <= T(60)) && details::numeric::is_integer(c);
33294 }
33295
33296 inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr (&branch)[2])
33297 {
33298 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
33299 const bool not_recipricol = (c >= T(0));
33300 const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
33301
33302 node_allocator_->free(branch[1]);
33303
33304 if (0 == p)
33305 {
33306 details::free_all_nodes(*node_allocator_, branch);
33307
33308 return node_allocator_->allocate_c<literal_node_t>(T(1));
33309 }
33310 else if (not_recipricol)
33311 return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipow_node>(branch[0],p);
33312 else
33313 return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipowinv_node>(branch[0],p);
33314 }
33315 #else
33316 inline expression_node_ptr cardinal_pow_optimisation(T&, const T&)
33317 {
33318 return error_node();
33319 }
33320
33321 inline bool cardinal_pow_optimisable(const details::operator_type&, const T&)
33322 {
33323 return false;
33324 }
33325
33326 inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr(&)[2])
33327 {
33328 return error_node();
33329 }
33330 #endif
33331
33332 struct synthesize_binary_ext_expression
33333 {
33334 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
33335 const details::operator_type& operation,
33336 expression_node_ptr (&branch)[2])
33337 {
33340
33341 if (left_neg && right_neg)
33342 {
33343 if (
33344 (details::e_add == operation) ||
33345 (details::e_sub == operation) ||
33346 (details::e_mul == operation) ||
33347 (details::e_div == operation)
33348 )
33349 {
33350 if (
33351 !expr_gen.parser_->simplify_unary_negation_branch(branch[0]) ||
33352 !expr_gen.parser_->simplify_unary_negation_branch(branch[1])
33353 )
33354 {
33355 details::free_all_nodes(*expr_gen.node_allocator_,branch);
33356
33357 return error_node();
33358 }
33359 }
33360
33361 switch (operation)
33362 {
33363
33364 case details::e_add : return expr_gen(details::e_neg,
33365 expr_gen.node_allocator_->
33366 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
33367 (branch[0],branch[1]));
33368
33369
33370 case details::e_sub : return expr_gen.node_allocator_->
33371 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
33372 (branch[1],branch[0]);
33373
33374 default : break;
33375 }
33376 }
33377 else if (left_neg && !right_neg)
33378 {
33379 if (
33380 (details::e_add == operation) ||
33381 (details::e_sub == operation) ||
33382 (details::e_mul == operation) ||
33383 (details::e_div == operation)
33384 )
33385 {
33386 if (!expr_gen.parser_->simplify_unary_negation_branch(branch[0]))
33387 {
33388 details::free_all_nodes(*expr_gen.node_allocator_,branch);
33389
33390 return error_node();
33391 }
33392
33393 switch (operation)
33394 {
33395
33396 case details::e_add : return expr_gen.node_allocator_->
33397 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
33398 (branch[1], branch[0]);
33399
33400
33401 case details::e_sub : return expr_gen(details::e_neg,
33402 expr_gen.node_allocator_->
33403 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
33404 (branch[0], branch[1]));
33405
33406
33407 case details::e_mul : return expr_gen(details::e_neg,
33408 expr_gen.node_allocator_->
33409 template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
33410 (branch[0], branch[1]));
33411
33412
33413 case details::e_div : return expr_gen(details::e_neg,
33414 expr_gen.node_allocator_->
33415 template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
33416 (branch[0], branch[1]));
33417
33418 default : return error_node();
33419 }
33420 }
33421 }
33422 else if (!left_neg && right_neg)
33423 {
33424 if (
33425 (details::e_add == operation) ||
33426 (details::e_sub == operation) ||
33427 (details::e_mul == operation) ||
33428 (details::e_div == operation)
33429 )
33430 {
33431 if (!expr_gen.parser_->simplify_unary_negation_branch(branch[1]))
33432 {
33433 details::free_all_nodes(*expr_gen.node_allocator_,branch);
33434
33435 return error_node();
33436 }
33437
33438 switch (operation)
33439 {
33440
33441 case details::e_add : return expr_gen.node_allocator_->
33442 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
33443 (branch[0], branch[1]);
33444
33445
33446 case details::e_sub : return expr_gen.node_allocator_->
33447 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
33448 (branch[0], branch[1]);
33449
33450
33451 case details::e_mul : return expr_gen(details::e_neg,
33452 expr_gen.node_allocator_->
33453 template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
33454 (branch[0], branch[1]));
33455
33456
33457 case details::e_div : return expr_gen(details::e_neg,
33458 expr_gen.node_allocator_->
33459 template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
33460 (branch[0], branch[1]));
33461
33462 default : return error_node();
33463 }
33464 }
33465 }
33466
33467 switch (operation)
33468 {
33469 #define case_stmt(op0, op1) \
33470 case op0 : return expr_gen.node_allocator_-> \
33471 template allocate<typename details::binary_ext_node<Type,op1<Type> > > \
33472 (branch[0], branch[1]); \
33473
33476 #undef case_stmt
33477 default : return error_node();
33478 }
33479 }
33480 };
33481
33482 struct synthesize_vob_expression
33483 {
33484 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
33485 const details::operator_type& operation,
33486 expression_node_ptr (&branch)[2])
33487 {
33488 const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref();
33489
33490 #ifndef exprtk_disable_enhanced_features
33491 if (details::is_sf3ext_node(branch[1]))
33492 {
33493 expression_node_ptr result = error_node();
33494
33495 const bool synthesis_result =
33496 synthesize_sf4ext_expression::template compile_right<vtype>
33497 (expr_gen, v, operation, branch[1], result);
33498
33499 if (synthesis_result)
33500 {
33501 details::free_node(*expr_gen.node_allocator_,branch[1]);
33502 return result;
33503 }
33504 }
33505 #endif
33506
33507 if (
33508 (details::e_mul == operation) ||
33509 (details::e_div == operation)
33510 )
33511 {
33512 if (details::is_uv_node(branch[1]))
33513 {
33514 typedef details::uv_base_node<Type>* uvbn_ptr_t;
33515
33516 details::operator_type o = static_cast<uvbn_ptr_t>(branch[1])->operation();
33517
33518 if (details::e_neg == o)
33519 {
33520 const Type& v1 = static_cast<uvbn_ptr_t>(branch[1])->v();
33521
33522 details::free_node(*expr_gen.node_allocator_,branch[1]);
33523
33524 switch (operation)
33525 {
33526 case details::e_mul : return expr_gen(details::e_neg,
33527 expr_gen.node_allocator_->
33528 template allocate_rr<typename details::
33529 vov_node<Type,details::mul_op<Type> > >(v,v1));
33530
33531 case details::e_div : return expr_gen(details::e_neg,
33532 expr_gen.node_allocator_->
33533 template allocate_rr<typename details::
33534 vov_node<Type,details::div_op<Type> > >(v,v1));
33535
33536 default : break;
33537 }
33538 }
33539 }
33540 }
33541
33542 switch (operation)
33543 {
33544 #define case_stmt(op0, op1) \
33545 case op0 : return expr_gen.node_allocator_-> \
33546 template allocate_rc<typename details::vob_node<Type,op1<Type> > > \
33547 (v, branch[1]); \
33548
33551 #undef case_stmt
33552 default : return error_node();
33553 }
33554 }
33555 };
33556
33557 struct synthesize_bov_expression
33558 {
33559 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
33560 const details::operator_type& operation,
33561 expression_node_ptr (&branch)[2])
33562 {
33563 const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref();
33564
33565 #ifndef exprtk_disable_enhanced_features
33566 if (details::is_sf3ext_node(branch[0]))
33567 {
33568 expression_node_ptr result = error_node();
33569
33570 const bool synthesis_result =
33571 synthesize_sf4ext_expression::template compile_left<vtype>
33572 (expr_gen, v, operation, branch[0], result);
33573
33574 if (synthesis_result)
33575 {
33576 details::free_node(*expr_gen.node_allocator_, branch[0]);
33577
33578 return result;
33579 }
33580 }
33581 #endif
33582
33583 if (
33584 (details::e_add == operation) ||
33585 (details::e_sub == operation) ||
33586 (details::e_mul == operation) ||
33587 (details::e_div == operation)
33588 )
33589 {
33590 if (details::is_uv_node(branch[0]))
33591 {
33592 typedef details::uv_base_node<Type>* uvbn_ptr_t;
33593
33594 details::operator_type o = static_cast<uvbn_ptr_t>(branch[0])->operation();
33595
33596 if (details::e_neg == o)
33597 {
33598 const Type& v0 = static_cast<uvbn_ptr_t>(branch[0])->v();
33599
33600 details::free_node(*expr_gen.node_allocator_,branch[0]);
33601
33602 switch (operation)
33603 {
33604 case details::e_add : return expr_gen.node_allocator_->
33605 template allocate_rr<typename details::
33606 vov_node<Type,details::sub_op<Type> > >(v,v0);
33607
33608 case details::e_sub : return expr_gen(details::e_neg,
33609 expr_gen.node_allocator_->
33610 template allocate_rr<typename details::
33611 vov_node<Type,details::add_op<Type> > >(v0,v));
33612
33613 case details::e_mul : return expr_gen(details::e_neg,
33614 expr_gen.node_allocator_->
33615 template allocate_rr<typename details::
33616 vov_node<Type,details::mul_op<Type> > >(v0,v));
33617
33618 case details::e_div : return expr_gen(details::e_neg,
33619 expr_gen.node_allocator_->
33620 template allocate_rr<typename details::
33621 vov_node<Type,details::div_op<Type> > >(v0,v));
33622 default : break;
33623 }
33624 }
33625 }
33626 }
33627
33628 switch (operation)
33629 {
33630 #define case_stmt(op0, op1) \
33631 case op0 : return expr_gen.node_allocator_-> \
33632 template allocate_cr<typename details::bov_node<Type,op1<Type> > > \
33633 (branch[0], v); \
33634
33637 #undef case_stmt
33638 default : return error_node();
33639 }
33640 }
33641 };
33642
33643 struct synthesize_cob_expression
33644 {
33645 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
33646 const details::operator_type& operation,
33647 expression_node_ptr (&branch)[2])
33648 {
33649 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
33650
33651 details::free_node(*expr_gen.node_allocator_,branch[0]);
33652
33653 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
33654 {
33655 details::free_node(*expr_gen.node_allocator_,branch[1]);
33656
33657 return expr_gen(T(0));
33658 }
33659 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
33660 {
33661 details::free_node(*expr_gen.node_allocator_, branch[1]);
33662
33663 return expr_gen(T(0));
33664 }
33665 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
33666 return branch[1];
33667 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
33668 return branch[1];
33669
33670 if (details::is_cob_node(branch[1]))
33671 {
33672
33673
33674
33675 if (
33676 (details::e_mul == operation) ||
33677 (details::e_add == operation)
33678 )
33679 {
33680 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
33681
33682 if (operation == cobnode->operation())
33683 {
33684 switch (operation)
33685 {
33686 case details::e_add : cobnode->set_c(c + cobnode->c()); break;
33687 case details::e_mul : cobnode->set_c(c * cobnode->c()); break;
33688 default : return error_node();
33689 }
33690
33691 return cobnode;
33692 }
33693 }
33694
33695 if (operation == details::e_mul)
33696 {
33697 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
33698 details::operator_type cob_opr = cobnode->operation();
33699
33700 if (
33701 (details::e_div == cob_opr) ||
33702 (details::e_mul == cob_opr)
33703 )
33704 {
33705 switch (cob_opr)
33706 {
33707 case details::e_div : cobnode->set_c(c * cobnode->c()); break;
33708 case details::e_mul : cobnode->set_c(cobnode->c() / c); break;
33709 default : return error_node();
33710 }
33711
33712 return cobnode;
33713 }
33714 }
33715 else if (operation == details::e_div)
33716 {
33717 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
33718 details::operator_type cob_opr = cobnode->operation();
33719
33720 if (
33721 (details::e_div == cob_opr) ||
33722 (details::e_mul == cob_opr)
33723 )
33724 {
33725 details::expression_node<Type>* new_cobnode = error_node();
33726
33727 switch (cob_opr)
33728 {
33729 case details::e_div : new_cobnode = expr_gen.node_allocator_->
33730 template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
33731 (c / cobnode->c(), cobnode->move_branch(0));
33732 break;
33733
33734 case details::e_mul : new_cobnode = expr_gen.node_allocator_->
33735 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
33736 (c / cobnode->c(), cobnode->move_branch(0));
33737 break;
33738
33739 default : return error_node();
33740 }
33741
33742 details::free_node(*expr_gen.node_allocator_,branch[1]);
33743
33744 return new_cobnode;
33745 }
33746 }
33747 }
33748 #ifndef exprtk_disable_enhanced_features
33749 else if (details::is_sf3ext_node(branch[1]))
33750 {
33751 expression_node_ptr result = error_node();
33752
33753 const bool synthesis_result =
33754 synthesize_sf4ext_expression::template compile_right<ctype>
33755 (expr_gen, c, operation, branch[1], result);
33756
33757 if (synthesis_result)
33758 {
33759 details::free_node(*expr_gen.node_allocator_,branch[1]);
33760
33761 return result;
33762 }
33763 }
33764 #endif
33765
33766 switch (operation)
33767 {
33768 #define case_stmt(op0, op1) \
33769 case op0 : return expr_gen.node_allocator_-> \
33770 template allocate_tt<typename details::cob_node<Type,op1<Type> > > \
33771 (c, branch[1]); \
33772
33775 #undef case_stmt
33776 default : return error_node();
33777 }
33778 }
33779 };
33780
33781 struct synthesize_boc_expression
33782 {
33783 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
33784 const details::operator_type& operation,
33785 expression_node_ptr (&branch)[2])
33786 {
33787 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
33788
33789 details::free_node(*(expr_gen.node_allocator_), branch[1]);
33790
33791 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
33792 {
33793 details::free_node(*expr_gen.node_allocator_, branch[0]);
33794
33795 return expr_gen(T(0));
33796 }
33797 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
33798 {
33799 details::free_node(*expr_gen.node_allocator_, branch[0]);
33800
33801 return expr_gen(std::numeric_limits<T>::quiet_NaN());
33802 }
33803 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
33804 return branch[0];
33805 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
33806 return branch[0];
33807
33808 if (details::is_boc_node(branch[0]))
33809 {
33810
33811
33812
33813 if (
33814 (details::e_mul == operation) ||
33815 (details::e_add == operation)
33816 )
33817 {
33818 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
33819
33820 if (operation == bocnode->operation())
33821 {
33822 switch (operation)
33823 {
33824 case details::e_add : bocnode->set_c(c + bocnode->c()); break;
33825 case details::e_mul : bocnode->set_c(c * bocnode->c()); break;
33826 default : return error_node();
33827 }
33828
33829 return bocnode;
33830 }
33831 }
33832 else if (operation == details::e_div)
33833 {
33834 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
33835 details::operator_type boc_opr = bocnode->operation();
33836
33837 if (
33838 (details::e_div == boc_opr) ||
33839 (details::e_mul == boc_opr)
33840 )
33841 {
33842 switch (boc_opr)
33843 {
33844 case details::e_div : bocnode->set_c(c * bocnode->c()); break;
33845 case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
33846 default : return error_node();
33847 }
33848
33849 return bocnode;
33850 }
33851 }
33852 else if (operation == details::e_pow)
33853 {
33854
33855 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
33856 details::operator_type boc_opr = bocnode->operation();
33857
33858 if (details::e_pow == boc_opr)
33859 {
33860 bocnode->set_c(bocnode->c() * c);
33861
33862 return bocnode;
33863 }
33864 }
33865 }
33866
33867 #ifndef exprtk_disable_enhanced_features
33868 if (details::is_sf3ext_node(branch[0]))
33869 {
33870 expression_node_ptr result = error_node();
33871
33872 const bool synthesis_result =
33873 synthesize_sf4ext_expression::template compile_left<ctype>
33874 (expr_gen, c, operation, branch[0], result);
33875
33876 if (synthesis_result)
33877 {
33878 free_node(*expr_gen.node_allocator_, branch[0]);
33879
33880 return result;
33881 }
33882 }
33883 #endif
33884
33885 switch (operation)
33886 {
33887 #define case_stmt(op0, op1) \
33888 case op0 : return expr_gen.node_allocator_-> \
33889 template allocate_cr<typename details::boc_node<Type,op1<Type> > > \
33890 (branch[0], c); \
33891
33894 #undef case_stmt
33895 default : return error_node();
33896 }
33897 }
33898 };
33899
33900 struct synthesize_cocob_expression
33901 {
33902 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
33903 const details::operator_type& operation,
33904 expression_node_ptr (&branch)[2])
33905 {
33906 expression_node_ptr result = error_node();
33907
33908
33909 if (details::is_cob_node(branch[0]))
33910 {
33911 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[0]);
33912
33913 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
33914
33915 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
33916 {
33917 details::free_node(*expr_gen.node_allocator_, branch[0]);
33918 details::free_node(*expr_gen.node_allocator_, branch[1]);
33919
33920 return expr_gen(T(0));
33921 }
33922 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
33923 {
33924 details::free_node(*expr_gen.node_allocator_, branch[0]);
33925 details::free_node(*expr_gen.node_allocator_, branch[1]);
33926
33927 return expr_gen(T(std::numeric_limits<T>::quiet_NaN()));
33928 }
33929 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
33930 {
33931 details::free_node(*expr_gen.node_allocator_, branch[1]);
33932
33933 return branch[0];
33934 }
33935 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
33936 {
33937 details::free_node(*expr_gen.node_allocator_, branch[1]);
33938
33939 return branch[0];
33940 }
33941 else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
33942 {
33943 details::free_node(*expr_gen.node_allocator_, branch[1]);
33944
33945 return branch[0];
33946 }
33947
33948 const bool op_addsub = (details::e_add == cobnode->operation()) ||
33949 (details::e_sub == cobnode->operation()) ;
33950
33951 if (op_addsub)
33952 {
33953 switch (operation)
33954 {
33955 case details::e_add : cobnode->set_c(cobnode->c() + c); break;
33956 case details::e_sub : cobnode->set_c(cobnode->c() - c); break;
33957 default : return error_node();
33958 }
33959
33960 result = cobnode;
33961 }
33962 else if (details::e_mul == cobnode->operation())
33963 {
33964 switch (operation)
33965 {
33966 case details::e_mul : cobnode->set_c(cobnode->c() * c); break;
33967 case details::e_div : cobnode->set_c(cobnode->c() / c); break;
33968 default : return error_node();
33969 }
33970
33971 result = cobnode;
33972 }
33973 else if (details::e_div == cobnode->operation())
33974 {
33975 if (details::e_mul == operation)
33976 {
33977 cobnode->set_c(cobnode->c() * c);
33978 result = cobnode;
33979 }
33980 else if (details::e_div == operation)
33981 {
33982 result = expr_gen.node_allocator_->
33983 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
33984 (cobnode->c() / c, cobnode->move_branch(0));
33985
33986 details::free_node(*expr_gen.node_allocator_, branch[0]);
33987 }
33988 }
33989
33990 if (result)
33991 {
33992 details::free_node(*expr_gen.node_allocator_,branch[1]);
33993 }
33994 }
33995
33996
33997 else if (details::is_cob_node(branch[1]))
33998 {
33999 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
34000
34001 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
34002
34003 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
34004 {
34005 details::free_node(*expr_gen.node_allocator_, branch[0]);
34006 details::free_node(*expr_gen.node_allocator_, branch[1]);
34007
34008 return expr_gen(T(0));
34009 }
34010 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
34011 {
34012 details::free_node(*expr_gen.node_allocator_, branch[0]);
34013 details::free_node(*expr_gen.node_allocator_, branch[1]);
34014
34015 return expr_gen(T(0));
34016 }
34017 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
34018 {
34019 details::free_node(*expr_gen.node_allocator_, branch[0]);
34020
34021 return branch[1];
34022 }
34023 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
34024 {
34025 details::free_node(*expr_gen.node_allocator_, branch[0]);
34026
34027 return branch[1];
34028 }
34029
34030 if (details::e_add == cobnode->operation())
34031 {
34032 if (details::e_add == operation)
34033 {
34034 cobnode->set_c(c + cobnode->c());
34035 result = cobnode;
34036 }
34037 else if (details::e_sub == operation)
34038 {
34039 result = expr_gen.node_allocator_->
34040 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
34041 (c - cobnode->c(), cobnode->move_branch(0));
34042
34043 details::free_node(*expr_gen.node_allocator_,branch[1]);
34044 }
34045 }
34046 else if (details::e_sub == cobnode->operation())
34047 {
34048 if (details::e_add == operation)
34049 {
34050 cobnode->set_c(c + cobnode->c());
34051 result = cobnode;
34052 }
34053 else if (details::e_sub == operation)
34054 {
34055 result = expr_gen.node_allocator_->
34056 template allocate_tt<typename details::cob_node<Type,details::add_op<Type> > >
34057 (c - cobnode->c(), cobnode->move_branch(0));
34058
34059 details::free_node(*expr_gen.node_allocator_,branch[1]);
34060 }
34061 }
34062 else if (details::e_mul == cobnode->operation())
34063 {
34064 if (details::e_mul == operation)
34065 {
34066 cobnode->set_c(c * cobnode->c());
34067 result = cobnode;
34068 }
34069 else if (details::e_div == operation)
34070 {
34071 result = expr_gen.node_allocator_->
34072 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
34073 (c / cobnode->c(), cobnode->move_branch(0));
34074
34075 details::free_node(*expr_gen.node_allocator_,branch[1]);
34076 }
34077 }
34078 else if (details::e_div == cobnode->operation())
34079 {
34080 if (details::e_mul == operation)
34081 {
34082 cobnode->set_c(c * cobnode->c());
34083 result = cobnode;
34084 }
34085 else if (details::e_div == operation)
34086 {
34087 result = expr_gen.node_allocator_->
34088 template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
34089 (c / cobnode->c(), cobnode->move_branch(0));
34090
34091 details::free_node(*expr_gen.node_allocator_,branch[1]);
34092 }
34093 }
34094
34095 if (result)
34096 {
34097 details::free_node(*expr_gen.node_allocator_,branch[0]);
34098 }
34099 }
34100
34101 return result;
34102 }
34103 };
34104
34105 struct synthesize_coboc_expression
34106 {
34107 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34108 const details::operator_type& operation,
34109 expression_node_ptr (&branch)[2])
34110 {
34111 expression_node_ptr result = error_node();
34112
34113
34114 if (details::is_boc_node(branch[0]))
34115 {
34116 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
34117
34118 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
34119
34120 if (details::e_add == bocnode->operation())
34121 {
34122 switch (operation)
34123 {
34124 case details::e_add : bocnode->set_c(bocnode->c() + c); break;
34125 case details::e_sub : bocnode->set_c(bocnode->c() - c); break;
34126 default : return error_node();
34127 }
34128
34129 result = bocnode;
34130 }
34131 else if (details::e_mul == bocnode->operation())
34132 {
34133 switch (operation)
34134 {
34135 case details::e_mul : bocnode->set_c(bocnode->c() * c); break;
34136 case details::e_div : bocnode->set_c(bocnode->c() / c); break;
34137 default : return error_node();
34138 }
34139
34140 result = bocnode;
34141 }
34142 else if (details::e_sub == bocnode->operation())
34143 {
34144 if (details::e_add == operation)
34145 {
34146 result = expr_gen.node_allocator_->
34147 template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
34148 (bocnode->move_branch(0), c - bocnode->c());
34149
34150 details::free_node(*expr_gen.node_allocator_,branch[0]);
34151 }
34152 else if (details::e_sub == operation)
34153 {
34154 bocnode->set_c(bocnode->c() + c);
34155 result = bocnode;
34156 }
34157 }
34158 else if (details::e_div == bocnode->operation())
34159 {
34160 switch (operation)
34161 {
34162 case details::e_div : bocnode->set_c(bocnode->c() * c); break;
34163 case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
34164 default : return error_node();
34165 }
34166
34167 result = bocnode;
34168 }
34169
34170 if (result)
34171 {
34172 details::free_node(*expr_gen.node_allocator_, branch[1]);
34173 }
34174 }
34175
34176
34177 else if (details::is_boc_node(branch[1]))
34178 {
34179 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[1]);
34180
34181 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
34182
34183 if (details::e_add == bocnode->operation())
34184 {
34185 if (details::e_add == operation)
34186 {
34187 bocnode->set_c(c + bocnode->c());
34188 result = bocnode;
34189 }
34190 else if (details::e_sub == operation)
34191 {
34192 result = expr_gen.node_allocator_->
34193 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
34194 (c - bocnode->c(), bocnode->move_branch(0));
34195
34196 details::free_node(*expr_gen.node_allocator_,branch[1]);
34197 }
34198 }
34199 else if (details::e_sub == bocnode->operation())
34200 {
34201 if (details::e_add == operation)
34202 {
34203 result = expr_gen.node_allocator_->
34204 template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
34205 (bocnode->move_branch(0), c - bocnode->c());
34206
34207 details::free_node(*expr_gen.node_allocator_,branch[1]);
34208 }
34209 else if (details::e_sub == operation)
34210 {
34211 result = expr_gen.node_allocator_->
34212 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
34213 (c + bocnode->c(), bocnode->move_branch(0));
34214
34215 details::free_node(*expr_gen.node_allocator_,branch[1]);
34216 }
34217 }
34218 else if (details::e_mul == bocnode->operation())
34219 {
34220 if (details::e_mul == operation)
34221 {
34222 bocnode->set_c(c * bocnode->c());
34223 result = bocnode;
34224 }
34225 else if (details::e_div == operation)
34226 {
34227 result = expr_gen.node_allocator_->
34228 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
34229 (c / bocnode->c(), bocnode->move_branch(0));
34230
34231 details::free_node(*expr_gen.node_allocator_,branch[1]);
34232 }
34233 }
34234 else if (details::e_div == bocnode->operation())
34235 {
34236 if (details::e_mul == operation)
34237 {
34238 bocnode->set_c(bocnode->c() / c);
34239 result = bocnode;
34240 }
34241 else if (details::e_div == operation)
34242 {
34243 result = expr_gen.node_allocator_->
34244 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
34245 (c * bocnode->c(), bocnode->move_branch(0));
34246
34247 details::free_node(*expr_gen.node_allocator_,branch[1]);
34248 }
34249 }
34250
34251 if (result)
34252 {
34253 details::free_node(*expr_gen.node_allocator_,branch[0]);
34254 }
34255 }
34256
34257 return result;
34258 }
34259 };
34260
34261 #ifndef exprtk_disable_enhanced_features
34262 inline bool synthesize_expression(const details::operator_type& operation,
34263 expression_node_ptr (&branch)[2],
34264 expression_node_ptr& result)
34265 {
34266 result = error_node();
34267
34268 if (!operation_optimisable(operation))
34269 return false;
34270
34271 const std::string node_id = branch_to_id(branch);
34272
34273 const typename synthesize_map_t::iterator itr = synthesize_map_.find(node_id);
34274
34275 if (synthesize_map_.end() != itr)
34276 {
34277 result = itr->second((*this), operation, branch);
34278
34279 return true;
34280 }
34281 else
34282 return false;
34283 }
34284
34285 struct synthesize_vov_expression
34286 {
34287 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34288 const details::operator_type& operation,
34289 expression_node_ptr (&branch)[2])
34290 {
34291 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
34292 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
34293
34294 switch (operation)
34295 {
34296 #define case_stmt(op0, op1) \
34297 case op0 : return expr_gen.node_allocator_-> \
34298 template allocate_rr<typename details::vov_node<Type,op1<Type> > > \
34299 (v1, v2); \
34300
34303 #undef case_stmt
34304 default : return error_node();
34305 }
34306 }
34307 };
34308
34309 struct synthesize_cov_expression
34310 {
34311 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34312 const details::operator_type& operation,
34313 expression_node_ptr (&branch)[2])
34314 {
34315 const Type c =
static_cast<details::literal_node<Type>*
> (branch[0])->
value();
34316 const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref ();
34317
34318 details::free_node(*(expr_gen.node_allocator_),branch[0]);
34319
34320 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
34321 return expr_gen(T(0));
34322 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
34323 return expr_gen(T(0));
34324 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
34325 return static_cast<details::variable_node<Type>*>(branch[1]);
34326 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
34327 return static_cast<details::variable_node<Type>*>(branch[1]);
34328
34329 switch (operation)
34330 {
34331 #define case_stmt(op0, op1) \
34332 case op0 : return expr_gen.node_allocator_-> \
34333 template allocate_cr<typename details::cov_node<Type,op1<Type> > > \
34334 (c, v); \
34335
34338 #undef case_stmt
34339 default : return error_node();
34340 }
34341 }
34342 };
34343
34344 struct synthesize_voc_expression
34345 {
34346 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34347 const details::operator_type& operation,
34348 expression_node_ptr (&branch)[2])
34349 {
34350 const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref ();
34351 const Type c =
static_cast<details::literal_node<Type>*
> (branch[1])->
value();
34352
34353 details::free_node(*(expr_gen.node_allocator_), branch[1]);
34354
34355 if (expr_gen.cardinal_pow_optimisable(operation,c))
34356 {
34357 if (std::equal_to<T>()(T(1),c))
34358 return branch[0];
34359 else
34360 return expr_gen.cardinal_pow_optimisation(v,c);
34361 }
34362 else if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
34363 return expr_gen(T(0));
34364 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
34365 return expr_gen(std::numeric_limits<T>::quiet_NaN());
34366 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
34367 return static_cast<details::variable_node<Type>*>(branch[0]);
34368 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
34369 return static_cast<details::variable_node<Type>*>(branch[0]);
34370 else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
34371 return static_cast<details::variable_node<Type>*>(branch[0]);
34372
34373 switch (operation)
34374 {
34375 #define case_stmt(op0, op1) \
34376 case op0 : return expr_gen.node_allocator_-> \
34377 template allocate_rc<typename details::voc_node<Type,op1<Type> > > \
34378 (v, c); \
34379
34382 #undef case_stmt
34383 default : return error_node();
34384 }
34385 }
34386 };
34387
34388 struct synthesize_sf3ext_expression
34389 {
34390 template <typename T0, typename T1, typename T2>
34391 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34392 const details::operator_type& sf3opr,
34393 T0 t0, T1 t1, T2 t2)
34394 {
34395 switch (sf3opr)
34396 {
34397 #define case_stmt(op) \
34398 case details::e_sf##op : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,details::sf##op##_op<Type> >:: \
34399 allocate(*(expr_gen.node_allocator_), t0, t1, t2); \
34400
34409 #undef case_stmt
34410 default : return error_node();
34411 }
34412 }
34413
34414 template <typename T0, typename T1, typename T2>
34415 static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
34416 T0 t0, T1 t1, T2 t2,
34417 expression_node_ptr& result)
34418 {
34419 details::operator_type sf3opr;
34420
34421 if (!expr_gen.sf3_optimisable(id,sf3opr))
34422 return false;
34423 else
34424 result = synthesize_sf3ext_expression::template process<T0, T1, T2>
34425 (expr_gen, sf3opr, t0, t1, t2);
34426
34427 return true;
34428 }
34429 };
34430
34431 struct synthesize_sf4ext_expression
34432 {
34433 template <typename T0, typename T1, typename T2, typename T3>
34434 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34435 const details::operator_type& sf4opr,
34436 T0 t0, T1 t1, T2 t2, T3 t3)
34437 {
34438 switch (sf4opr)
34439 {
34440 #define case_stmt0(op) \
34441 case details::e_sf##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sf##op##_op<Type> >:: \
34442 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
34443
34444 #define case_stmt1(op) \
34445 case details::e_sf4ext##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sfext##op##_op<Type> >:: \
34446 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
34447
34457
34474
34475 #undef case_stmt0
34476 #undef case_stmt1
34477 default : return error_node();
34478 }
34479 }
34480
34481 template <typename T0, typename T1, typename T2, typename T3>
34482 static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
34483 T0 t0, T1 t1, T2 t2, T3 t3,
34484 expression_node_ptr& result)
34485 {
34486 details::operator_type sf4opr;
34487
34488 if (!expr_gen.sf4_optimisable(id,sf4opr))
34489 return false;
34490 else
34491 result = synthesize_sf4ext_expression::template process<T0, T1, T2, T3>
34492 (expr_gen, sf4opr, t0, t1, t2, t3);
34493
34494 return true;
34495 }
34496
34497
34498 template <typename ExternalType>
34499 static inline bool compile_right(expression_generator<Type>& expr_gen,
34500 ExternalType t,
34501 const details::operator_type& operation,
34502 expression_node_ptr& sf3node,
34503 expression_node_ptr& result)
34504 {
34505 if (!details::is_sf3ext_node(sf3node))
34506 return false;
34507
34508 typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
34509
34510 sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
34511 const std::string id = "t" + expr_gen.to_str(operation) + "(" + n->type_id() + ")";
34512
34513 switch (n->type())
34514 {
34515 case details::expression_node<Type>::e_covoc : return compile_right_impl
34516 <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
34517 (expr_gen, id, t, sf3node, result);
34518
34519 case details::expression_node<Type>::e_covov : return compile_right_impl
34520 <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
34521 (expr_gen, id, t, sf3node, result);
34522
34523 case details::expression_node<Type>::e_vocov : return compile_right_impl
34524 <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
34525 (expr_gen, id, t, sf3node, result);
34526
34527 case details::expression_node<Type>::e_vovoc : return compile_right_impl
34528 <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
34529 (expr_gen, id, t, sf3node, result);
34530
34531 case details::expression_node<Type>::e_vovov : return compile_right_impl
34532 <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
34533 (expr_gen, id, t, sf3node, result);
34534
34535 default : return false;
34536 }
34537 }
34538
34539
34540 template <typename ExternalType>
34541 static inline bool compile_left(expression_generator<Type>& expr_gen,
34542 ExternalType t,
34543 const details::operator_type& operation,
34544 expression_node_ptr& sf3node,
34545 expression_node_ptr& result)
34546 {
34547 if (!details::is_sf3ext_node(sf3node))
34548 return false;
34549
34550 typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
34551
34552 sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
34553
34554 const std::string id = "(" + n->type_id() + ")" + expr_gen.to_str(operation) + "t";
34555
34556 switch (n->type())
34557 {
34558 case details::expression_node<Type>::e_covoc : return compile_left_impl
34559 <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
34560 (expr_gen, id, t, sf3node, result);
34561
34562 case details::expression_node<Type>::e_covov : return compile_left_impl
34563 <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
34564 (expr_gen, id, t, sf3node, result);
34565
34566 case details::expression_node<Type>::e_vocov : return compile_left_impl
34567 <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
34568 (expr_gen, id, t, sf3node, result);
34569
34570 case details::expression_node<Type>::e_vovoc : return compile_left_impl
34571 <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
34572 (expr_gen, id, t, sf3node, result);
34573
34574 case details::expression_node<Type>::e_vovov : return compile_left_impl
34575 <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
34576 (expr_gen, id, t, sf3node, result);
34577
34578 default : return false;
34579 }
34580 }
34581
34582 template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
34583 static inline bool compile_right_impl(expression_generator<Type>& expr_gen,
34584 const std::string& id,
34585 ExternalType t,
34586 expression_node_ptr& node,
34587 expression_node_ptr& result)
34588 {
34589 SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
34590
34591 if (n)
34592 {
34593 T0 t0 = n->t0();
34594 T1 t1 = n->t1();
34595 T2 t2 = n->t2();
34596
34597 return synthesize_sf4ext_expression::template compile<ExternalType, T0, T1, T2>
34598 (expr_gen, id, t, t0, t1, t2, result);
34599 }
34600 else
34601 return false;
34602 }
34603
34604 template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
34605 static inline bool compile_left_impl(expression_generator<Type>& expr_gen,
34606 const std::string& id,
34607 ExternalType t,
34608 expression_node_ptr& node,
34609 expression_node_ptr& result)
34610 {
34611 SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
34612
34613 if (n)
34614 {
34615 T0 t0 = n->t0();
34616 T1 t1 = n->t1();
34617 T2 t2 = n->t2();
34618
34619 return synthesize_sf4ext_expression::template compile<T0, T1, T2, ExternalType>
34620 (expr_gen, id, t0, t1, t2, t, result);
34621 }
34622 else
34623 return false;
34624 }
34625 };
34626
34627 struct synthesize_vovov_expression0
34628 {
34629 typedef typename vovov_t::type0 node_type;
34630 typedef typename vovov_t::sf3_type sf3_type;
34631
34632 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34633 const details::operator_type& operation,
34634 expression_node_ptr (&branch)[2])
34635 {
34636
34637 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
34638 const Type& v0 = vov->v0();
34639 const Type& v1 = vov->v1();
34640 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
34641 const details::operator_type o0 = vov->operation();
34642 const details::operator_type o1 = operation;
34643
34644 details::free_node(*(expr_gen.node_allocator_),branch[0]);
34645
34646 expression_node_ptr result = error_node();
34647
34648 if (expr_gen.parser_->settings_.strength_reduction_enabled())
34649 {
34650
34651 if ((details::e_div == o0) && (details::e_div == o1))
34652 {
34653 const bool synthesis_result =
34654 synthesize_sf3ext_expression::
34655 template compile<vtype, vtype, vtype>(expr_gen, "t/(t*t)", v0, v1, v2, result);
34656
34657 exprtk_debug((
"(v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)\n"));
34658
34659 return (synthesis_result) ? result : error_node();
34660 }
34661 }
34662
34663 const bool synthesis_result =
34664 synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
34665 (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
34666
34667 if (synthesis_result)
34668 return result;
34669
34670 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34671 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34672
34673 if (!expr_gen.valid_operator(o0,f0))
34674 return error_node();
34675 else if (!expr_gen.valid_operator(o1,f1))
34676 return error_node();
34677 else
34678 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
34679 }
34680
34681 static inline std::string id(expression_generator<Type>& expr_gen,
34682 const details::operator_type o0,
34683 const details::operator_type o1)
34684 {
34685 return details::build_string()
34686 << "(t" << expr_gen.to_str(o0)
34687 << "t)" << expr_gen.to_str(o1)
34688 << "t";
34689 }
34690 };
34691
34692 struct synthesize_vovov_expression1
34693 {
34694 typedef typename vovov_t::type1 node_type;
34695 typedef typename vovov_t::sf3_type sf3_type;
34696
34697 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34698 const details::operator_type& operation,
34699 expression_node_ptr (&branch)[2])
34700 {
34701
34702 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
34703 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
34704 const Type& v1 = vov->v0();
34705 const Type& v2 = vov->v1();
34706 const details::operator_type o0 = operation;
34707 const details::operator_type o1 = vov->operation();
34708
34709 details::free_node(*(expr_gen.node_allocator_),branch[1]);
34710
34711 expression_node_ptr result = error_node();
34712
34713 if (expr_gen.parser_->settings_.strength_reduction_enabled())
34714 {
34715
34716 if ((details::e_div == o0) && (details::e_div == o1))
34717 {
34718 const bool synthesis_result =
34719 synthesize_sf3ext_expression::
34720 template compile<vtype, vtype, vtype>(expr_gen, "(t*t)/t", v0, v2, v1, result);
34721
34722 exprtk_debug((
"v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1\n"));
34723
34724 return (synthesis_result) ? result : error_node();
34725 }
34726 }
34727
34728 const bool synthesis_result =
34729 synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
34730 (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
34731
34732 if (synthesis_result)
34733 return result;
34734
34735 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34736 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34737
34738 if (!expr_gen.valid_operator(o0,f0))
34739 return error_node();
34740 else if (!expr_gen.valid_operator(o1,f1))
34741 return error_node();
34742 else
34743 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
34744 }
34745
34746 static inline std::string id(expression_generator<Type>& expr_gen,
34747 const details::operator_type o0,
34748 const details::operator_type o1)
34749 {
34750 return details::build_string()
34751 << "t" << expr_gen.to_str(o0)
34752 << "(t" << expr_gen.to_str(o1)
34753 << "t)";
34754 }
34755 };
34756
34757 struct synthesize_vovoc_expression0
34758 {
34759 typedef typename vovoc_t::type0 node_type;
34760 typedef typename vovoc_t::sf3_type sf3_type;
34761
34762 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34763 const details::operator_type& operation,
34764 expression_node_ptr (&branch)[2])
34765 {
34766
34767 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
34768 const Type& v0 = vov->v0();
34769 const Type& v1 = vov->v1();
34770 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
34771 const details::operator_type o0 = vov->operation();
34772 const details::operator_type o1 = operation;
34773
34774 details::free_node(*(expr_gen.node_allocator_),branch[0]);
34775 details::free_node(*(expr_gen.node_allocator_),branch[1]);
34776
34777 expression_node_ptr result = error_node();
34778
34779 if (expr_gen.parser_->settings_.strength_reduction_enabled())
34780 {
34781
34782 if ((details::e_div == o0) && (details::e_div == o1))
34783 {
34784 const bool synthesis_result =
34785 synthesize_sf3ext_expression::
34786 template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
34787
34788 exprtk_debug((
"(v0 / v1) / c --> (vovoc) v0 / (v1 * c)\n"));
34789
34790 return (synthesis_result) ? result : error_node();
34791 }
34792 }
34793
34794 const bool synthesis_result =
34795 synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
34796 (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
34797
34798 if (synthesis_result)
34799 return result;
34800
34801 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34802 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34803
34804 if (!expr_gen.valid_operator(o0,f0))
34805 return error_node();
34806 else if (!expr_gen.valid_operator(o1,f1))
34807 return error_node();
34808 else
34809 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
34810 }
34811
34812 static inline std::string id(expression_generator<Type>& expr_gen,
34813 const details::operator_type o0,
34814 const details::operator_type o1)
34815 {
34816 return details::build_string()
34817 << "(t" << expr_gen.to_str(o0)
34818 << "t)" << expr_gen.to_str(o1)
34819 << "t";
34820 }
34821 };
34822
34823 struct synthesize_vovoc_expression1
34824 {
34825 typedef typename vovoc_t::type1 node_type;
34826 typedef typename vovoc_t::sf3_type sf3_type;
34827
34828 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34829 const details::operator_type& operation,
34830 expression_node_ptr (&branch)[2])
34831 {
34832
34833 const details::voc_base_node<Type>* voc = static_cast<const details::voc_base_node<Type>*>(branch[1]);
34834 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
34835 const Type& v1 = voc->v();
34836 const Type c = voc->c();
34837 const details::operator_type o0 = operation;
34838 const details::operator_type o1 = voc->operation();
34839
34840 details::free_node(*(expr_gen.node_allocator_),branch[1]);
34841
34842 expression_node_ptr result = error_node();
34843
34844 if (expr_gen.parser_->settings_.strength_reduction_enabled())
34845 {
34846
34847 if ((details::e_div == o0) && (details::e_div == o1))
34848 {
34849 const bool synthesis_result =
34850 synthesize_sf3ext_expression::
34851 template compile<vtype, ctype, vtype>(expr_gen, "(t*t)/t", v0, c, v1, result);
34852
34853 exprtk_debug((
"v0 / (v1 / c) --> (vocov) (v0 * c) / v1\n"));
34854
34855 return (synthesis_result) ? result : error_node();
34856 }
34857 }
34858
34859 const bool synthesis_result =
34860 synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
34861 (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
34862
34863 if (synthesis_result)
34864 return result;
34865
34866 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34867 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34868
34869 if (!expr_gen.valid_operator(o0,f0))
34870 return error_node();
34871 else if (!expr_gen.valid_operator(o1,f1))
34872 return error_node();
34873 else
34874 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
34875 }
34876
34877 static inline std::string id(expression_generator<Type>& expr_gen,
34878 const details::operator_type o0,
34879 const details::operator_type o1)
34880 {
34881 return details::build_string()
34882 << "t" << expr_gen.to_str(o0)
34883 << "(t" << expr_gen.to_str(o1)
34884 << "t)";
34885 }
34886 };
34887
34888 struct synthesize_vocov_expression0
34889 {
34890 typedef typename vocov_t::type0 node_type;
34891 typedef typename vocov_t::sf3_type sf3_type;
34892
34893 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34894 const details::operator_type& operation,
34895 expression_node_ptr (&branch)[2])
34896 {
34897
34898 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
34899 const Type& v0 = voc->v();
34900 const Type c = voc->c();
34901 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
34902 const details::operator_type o0 = voc->operation();
34903 const details::operator_type o1 = operation;
34904
34905 details::free_node(*(expr_gen.node_allocator_),branch[0]);
34906
34907 expression_node_ptr result = error_node();
34908
34909 if (expr_gen.parser_->settings_.strength_reduction_enabled())
34910 {
34911
34912 if ((details::e_div == o0) && (details::e_div == o1))
34913 {
34914 const bool synthesis_result =
34915 synthesize_sf3ext_expression::
34916 template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
34917
34918 exprtk_debug((
"(v0 / c) / v1 --> (vovoc) v0 / (v1 * c)\n"));
34919
34920 return (synthesis_result) ? result : error_node();
34921 }
34922 }
34923
34924 const bool synthesis_result =
34925 synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
34926 (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
34927
34928 if (synthesis_result)
34929 return result;
34930
34931 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34932 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34933
34934 if (!expr_gen.valid_operator(o0,f0))
34935 return error_node();
34936 else if (!expr_gen.valid_operator(o1,f1))
34937 return error_node();
34938 else
34939 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
34940 }
34941
34942 static inline std::string id(expression_generator<Type>& expr_gen,
34943 const details::operator_type o0,
34944 const details::operator_type o1)
34945 {
34946 return details::build_string()
34947 << "(t" << expr_gen.to_str(o0)
34948 << "t)" << expr_gen.to_str(o1)
34949 << "t";
34950 }
34951 };
34952
34953 struct synthesize_vocov_expression1
34954 {
34955 typedef typename vocov_t::type1 node_type;
34956 typedef typename vocov_t::sf3_type sf3_type;
34957
34958 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
34959 const details::operator_type& operation,
34960 expression_node_ptr (&branch)[2])
34961 {
34962
34963 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
34964 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
34965 const Type c = cov->c();
34966 const Type& v1 = cov->v();
34967 const details::operator_type o0 = operation;
34968 const details::operator_type o1 = cov->operation();
34969
34970 details::free_node(*(expr_gen.node_allocator_),branch[1]);
34971
34972 expression_node_ptr result = error_node();
34973
34974 if (expr_gen.parser_->settings_.strength_reduction_enabled())
34975 {
34976
34977 if ((details::e_div == o0) && (details::e_div == o1))
34978 {
34979 const bool synthesis_result =
34980 synthesize_sf3ext_expression::
34981 template compile<vtype, vtype, ctype>(expr_gen, "(t*t)/t", v0, v1, c, result);
34982
34983 exprtk_debug((
"v0 / (c / v1) --> (vovoc) (v0 * v1) / c\n"));
34984
34985 return (synthesis_result) ? result : error_node();
34986 }
34987 }
34988
34989 const bool synthesis_result =
34990 synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
34991 (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
34992
34993 if (synthesis_result)
34994 return result;
34995
34996 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34997 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34998
34999 if (!expr_gen.valid_operator(o0,f0))
35000 return error_node();
35001 else if (!expr_gen.valid_operator(o1,f1))
35002 return error_node();
35003 else
35004 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
35005 }
35006
35007 static inline std::string id(expression_generator<Type>& expr_gen,
35008 const details::operator_type o0,
35009 const details::operator_type o1)
35010 {
35011 return details::build_string()
35012 << "t" << expr_gen.to_str(o0)
35013 << "(t" << expr_gen.to_str(o1)
35014 << "t)";
35015 }
35016 };
35017
35018 struct synthesize_covov_expression0
35019 {
35020 typedef typename covov_t::type0 node_type;
35021 typedef typename covov_t::sf3_type sf3_type;
35022
35023 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35024 const details::operator_type& operation,
35025 expression_node_ptr (&branch)[2])
35026 {
35027
35028 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
35029 const Type c = cov->c();
35030 const Type& v0 = cov->v();
35031 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
35032 const details::operator_type o0 = cov->operation();
35033 const details::operator_type o1 = operation;
35034
35035 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35036
35037 expression_node_ptr result = error_node();
35038
35039 if (expr_gen.parser_->settings_.strength_reduction_enabled())
35040 {
35041
35042 if ((details::e_div == o0) && (details::e_div == o1))
35043 {
35044 const bool synthesis_result =
35045 synthesize_sf3ext_expression::
35046 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", c, v0, v1, result);
35047
35048 exprtk_debug((
"(c / v0) / v1 --> (covov) c / (v0 * v1)\n"));
35049
35050 return (synthesis_result) ? result : error_node();
35051 }
35052 }
35053
35054 const bool synthesis_result =
35055 synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
35056 (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
35057
35058 if (synthesis_result)
35059 return result;
35060
35061 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35062 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35063
35064 if (!expr_gen.valid_operator(o0,f0))
35065 return error_node();
35066 else if (!expr_gen.valid_operator(o1,f1))
35067 return error_node();
35068 else
35069 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
35070 }
35071
35072 static inline std::string id(expression_generator<Type>& expr_gen,
35073 const details::operator_type o0,
35074 const details::operator_type o1)
35075 {
35076 return details::build_string()
35077 << "(t" << expr_gen.to_str(o0)
35078 << "t)" << expr_gen.to_str(o1)
35079 << "t";
35080 }
35081 };
35082
35083 struct synthesize_covov_expression1
35084 {
35085 typedef typename covov_t::type1 node_type;
35086 typedef typename covov_t::sf3_type sf3_type;
35087
35088 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35089 const details::operator_type& operation,
35090 expression_node_ptr (&branch)[2])
35091 {
35092
35093 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
35094 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
35095 const Type& v0 = vov->v0();
35096 const Type& v1 = vov->v1();
35097 const details::operator_type o0 = operation;
35098 const details::operator_type o1 = vov->operation();
35099
35100 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35101 details::free_node(*(expr_gen.node_allocator_),branch[1]);
35102
35103 expression_node_ptr result = error_node();
35104
35105 if (expr_gen.parser_->settings_.strength_reduction_enabled())
35106 {
35107
35108 if ((details::e_div == o0) && (details::e_div == o1))
35109 {
35110 const bool synthesis_result =
35111 synthesize_sf3ext_expression::
35112 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", c, v1, v0, result);
35113
35114 exprtk_debug((
"c / (v0 / v1) --> (covov) (c * v1) / v0\n"));
35115
35116 return (synthesis_result) ? result : error_node();
35117 }
35118 }
35119
35120 const bool synthesis_result =
35121 synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
35122 (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
35123
35124 if (synthesis_result)
35125 return result;
35126
35127 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35128 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35129
35130 if (!expr_gen.valid_operator(o0,f0))
35131 return error_node();
35132 else if (!expr_gen.valid_operator(o1,f1))
35133 return error_node();
35134 else
35135 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
35136 }
35137
35138 static inline std::string id(expression_generator<Type>& expr_gen,
35139 const details::operator_type o0,
35140 const details::operator_type o1)
35141 {
35142 return details::build_string()
35143 << "t" << expr_gen.to_str(o0)
35144 << "(t" << expr_gen.to_str(o1)
35145 << "t)";
35146 }
35147 };
35148
35149 struct synthesize_covoc_expression0
35150 {
35151 typedef typename covoc_t::type0 node_type;
35152 typedef typename covoc_t::sf3_type sf3_type;
35153
35154 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35155 const details::operator_type& operation,
35156 expression_node_ptr (&branch)[2])
35157 {
35158
35159 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
35160 const Type c0 = cov->c();
35161 const Type& v = cov->v();
35162 const Type c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
35163 const details::operator_type o0 = cov->operation();
35164 const details::operator_type o1 = operation;
35165
35166 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35167 details::free_node(*(expr_gen.node_allocator_),branch[1]);
35168
35169 expression_node_ptr result = error_node();
35170
35171 if (expr_gen.parser_->settings_.strength_reduction_enabled())
35172 {
35173
35174 if ((details::e_add == o0) && (details::e_add == o1))
35175 {
35176 exprtk_debug((
"(c0 + v) + c1 --> (cov) (c0 + c1) + v\n"));
35177
35178 return expr_gen.node_allocator_->
35179 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
35180 }
35181
35182 else if ((details::e_add == o0) && (details::e_sub == o1))
35183 {
35184 exprtk_debug((
"(c0 + v) - c1 --> (cov) (c0 - c1) + v\n"));
35185
35186 return expr_gen.node_allocator_->
35187 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
35188 }
35189
35190 else if ((details::e_sub == o0) && (details::e_add == o1))
35191 {
35192 exprtk_debug((
"(c0 - v) + c1 --> (cov) (c0 + c1) - v\n"));
35193
35194 return expr_gen.node_allocator_->
35195 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
35196 }
35197
35198 else if ((details::e_sub == o0) && (details::e_sub == o1))
35199 {
35200 exprtk_debug((
"(c0 - v) - c1 --> (cov) (c0 - c1) - v\n"));
35201
35202 return expr_gen.node_allocator_->
35203 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
35204 }
35205
35206 else if ((details::e_mul == o0) && (details::e_mul == o1))
35207 {
35208 exprtk_debug((
"(c0 * v) * c1 --> (cov) (c0 * c1) * v\n"));
35209
35210 return expr_gen.node_allocator_->
35211 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
35212 }
35213
35214 else if ((details::e_mul == o0) && (details::e_div == o1))
35215 {
35216 exprtk_debug((
"(c0 * v) / c1 --> (cov) (c0 / c1) * v\n"));
35217
35218 return expr_gen.node_allocator_->
35219 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
35220 }
35221
35222 else if ((details::e_div == o0) && (details::e_mul == o1))
35223 {
35224 exprtk_debug((
"(c0 / v) * c1 --> (cov) (c0 * c1) / v\n"));
35225
35226 return expr_gen.node_allocator_->
35227 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
35228 }
35229
35230 else if ((details::e_div == o0) && (details::e_div == o1))
35231 {
35232 exprtk_debug((
"(c0 / v) / c1 --> (cov) (c0 / c1) / v\n"));
35233
35234 return expr_gen.node_allocator_->
35235 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
35236 }
35237 }
35238
35239 const bool synthesis_result =
35240 synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
35241 (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
35242
35243 if (synthesis_result)
35244 return result;
35245
35246 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35247 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35248
35249 if (!expr_gen.valid_operator(o0,f0))
35250 return error_node();
35251 else if (!expr_gen.valid_operator(o1,f1))
35252 return error_node();
35253 else
35254 return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
35255 }
35256
35257 static inline std::string id(expression_generator<Type>& expr_gen,
35258 const details::operator_type o0,
35259 const details::operator_type o1)
35260 {
35261 return details::build_string()
35262 << "(t" << expr_gen.to_str(o0)
35263 << "t)" << expr_gen.to_str(o1)
35264 << "t";
35265 }
35266 };
35267
35268 struct synthesize_covoc_expression1
35269 {
35270 typedef typename covoc_t::type1 node_type;
35271 typedef typename covoc_t::sf3_type sf3_type;
35272
35273 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35274 const details::operator_type& operation,
35275 expression_node_ptr (&branch)[2])
35276 {
35277
35278 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
35279 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
35280 const Type& v = voc->v();
35281 const Type c1 = voc->c();
35282 const details::operator_type o0 = operation;
35283 const details::operator_type o1 = voc->operation();
35284
35285 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35286 details::free_node(*(expr_gen.node_allocator_),branch[1]);
35287
35288 expression_node_ptr result = error_node();
35289
35290 if (expr_gen.parser_->settings_.strength_reduction_enabled())
35291 {
35292
35293 if ((details::e_add == o0) && (details::e_add == o1))
35294 {
35295 exprtk_debug((
"(c0) + (v + c1) --> (cov) (c0 + c1) + v\n"));
35296
35297 return expr_gen.node_allocator_->
35298 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
35299 }
35300
35301 else if ((details::e_add == o0) && (details::e_sub == o1))
35302 {
35303 exprtk_debug((
"(c0) + (v - c1) --> (cov) (c0 - c1) + v\n"));
35304
35305 return expr_gen.node_allocator_->
35306 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
35307 }
35308
35309 else if ((details::e_sub == o0) && (details::e_add == o1))
35310 {
35311 exprtk_debug((
"(c0) - (v + c1) --> (cov) (c0 - c1) - v\n"));
35312
35313 return expr_gen.node_allocator_->
35314 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
35315 }
35316
35317 else if ((details::e_sub == o0) && (details::e_sub == o1))
35318 {
35319 exprtk_debug((
"(c0) - (v - c1) --> (cov) (c0 + c1) - v\n"));
35320
35321 return expr_gen.node_allocator_->
35322 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
35323 }
35324
35325 else if ((details::e_mul == o0) && (details::e_mul == o1))
35326 {
35327 exprtk_debug((
"(c0) * (v * c1) --> (voc) v * (c0 * c1)\n"));
35328
35329 return expr_gen.node_allocator_->
35330 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
35331 }
35332
35333 else if ((details::e_mul == o0) && (details::e_div == o1))
35334 {
35335 exprtk_debug((
"(c0) * (v / c1) --> (cov) (c0 / c1) * v\n"));
35336
35337 return expr_gen.node_allocator_->
35338 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
35339 }
35340
35341 else if ((details::e_div == o0) && (details::e_mul == o1))
35342 {
35343 exprtk_debug((
"(c0) / (v * c1) --> (cov) (c0 / c1) / v\n"));
35344
35345 return expr_gen.node_allocator_->
35346 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
35347 }
35348
35349 else if ((details::e_div == o0) && (details::e_div == o1))
35350 {
35351 exprtk_debug((
"(c0) / (v / c1) --> (cov) (c0 * c1) / v\n"));
35352
35353 return expr_gen.node_allocator_->
35354 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
35355 }
35356 }
35357
35358 const bool synthesis_result =
35359 synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
35360 (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
35361
35362 if (synthesis_result)
35363 return result;
35364
35365 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35366 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35367
35368 if (!expr_gen.valid_operator(o0,f0))
35369 return error_node();
35370 else if (!expr_gen.valid_operator(o1,f1))
35371 return error_node();
35372 else
35373 return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
35374 }
35375
35376 static inline std::string id(expression_generator<Type>& expr_gen,
35377 const details::operator_type o0,
35378 const details::operator_type o1)
35379 {
35380 return details::build_string()
35381 << "t" << expr_gen.to_str(o0)
35382 << "(t" << expr_gen.to_str(o1)
35383 << "t)";
35384 }
35385 };
35386
35387 struct synthesize_cocov_expression0
35388 {
35389 typedef typename cocov_t::type0 node_type;
35390 static inline expression_node_ptr
process(expression_generator<Type>&,
35391 const details::operator_type&,
35392 expression_node_ptr (&)[2])
35393 {
35394
35395 return error_node();
35396 }
35397 };
35398
35399 struct synthesize_cocov_expression1
35400 {
35401 typedef typename cocov_t::type1 node_type;
35402 typedef typename cocov_t::sf3_type sf3_type;
35403
35404 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35405 const details::operator_type& operation,
35406 expression_node_ptr (&branch)[2])
35407 {
35408
35409 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
35410 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
35411 const Type c1 = cov->c();
35412 const Type& v = cov->v();
35413 const details::operator_type o0 = operation;
35414 const details::operator_type o1 = cov->operation();
35415
35416 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35417 details::free_node(*(expr_gen.node_allocator_),branch[1]);
35418
35419 expression_node_ptr result = error_node();
35420
35421 if (expr_gen.parser_->settings_.strength_reduction_enabled())
35422 {
35423
35424 if ((details::e_add == o0) && (details::e_add == o1))
35425 {
35426 exprtk_debug((
"(c0) + (c1 + v) --> (cov) (c0 + c1) + v\n"));
35427
35428 return expr_gen.node_allocator_->
35429 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
35430 }
35431
35432 else if ((details::e_add == o0) && (details::e_sub == o1))
35433 {
35434 exprtk_debug((
"(c0) + (c1 - v) --> (cov) (c0 + c1) - v\n"));
35435
35436 return expr_gen.node_allocator_->
35437 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
35438 }
35439
35440 else if ((details::e_sub == o0) && (details::e_add == o1))
35441 {
35442 exprtk_debug((
"(c0) - (c1 + v) --> (cov) (c0 - c1) - v\n"));
35443
35444 return expr_gen.node_allocator_->
35445 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
35446 }
35447
35448 else if ((details::e_sub == o0) && (details::e_sub == o1))
35449 {
35450 exprtk_debug((
"(c0) - (c1 - v) --> (cov) (c0 - c1) + v\n"));
35451
35452 return expr_gen.node_allocator_->
35453 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
35454 }
35455
35456 else if ((details::e_mul == o0) && (details::e_mul == o1))
35457 {
35458 exprtk_debug((
"(c0) * (c1 * v) --> (cov) (c0 * c1) * v\n"));
35459
35460 return expr_gen.node_allocator_->
35461 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
35462 }
35463
35464 else if ((details::e_mul == o0) && (details::e_div == o1))
35465 {
35466 exprtk_debug((
"(c0) * (c1 / v) --> (cov) (c0 * c1) / v\n"));
35467
35468 return expr_gen.node_allocator_->
35469 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
35470 }
35471
35472 else if ((details::e_div == o0) && (details::e_mul == o1))
35473 {
35474 exprtk_debug((
"(c0) / (c1 * v) --> (cov) (c0 / c1) / v\n"));
35475
35476 return expr_gen.node_allocator_->
35477 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
35478 }
35479
35480 else if ((details::e_div == o0) && (details::e_div == o1))
35481 {
35482 exprtk_debug((
"(c0) / (c1 / v) --> (cov) (c0 / c1) * v\n"));
35483
35484 return expr_gen.node_allocator_->
35485 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
35486 }
35487 }
35488
35489 const bool synthesis_result =
35490 synthesize_sf3ext_expression::template compile<ctype, ctype, vtype>
35491 (expr_gen, id(expr_gen, o0, o1), c0, c1, v, result);
35492
35493 if (synthesis_result)
35494 return result;
35495
35496 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35497 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35498
35499 if (!expr_gen.valid_operator(o0,f0))
35500 return error_node();
35501 else if (!expr_gen.valid_operator(o1,f1))
35502 return error_node();
35503 else
35504 return node_type::allocate(*(expr_gen.node_allocator_), c0, c1, v, f0, f1);
35505 }
35506
35507 static inline std::string id(expression_generator<Type>& expr_gen,
35508 const details::operator_type o0,
35509 const details::operator_type o1)
35510 {
35511 return details::build_string()
35512 << "t" << expr_gen.to_str(o0)
35513 << "(t" << expr_gen.to_str(o1)
35514 << "t)";
35515 }
35516 };
35517
35518 struct synthesize_vococ_expression0
35519 {
35520 typedef typename vococ_t::type0 node_type;
35521 typedef typename vococ_t::sf3_type sf3_type;
35522
35523 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35524 const details::operator_type& operation,
35525 expression_node_ptr (&branch)[2])
35526 {
35527
35528 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
35529 const Type& v = voc->v();
35530 const Type& c0 = voc->c();
35531 const Type& c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
35532 const details::operator_type o0 = voc->operation();
35533 const details::operator_type o1 = operation;
35534
35535 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35536 details::free_node(*(expr_gen.node_allocator_),branch[1]);
35537
35538 expression_node_ptr result = error_node();
35539
35540 if (expr_gen.parser_->settings_.strength_reduction_enabled())
35541 {
35542
35543 if ((details::e_add == o0) && (details::e_add == o1))
35544 {
35545 exprtk_debug((
"(v + c0) + c1 --> (voc) v + (c0 + c1)\n"));
35546
35547 return expr_gen.node_allocator_->
35548 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 + c1);
35549 }
35550
35551 else if ((details::e_add == o0) && (details::e_sub == o1))
35552 {
35553 exprtk_debug((
"(v + c0) - c1 --> (voc) v + (c0 - c1)\n"));
35554
35555 return expr_gen.node_allocator_->
35556 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 - c1);
35557 }
35558
35559 else if ((details::e_sub == o0) && (details::e_add == o1))
35560 {
35561 exprtk_debug((
"(v - c0) + c1 --> (voc) v - (c0 + c1)\n"));
35562
35563 return expr_gen.node_allocator_->
35564 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c1 - c0);
35565 }
35566
35567 else if ((details::e_sub == o0) && (details::e_sub == o1))
35568 {
35569 exprtk_debug((
"(v - c0) - c1 --> (voc) v - (c0 + c1)\n"));
35570
35571 return expr_gen.node_allocator_->
35572 template allocate_rc<typename details::voc_node<Type,details::sub_op<Type> > >(v, c0 + c1);
35573 }
35574
35575 else if ((details::e_mul == o0) && (details::e_mul == o1))
35576 {
35577 exprtk_debug((
"(v * c0) * c1 --> (voc) v * (c0 * c1)\n"));
35578
35579 return expr_gen.node_allocator_->
35580 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 * c1);
35581 }
35582
35583 else if ((details::e_mul == o0) && (details::e_div == o1))
35584 {
35585 exprtk_debug((
"(v * c0) / c1 --> (voc) v * (c0 / c1)\n"));
35586
35587 return expr_gen.node_allocator_->
35588 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 / c1);
35589 }
35590
35591 else if ((details::e_div == o0) && (details::e_mul == o1))
35592 {
35593 exprtk_debug((
"(v / c0) * c1 --> (voc) v * (c1 / c0)\n"));
35594
35595 return expr_gen.node_allocator_->
35596 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c1 / c0);
35597 }
35598
35599 else if ((details::e_div == o0) && (details::e_div == o1))
35600 {
35601 exprtk_debug((
"(v / c0) / c1 --> (voc) v / (c0 * c1)\n"));
35602
35603 return expr_gen.node_allocator_->
35604 template allocate_rc<typename details::voc_node<Type,details::div_op<Type> > >(v, c0 * c1);
35605 }
35606
35607 else if ((details::e_pow == o0) && (details::e_pow == o1))
35608 {
35609 exprtk_debug((
"(v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)\n"));
35610
35611 return expr_gen.node_allocator_->
35612 template allocate_rc<typename details::voc_node<Type,details::pow_op<Type> > >(v, c0 * c1);
35613 }
35614 }
35615
35616 const bool synthesis_result =
35617 synthesize_sf3ext_expression::template compile<vtype, ctype, ctype>
35618 (expr_gen, id(expr_gen, o0, o1), v, c0, c1, result);
35619
35620 if (synthesis_result)
35621 return result;
35622
35623 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35624 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35625
35626 if (!expr_gen.valid_operator(o0,f0))
35627 return error_node();
35628 else if (!expr_gen.valid_operator(o1,f1))
35629 return error_node();
35630 else
35631 return node_type::allocate(*(expr_gen.node_allocator_), v, c0, c1, f0, f1);
35632 }
35633
35634 static inline std::string id(expression_generator<Type>& expr_gen,
35635 const details::operator_type o0,
35636 const details::operator_type o1)
35637 {
35638 return details::build_string()
35639 << "(t" << expr_gen.to_str(o0)
35640 << "t)" << expr_gen.to_str(o1)
35641 << "t";
35642 }
35643 };
35644
35645 struct synthesize_vococ_expression1
35646 {
35647 typedef typename vococ_t::type0 node_type;
35648
35649 static inline expression_node_ptr
process(expression_generator<Type>&,
35650 const details::operator_type&,
35651 expression_node_ptr (&)[2])
35652 {
35653
35654 exprtk_debug((
"(v) o0 (c0 o1 c1) - Not possible.\n"));
35655 return error_node();
35656 }
35657 };
35658
35659 struct synthesize_vovovov_expression0
35660 {
35661 typedef typename vovovov_t::type0 node_type;
35662 typedef typename vovovov_t::sf4_type sf4_type;
35663 typedef typename node_type::T0 T0;
35664 typedef typename node_type::T1 T1;
35665 typedef typename node_type::T2 T2;
35666 typedef typename node_type::T3 T3;
35667
35668 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35669 const details::operator_type& operation,
35670 expression_node_ptr (&branch)[2])
35671 {
35672
35673 const details::vov_base_node<Type>* vov0 = static_cast<details::vov_base_node<Type>*>(branch[0]);
35674 const details::vov_base_node<Type>* vov1 = static_cast<details::vov_base_node<Type>*>(branch[1]);
35675 const Type& v0 = vov0->v0();
35676 const Type& v1 = vov0->v1();
35677 const Type& v2 = vov1->v0();
35678 const Type& v3 = vov1->v1();
35679 const details::operator_type o0 = vov0->operation();
35680 const details::operator_type o1 = operation;
35681 const details::operator_type o2 = vov1->operation();
35682
35683 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35684 details::free_node(*(expr_gen.node_allocator_),branch[1]);
35685
35686 expression_node_ptr result = error_node();
35687
35688 if (expr_gen.parser_->settings_.strength_reduction_enabled())
35689 {
35690
35691 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
35692 {
35693 const bool synthesis_result =
35694 synthesize_sf4ext_expression::
35695 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, v3, result);
35696
35697 exprtk_debug((
"(v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)\n"));
35698
35699 return (synthesis_result) ? result : error_node();
35700 }
35701
35702 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
35703 {
35704 const bool synthesis_result =
35705 synthesize_sf4ext_expression::
35706 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v3, v1, v2, result);
35707
35708 exprtk_debug((
"(v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)\n"));
35709
35710 return (synthesis_result) ? result : error_node();
35711 }
35712
35713 else if ((details::e_add == o0) && (details::e_div == o1) && (details::e_div == o2))
35714 {
35715 const bool synthesis_result =
35716 synthesize_sf4ext_expression::
35717 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t+t)*(t/t)", v0, v1, v3, v2, result);
35718
35719 exprtk_debug((
"(v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)\n"));
35720
35721 return (synthesis_result) ? result : error_node();
35722 }
35723
35724 else if ((details::e_sub == o0) && (details::e_div == o1) && (details::e_div == o2))
35725 {
35726 const bool synthesis_result =
35727 synthesize_sf4ext_expression::
35728 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t-t)*(t/t)", v0, v1, v3, v2, result);
35729
35730 exprtk_debug((
"(v0 - v1) / (v2 / v3) --> (vovovov) (v0 - v1) * (v3 / v2)\n"));
35731
35732 return (synthesis_result) ? result : error_node();
35733 }
35734
35735 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
35736 {
35737 const bool synthesis_result =
35738 synthesize_sf4ext_expression::
35739 template compile<vtype, vtype, vtype, vtype>(expr_gen, "((t*t)*t)/t", v0, v1, v3, v2, result);
35740
35741 exprtk_debug((
"(v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2\n"));
35742
35743 return (synthesis_result) ? result : error_node();
35744 }
35745 }
35746
35747 const bool synthesis_result =
35748 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
35749 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
35750
35751 if (synthesis_result)
35752 return result;
35753
35754 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35755 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35756 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
35757
35758 if (!expr_gen.valid_operator(o0,f0))
35759 return error_node();
35760 else if (!expr_gen.valid_operator(o1,f1))
35761 return error_node();
35762 else if (!expr_gen.valid_operator(o2,f2))
35763 return error_node();
35764 else
35765 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
35766 }
35767
35768 static inline std::string id(expression_generator<Type>& expr_gen,
35769 const details::operator_type o0,
35770 const details::operator_type o1,
35771 const details::operator_type o2)
35772 {
35773 return details::build_string()
35774 << "(t" << expr_gen.to_str(o0)
35775 << "t)" << expr_gen.to_str(o1)
35776 << "(t" << expr_gen.to_str(o2)
35777 << "t)";
35778 }
35779 };
35780
35781 struct synthesize_vovovoc_expression0
35782 {
35783 typedef typename vovovoc_t::type0 node_type;
35784 typedef typename vovovoc_t::sf4_type sf4_type;
35785 typedef typename node_type::T0 T0;
35786 typedef typename node_type::T1 T1;
35787 typedef typename node_type::T2 T2;
35788 typedef typename node_type::T3 T3;
35789
35790 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35791 const details::operator_type& operation,
35792 expression_node_ptr (&branch)[2])
35793 {
35794
35795 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
35796 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
35797 const Type& v0 = vov->v0();
35798 const Type& v1 = vov->v1();
35799 const Type& v2 = voc->v ();
35800 const Type c = voc->c ();
35801 const details::operator_type o0 = vov->operation();
35802 const details::operator_type o1 = operation;
35803 const details::operator_type o2 = voc->operation();
35804
35805 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35806 details::free_node(*(expr_gen.node_allocator_),branch[1]);
35807
35808 expression_node_ptr result = error_node();
35809
35810 if (expr_gen.parser_->settings_.strength_reduction_enabled())
35811 {
35812
35813 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
35814 {
35815 const bool synthesis_result =
35816 synthesize_sf4ext_expression::
35817 template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
35818
35819 exprtk_debug((
"(v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
35820
35821 return (synthesis_result) ? result : error_node();
35822 }
35823
35824 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
35825 {
35826 const bool synthesis_result =
35827 synthesize_sf4ext_expression::
35828 template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
35829
35830 exprtk_debug((
"(v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
35831
35832 return (synthesis_result) ? result : error_node();
35833 }
35834 }
35835
35836 const bool synthesis_result =
35837 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
35838 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
35839
35840 if (synthesis_result)
35841 return result;
35842
35843 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35844 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35845 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
35846
35847 if (!expr_gen.valid_operator(o0,f0))
35848 return error_node();
35849 else if (!expr_gen.valid_operator(o1,f1))
35850 return error_node();
35851 else if (!expr_gen.valid_operator(o2,f2))
35852 return error_node();
35853 else
35854 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
35855 }
35856
35857 static inline std::string id(expression_generator<Type>& expr_gen,
35858 const details::operator_type o0,
35859 const details::operator_type o1,
35860 const details::operator_type o2)
35861 {
35862 return details::build_string()
35863 << "(t" << expr_gen.to_str(o0)
35864 << "t)" << expr_gen.to_str(o1)
35865 << "(t" << expr_gen.to_str(o2)
35866 << "t)";
35867 }
35868 };
35869
35870 struct synthesize_vovocov_expression0
35871 {
35872 typedef typename vovocov_t::type0 node_type;
35873 typedef typename vovocov_t::sf4_type sf4_type;
35874 typedef typename node_type::T0 T0;
35875 typedef typename node_type::T1 T1;
35876 typedef typename node_type::T2 T2;
35877 typedef typename node_type::T3 T3;
35878
35879 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35880 const details::operator_type& operation,
35881 expression_node_ptr (&branch)[2])
35882 {
35883
35884 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
35885 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
35886 const Type& v0 = vov->v0();
35887 const Type& v1 = vov->v1();
35888 const Type& v2 = cov->v ();
35889 const Type c = cov->c ();
35890 const details::operator_type o0 = vov->operation();
35891 const details::operator_type o1 = operation;
35892 const details::operator_type o2 = cov->operation();
35893
35894 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35895 details::free_node(*(expr_gen.node_allocator_),branch[1]);
35896
35897 expression_node_ptr result = error_node();
35898
35899 if (expr_gen.parser_->settings_.strength_reduction_enabled())
35900 {
35901
35902 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
35903 {
35904 const bool synthesis_result =
35905 synthesize_sf4ext_expression::
35906 template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
35907
35908 exprtk_debug((
"(v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
35909
35910 return (synthesis_result) ? result : error_node();
35911 }
35912
35913 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
35914 {
35915 const bool synthesis_result =
35916 synthesize_sf4ext_expression::
35917 template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
35918
35919 exprtk_debug((
"(v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
35920
35921 return (synthesis_result) ? result : error_node();
35922 }
35923 }
35924
35925 const bool synthesis_result =
35926 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
35927 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
35928
35929 if (synthesis_result)
35930 return result;
35931
35932 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35933 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35934 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
35935
35936 if (!expr_gen.valid_operator(o0,f0))
35937 return error_node();
35938 else if (!expr_gen.valid_operator(o1,f1))
35939 return error_node();
35940 else if (!expr_gen.valid_operator(o2,f2))
35941 return error_node();
35942 else
35943 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
35944 }
35945
35946 static inline std::string id(expression_generator<Type>& expr_gen,
35947 const details::operator_type o0,
35948 const details::operator_type o1,
35949 const details::operator_type o2)
35950 {
35951 return details::build_string()
35952 << "(t" << expr_gen.to_str(o0)
35953 << "t)" << expr_gen.to_str(o1)
35954 << "(t" << expr_gen.to_str(o2)
35955 << "t)";
35956 }
35957 };
35958
35959 struct synthesize_vocovov_expression0
35960 {
35961 typedef typename vocovov_t::type0 node_type;
35962 typedef typename vocovov_t::sf4_type sf4_type;
35963 typedef typename node_type::T0 T0;
35964 typedef typename node_type::T1 T1;
35965 typedef typename node_type::T2 T2;
35966 typedef typename node_type::T3 T3;
35967
35968 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
35969 const details::operator_type& operation,
35970 expression_node_ptr (&branch)[2])
35971 {
35972
35973 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
35974 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
35975 const Type c = voc->c ();
35976 const Type& v0 = voc->v ();
35977 const Type& v1 = vov->v0();
35978 const Type& v2 = vov->v1();
35979 const details::operator_type o0 = voc->operation();
35980 const details::operator_type o1 = operation;
35981 const details::operator_type o2 = vov->operation();
35982
35983 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35984 details::free_node(*(expr_gen.node_allocator_),branch[1]);
35985
35986 expression_node_ptr result = error_node();
35987
35988 if (expr_gen.parser_->settings_.strength_reduction_enabled())
35989 {
35990
35991 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
35992 {
35993 const bool synthesis_result =
35994 synthesize_sf4ext_expression::
35995 template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v1, c, v2, result);
35996
35997 exprtk_debug((
"(v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)\n"));
35998
35999 return (synthesis_result) ? result : error_node();
36000 }
36001
36002 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36003 {
36004 const bool synthesis_result =
36005 synthesize_sf4ext_expression::
36006 template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, c, v1, result);
36007
36008 exprtk_debug((
"(v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)\n"));
36009
36010 return (synthesis_result) ? result : error_node();
36011 }
36012 }
36013
36014 const bool synthesis_result =
36015 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36016 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
36017
36018 if (synthesis_result)
36019 return result;
36020
36021 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36022 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36023 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36024
36025 if (!expr_gen.valid_operator(o0,f0))
36026 return error_node();
36027 else if (!expr_gen.valid_operator(o1,f1))
36028 return error_node();
36029 else if (!expr_gen.valid_operator(o2,f2))
36030 return error_node();
36031 else
36032 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
36033 }
36034
36035 static inline std::string id(expression_generator<Type>& expr_gen,
36036 const details::operator_type o0,
36037 const details::operator_type o1,
36038 const details::operator_type o2)
36039 {
36040 return details::build_string()
36041 << "(t" << expr_gen.to_str(o0)
36042 << "t)" << expr_gen.to_str(o1)
36043 << "(t" << expr_gen.to_str(o2)
36044 << "t)";
36045 }
36046 };
36047
36048 struct synthesize_covovov_expression0
36049 {
36050 typedef typename covovov_t::type0 node_type;
36051 typedef typename covovov_t::sf4_type sf4_type;
36052 typedef typename node_type::T0 T0;
36053 typedef typename node_type::T1 T1;
36054 typedef typename node_type::T2 T2;
36055 typedef typename node_type::T3 T3;
36056
36057 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36058 const details::operator_type& operation,
36059 expression_node_ptr (&branch)[2])
36060 {
36061
36062 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
36063 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
36064 const Type c = cov->c ();
36065 const Type& v0 = cov->v ();
36066 const Type& v1 = vov->v0();
36067 const Type& v2 = vov->v1();
36068 const details::operator_type o0 = cov->operation();
36069 const details::operator_type o1 = operation;
36070 const details::operator_type o2 = vov->operation();
36071
36072 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36073 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36074
36075 expression_node_ptr result = error_node();
36076
36077 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36078 {
36079
36080 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36081 {
36082 const bool synthesis_result =
36083 synthesize_sf4ext_expression::
36084 template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v1, v0, v2, result);
36085
36086 exprtk_debug((
"(c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)\n"));
36087
36088 return (synthesis_result) ? result : error_node();
36089 }
36090
36091 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36092 {
36093 const bool synthesis_result =
36094 synthesize_sf4ext_expression::
36095 template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v2, v0, v1, result);
36096
36097 exprtk_debug((
"(c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)\n"));
36098
36099 return (synthesis_result) ? result : error_node();
36100 }
36101 }
36102
36103 const bool synthesis_result =
36104 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36105 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
36106
36107 if (synthesis_result)
36108 return result;
36109
36110 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36111 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36112 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36113
36114 if (!expr_gen.valid_operator(o0,f0))
36115 return error_node();
36116 else if (!expr_gen.valid_operator(o1,f1))
36117 return error_node();
36118 else if (!expr_gen.valid_operator(o2,f2))
36119 return error_node();
36120 else
36121 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
36122 }
36123
36124 static inline std::string id(expression_generator<Type>& expr_gen,
36125 const details::operator_type o0,
36126 const details::operator_type o1,
36127 const details::operator_type o2)
36128 {
36129 return details::build_string()
36130 << "(t" << expr_gen.to_str(o0)
36131 << "t)" << expr_gen.to_str(o1)
36132 << "(t" << expr_gen.to_str(o2)
36133 << "t)";
36134 }
36135 };
36136
36137 struct synthesize_covocov_expression0
36138 {
36139 typedef typename covocov_t::type0 node_type;
36140 typedef typename covocov_t::sf4_type sf4_type;
36141 typedef typename node_type::T0 T0;
36142 typedef typename node_type::T1 T1;
36143 typedef typename node_type::T2 T2;
36144 typedef typename node_type::T3 T3;
36145
36146 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36147 const details::operator_type& operation,
36148 expression_node_ptr (&branch)[2])
36149 {
36150
36151 const details::cov_base_node<Type>* cov0 = static_cast<details::cov_base_node<Type>*>(branch[0]);
36152 const details::cov_base_node<Type>* cov1 = static_cast<details::cov_base_node<Type>*>(branch[1]);
36153 const Type c0 = cov0->c();
36154 const Type& v0 = cov0->v();
36155 const Type c1 = cov1->c();
36156 const Type& v1 = cov1->v();
36157 const details::operator_type o0 = cov0->operation();
36158 const details::operator_type o1 = operation;
36159 const details::operator_type o2 = cov1->operation();
36160
36161 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36162 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36163
36164 expression_node_ptr result = error_node();
36165
36166 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36167 {
36168
36169 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
36170 {
36171 const bool synthesis_result =
36172 synthesize_sf3ext_expression::
36173 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
36174
36175 exprtk_debug((
"(c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
36176
36177 return (synthesis_result) ? result : error_node();
36178 }
36179
36180 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
36181 {
36182 const bool synthesis_result =
36183 synthesize_sf3ext_expression::
36184 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
36185
36186 exprtk_debug((
"(c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
36187
36188 return (synthesis_result) ? result : error_node();
36189 }
36190
36191 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
36192 {
36193 const bool synthesis_result =
36194 synthesize_sf3ext_expression::
36195 template compile<ctype, vtype, vtype>(expr_gen, "(t-t)+t", (c0 - c1), v0, v1, result);
36196
36197 exprtk_debug((
"(c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1\n"));
36198
36199 return (synthesis_result) ? result : error_node();
36200 }
36201
36202 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
36203 {
36204 const bool synthesis_result =
36205 synthesize_sf3ext_expression::
36206 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
36207
36208 exprtk_debug((
"(c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
36209
36210 return (synthesis_result) ? result : error_node();
36211 }
36212
36213 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
36214 {
36215 const bool synthesis_result =
36216 synthesize_sf3ext_expression::
36217 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
36218
36219 exprtk_debug((
"(c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
36220
36221 return (synthesis_result) ? result : error_node();
36222 }
36223
36224 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36225 {
36226 const bool synthesis_result =
36227 synthesize_sf3ext_expression::
36228 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
36229
36230 exprtk_debug((
"(c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
36231
36232 return (synthesis_result) ? result : error_node();
36233 }
36234
36235 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36236 {
36237 const bool synthesis_result =
36238 synthesize_sf3ext_expression::
36239 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v1, v0, result);
36240
36241 exprtk_debug((
"(c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0\n"));
36242
36243 return (synthesis_result) ? result : error_node();
36244 }
36245
36246 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
36247 {
36248 const bool synthesis_result =
36249 synthesize_sf3ext_expression::
36250 template compile<ctype, vtype, vtype>(expr_gen, "t*(t*t)", (c0 / c1), v0, v1, result);
36251
36252 exprtk_debug((
"(c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
36253
36254 return (synthesis_result) ? result : error_node();
36255 }
36256
36257 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
36258 {
36259 const bool synthesis_result =
36260 synthesize_sf3ext_expression::
36261 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
36262
36263 exprtk_debug((
"(c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
36264
36265 return (synthesis_result) ? result : error_node();
36266 }
36267
36268 else if (
36269 (std::equal_to<T>()(c0,c1)) &&
36270 (details::e_mul == o0) &&
36271 (details::e_mul == o2) &&
36272 (
36273 (details::e_add == o1) ||
36274 (details::e_sub == o1)
36275 )
36276 )
36277 {
36278 std::string specfunc;
36279
36280 switch (o1)
36281 {
36282 case details::e_add : specfunc = "t*(t+t)"; break;
36283 case details::e_sub : specfunc = "t*(t-t)"; break;
36284 default : return error_node();
36285 }
36286
36287 const bool synthesis_result =
36288 synthesize_sf3ext_expression::
36289 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
36290
36291 exprtk_debug((
"(c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
36292
36293 return (synthesis_result) ? result : error_node();
36294 }
36295 }
36296
36297 const bool synthesis_result =
36298 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36299 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
36300
36301 if (synthesis_result)
36302 return result;
36303
36304 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36305 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36306 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36307
36308 if (!expr_gen.valid_operator(o0,f0))
36309 return error_node();
36310 else if (!expr_gen.valid_operator(o1,f1))
36311 return error_node();
36312 else if (!expr_gen.valid_operator(o2,f2))
36313 return error_node();
36314 else
36315 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
36316 }
36317
36318 static inline std::string id(expression_generator<Type>& expr_gen,
36319 const details::operator_type o0,
36320 const details::operator_type o1,
36321 const details::operator_type o2)
36322 {
36323 return details::build_string()
36324 << "(t" << expr_gen.to_str(o0)
36325 << "t)" << expr_gen.to_str(o1)
36326 << "(t" << expr_gen.to_str(o2)
36327 << "t)";
36328 }
36329 };
36330
36331 struct synthesize_vocovoc_expression0
36332 {
36333 typedef typename vocovoc_t::type0 node_type;
36334 typedef typename vocovoc_t::sf4_type sf4_type;
36335 typedef typename node_type::T0 T0;
36336 typedef typename node_type::T1 T1;
36337 typedef typename node_type::T2 T2;
36338 typedef typename node_type::T3 T3;
36339
36340 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36341 const details::operator_type& operation,
36342 expression_node_ptr (&branch)[2])
36343 {
36344
36345 const details::voc_base_node<Type>* voc0 = static_cast<details::voc_base_node<Type>*>(branch[0]);
36346 const details::voc_base_node<Type>* voc1 = static_cast<details::voc_base_node<Type>*>(branch[1]);
36347 const Type c0 = voc0->c();
36348 const Type& v0 = voc0->v();
36349 const Type c1 = voc1->c();
36350 const Type& v1 = voc1->v();
36351 const details::operator_type o0 = voc0->operation();
36352 const details::operator_type o1 = operation;
36353 const details::operator_type o2 = voc1->operation();
36354
36355 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36356 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36357
36358 expression_node_ptr result = error_node();
36359
36360 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36361 {
36362
36363 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
36364 {
36365 const bool synthesis_result =
36366 synthesize_sf3ext_expression::
36367 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
36368
36369 exprtk_debug((
"(v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
36370
36371 return (synthesis_result) ? result : error_node();
36372 }
36373
36374 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
36375 {
36376 const bool synthesis_result =
36377 synthesize_sf3ext_expression::
36378 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
36379
36380 exprtk_debug((
"(v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
36381
36382 return (synthesis_result) ? result : error_node();
36383 }
36384
36385 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
36386 {
36387 const bool synthesis_result =
36388 synthesize_sf3ext_expression::
36389 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c1 - c0), v0, v1, result);
36390
36391 exprtk_debug((
"(v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1\n"));
36392
36393 return (synthesis_result) ? result : error_node();
36394 }
36395
36396 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
36397 {
36398 const bool synthesis_result =
36399 synthesize_sf3ext_expression::
36400 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
36401
36402 exprtk_debug((
"(v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
36403
36404 return (synthesis_result) ? result : error_node();
36405 }
36406
36407 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
36408 {
36409 const bool synthesis_result =
36410 synthesize_sf3ext_expression::
36411 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
36412
36413 exprtk_debug((
"(v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
36414
36415 return (synthesis_result) ? result : error_node();
36416 }
36417
36418 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36419 {
36420 const bool synthesis_result =
36421 synthesize_sf3ext_expression::
36422 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", Type(1) / (c0 * c1), v0, v1, result);
36423
36424 exprtk_debug((
"(v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1\n"));
36425
36426 return (synthesis_result) ? result : error_node();
36427 }
36428
36429 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36430 {
36431 const bool synthesis_result =
36432 synthesize_sf3ext_expression::
36433 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
36434
36435 exprtk_debug((
"(v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1\n"));
36436
36437 return (synthesis_result) ? result : error_node();
36438 }
36439
36440 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
36441 {
36442 const bool synthesis_result =
36443 synthesize_sf3ext_expression::
36444 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 * c1), v0, v1, result);
36445
36446 exprtk_debug((
"(v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
36447
36448 return (synthesis_result) ? result : error_node();
36449 }
36450
36451 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
36452 {
36453 const bool synthesis_result =
36454 synthesize_sf3ext_expression::
36455 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", Type(1) / (c0 * c1), v0, v1, result);
36456
36457 exprtk_debug((
"(v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1\n"));
36458
36459 return (synthesis_result) ? result : error_node();
36460 }
36461
36462 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_add == o2))
36463 {
36464 const bool synthesis_result =
36465 synthesize_sf4ext_expression::
36466 template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t+t)", v0, T(1) / c0, v1, c1, result);
36467
36468 exprtk_debug((
"(v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)\n"));
36469
36470 return (synthesis_result) ? result : error_node();
36471 }
36472
36473 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_sub == o2))
36474 {
36475 const bool synthesis_result =
36476 synthesize_sf4ext_expression::
36477 template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t-t)", v0, T(1) / c0, v1, c1, result);
36478
36479 exprtk_debug((
"(v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)\n"));
36480
36481 return (synthesis_result) ? result : error_node();
36482 }
36483
36484 else if (
36485 (std::equal_to<T>()(c0,c1)) &&
36486 (details::e_mul == o0) &&
36487 (details::e_mul == o2) &&
36488 (
36489 (details::e_add == o1) ||
36490 (details::e_sub == o1)
36491 )
36492 )
36493 {
36494 std::string specfunc;
36495
36496 switch (o1)
36497 {
36498 case details::e_add : specfunc = "t*(t+t)"; break;
36499 case details::e_sub : specfunc = "t*(t-t)"; break;
36500 default : return error_node();
36501 }
36502
36503 const bool synthesis_result =
36504 synthesize_sf3ext_expression::
36505 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
36506
36507 exprtk_debug((
"(v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
36508
36509 return (synthesis_result) ? result : error_node();
36510 }
36511
36512 else if (
36513 (std::equal_to<T>()(c0,c1)) &&
36514 (details::e_div == o0) &&
36515 (details::e_div == o2) &&
36516 (
36517 (details::e_add == o1) ||
36518 (details::e_sub == o1)
36519 )
36520 )
36521 {
36522 std::string specfunc;
36523
36524 switch (o1)
36525 {
36526 case details::e_add : specfunc = "(t+t)/t"; break;
36527 case details::e_sub : specfunc = "(t-t)/t"; break;
36528 default : return error_node();
36529 }
36530
36531 const bool synthesis_result =
36532 synthesize_sf3ext_expression::
36533 template compile<vtype, vtype, ctype>(expr_gen, specfunc, v0, v1, c0, result);
36534
36535 exprtk_debug((
"(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n"));
36536
36537 return (synthesis_result) ? result : error_node();
36538 }
36539 }
36540
36541 const bool synthesis_result =
36542 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36543 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
36544
36545 if (synthesis_result)
36546 return result;
36547
36548 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36549 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36550 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36551
36552 if (!expr_gen.valid_operator(o0,f0))
36553 return error_node();
36554 else if (!expr_gen.valid_operator(o1,f1))
36555 return error_node();
36556 else if (!expr_gen.valid_operator(o2,f2))
36557 return error_node();
36558 else
36559 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
36560 }
36561
36562 static inline std::string id(expression_generator<Type>& expr_gen,
36563 const details::operator_type o0,
36564 const details::operator_type o1,
36565 const details::operator_type o2)
36566 {
36567 return details::build_string()
36568 << "(t" << expr_gen.to_str(o0)
36569 << "t)" << expr_gen.to_str(o1)
36570 << "(t" << expr_gen.to_str(o2)
36571 << "t)";
36572 }
36573 };
36574
36575 struct synthesize_covovoc_expression0
36576 {
36577 typedef typename covovoc_t::type0 node_type;
36578 typedef typename covovoc_t::sf4_type sf4_type;
36579 typedef typename node_type::T0 T0;
36580 typedef typename node_type::T1 T1;
36581 typedef typename node_type::T2 T2;
36582 typedef typename node_type::T3 T3;
36583
36584 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36585 const details::operator_type& operation,
36586 expression_node_ptr (&branch)[2])
36587 {
36588
36589 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
36590 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
36591 const Type c0 = cov->c();
36592 const Type& v0 = cov->v();
36593 const Type c1 = voc->c();
36594 const Type& v1 = voc->v();
36595 const details::operator_type o0 = cov->operation();
36596 const details::operator_type o1 = operation;
36597 const details::operator_type o2 = voc->operation();
36598
36599 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36600 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36601
36602 expression_node_ptr result = error_node();
36603
36604 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36605 {
36606
36607 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
36608 {
36609 const bool synthesis_result =
36610 synthesize_sf3ext_expression::
36611 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
36612
36613 exprtk_debug((
"(c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
36614
36615 return (synthesis_result) ? result : error_node();
36616 }
36617
36618 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
36619 {
36620 const bool synthesis_result =
36621 synthesize_sf3ext_expression::
36622 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
36623
36624 exprtk_debug((
"(c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
36625
36626 return (synthesis_result) ? result : error_node();
36627 }
36628
36629 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
36630 {
36631 const bool synthesis_result =
36632 synthesize_sf3ext_expression::
36633 template compile<ctype, vtype, vtype>(expr_gen, "t-(t+t)", (c0 + c1), v0, v1, result);
36634
36635 exprtk_debug((
"(c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1\n"));
36636
36637 return (synthesis_result) ? result : error_node();
36638 }
36639
36640 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
36641 {
36642 const bool synthesis_result =
36643 synthesize_sf3ext_expression::
36644 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
36645
36646 exprtk_debug((
"(c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
36647
36648 return (synthesis_result) ? result : error_node();
36649 }
36650
36651 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
36652 {
36653 const bool synthesis_result =
36654 synthesize_sf3ext_expression::
36655 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
36656
36657 exprtk_debug((
"(c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
36658
36659 return (synthesis_result) ? result : error_node();
36660 }
36661
36662 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36663 {
36664 const bool synthesis_result =
36665 synthesize_sf3ext_expression::
36666 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 / c1), v1, v0, result);
36667
36668 exprtk_debug((
"(c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)\n"));
36669
36670 return (synthesis_result) ? result : error_node();
36671 }
36672
36673 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36674 {
36675 const bool synthesis_result =
36676 synthesize_sf3ext_expression::
36677 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
36678
36679 exprtk_debug((
"(c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
36680
36681 return (synthesis_result) ? result : error_node();
36682 }
36683
36684 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
36685 {
36686 const bool synthesis_result =
36687 synthesize_sf3ext_expression::
36688 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 * c1), v0, v1, result);
36689
36690 exprtk_debug((
"(c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
36691
36692 return (synthesis_result) ? result : error_node();
36693 }
36694
36695 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
36696 {
36697 const bool synthesis_result =
36698 synthesize_sf3ext_expression::
36699 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
36700
36701 exprtk_debug((
"(c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
36702
36703 return (synthesis_result) ? result : error_node();
36704 }
36705
36706 else if (
36707 (std::equal_to<T>()(c0,c1)) &&
36708 (details::e_mul == o0) &&
36709 (details::e_mul == o2) &&
36710 (
36711 (details::e_add == o1) ||
36712 (details::e_sub == o1)
36713 )
36714 )
36715 {
36716 std::string specfunc;
36717
36718 switch (o1)
36719 {
36720 case details::e_add : specfunc = "t*(t+t)"; break;
36721 case details::e_sub : specfunc = "t*(t-t)"; break;
36722 default : return error_node();
36723 }
36724
36725 const bool synthesis_result =
36726 synthesize_sf3ext_expression::
36727 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
36728
36729 exprtk_debug((
"(c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
36730
36731 return (synthesis_result) ? result : error_node();
36732 }
36733 }
36734
36735 const bool synthesis_result =
36736 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36737 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
36738
36739 if (synthesis_result)
36740 return result;
36741
36742 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36743 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36744 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36745
36746 if (!expr_gen.valid_operator(o0,f0))
36747 return error_node();
36748 else if (!expr_gen.valid_operator(o1,f1))
36749 return error_node();
36750 else if (!expr_gen.valid_operator(o2,f2))
36751 return error_node();
36752 else
36753 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
36754 }
36755
36756 static inline std::string id(expression_generator<Type>& expr_gen,
36757 const details::operator_type o0,
36758 const details::operator_type o1,
36759 const details::operator_type o2)
36760 {
36761 return details::build_string()
36762 << "(t" << expr_gen.to_str(o0)
36763 << "t)" << expr_gen.to_str(o1)
36764 << "(t" << expr_gen.to_str(o2)
36765 << "t)";
36766 }
36767 };
36768
36769 struct synthesize_vococov_expression0
36770 {
36771 typedef typename vococov_t::type0 node_type;
36772 typedef typename vococov_t::sf4_type sf4_type;
36773 typedef typename node_type::T0 T0;
36774 typedef typename node_type::T1 T1;
36775 typedef typename node_type::T2 T2;
36776 typedef typename node_type::T3 T3;
36777
36778 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
36779 const details::operator_type& operation,
36780 expression_node_ptr (&branch)[2])
36781 {
36782
36783 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
36784 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
36785 const Type c0 = voc->c();
36786 const Type& v0 = voc->v();
36787 const Type c1 = cov->c();
36788 const Type& v1 = cov->v();
36789 const details::operator_type o0 = voc->operation();
36790 const details::operator_type o1 = operation;
36791 const details::operator_type o2 = cov->operation();
36792
36793 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36794 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36795
36796 expression_node_ptr result = error_node();
36797
36798 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36799 {
36800
36801 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
36802 {
36803 const bool synthesis_result =
36804 synthesize_sf3ext_expression::
36805 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
36806
36807 exprtk_debug((
"(v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
36808
36809 return (synthesis_result) ? result : error_node();
36810 }
36811
36812 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
36813 {
36814 const bool synthesis_result =
36815 synthesize_sf3ext_expression::
36816 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
36817
36818 exprtk_debug((
"(v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
36819
36820 return (synthesis_result) ? result : error_node();
36821 }
36822
36823 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
36824 {
36825 const bool synthesis_result =
36826 synthesize_sf3ext_expression::
36827 template compile<vtype, vtype, ctype>(expr_gen, "(t+t)-t", v0, v1, (c1 + c0), result);
36828
36829 exprtk_debug((
"(v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)\n"));
36830
36831 return (synthesis_result) ? result : error_node();
36832 }
36833
36834 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
36835 {
36836 const bool synthesis_result =
36837 synthesize_sf3ext_expression::
36838 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
36839
36840 exprtk_debug((
"(v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
36841
36842 return (synthesis_result) ? result : error_node();
36843 }
36844
36845 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
36846 {
36847 const bool synthesis_result =
36848 synthesize_sf3ext_expression::
36849 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
36850
36851 exprtk_debug((
"(v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
36852
36853 return (synthesis_result) ? result : error_node();
36854 }
36855
36856 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36857 {
36858 const bool synthesis_result =
36859 synthesize_sf3ext_expression::
36860 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
36861
36862 exprtk_debug((
"(v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)\n"));
36863
36864 return (synthesis_result) ? result : error_node();
36865 }
36866
36867 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
36868 {
36869 const bool synthesis_result =
36870 synthesize_sf3ext_expression::
36871 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 / c1), v0, v1, result);
36872
36873 exprtk_debug((
"(v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
36874
36875 return (synthesis_result) ? result : error_node();
36876 }
36877
36878 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
36879 {
36880 const bool synthesis_result =
36881 synthesize_sf3ext_expression::
36882 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", Type(1) / (c0 * c1), v0, v1, result);
36883
36884 exprtk_debug((
"(v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)\n"));
36885
36886 return (synthesis_result) ? result : error_node();
36887 }
36888
36889 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36890 {
36891 const bool synthesis_result =
36892 synthesize_sf3ext_expression::
36893 template compile<vtype, vtype, ctype>(expr_gen, "(t*t)*t", v0, v1, Type(1) / (c0 * c1), result);
36894
36895 exprtk_debug((
"(v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))\n"));
36896
36897 return (synthesis_result) ? result : error_node();
36898 }
36899
36900 else if (
36901 (std::equal_to<T>()(c0,c1)) &&
36902 (details::e_mul == o0) &&
36903 (details::e_mul == o2) &&
36904 (
36905 (details::e_add == o1) || (details::e_sub == o1)
36906 )
36907 )
36908 {
36909 std::string specfunc;
36910
36911 switch (o1)
36912 {
36913 case details::e_add : specfunc = "t*(t+t)"; break;
36914 case details::e_sub : specfunc = "t*(t-t)"; break;
36915 default : return error_node();
36916 }
36917
36918 const bool synthesis_result =
36919 synthesize_sf3ext_expression::
36920 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
36921
36922 exprtk_debug((
"(v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
36923
36924 return (synthesis_result) ? result : error_node();
36925 }
36926 }
36927
36928 const bool synthesis_result =
36929 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36930 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
36931
36932 if (synthesis_result)
36933 return result;
36934
36935 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36936 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36937 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36938
36939 if (!expr_gen.valid_operator(o0,f0))
36940 return error_node();
36941 else if (!expr_gen.valid_operator(o1,f1))
36942 return error_node();
36943 else if (!expr_gen.valid_operator(o2,f2))
36944 return error_node();
36945 else
36946 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
36947 }
36948
36949 static inline std::string id(expression_generator<Type>& expr_gen,
36950 const details::operator_type o0,
36951 const details::operator_type o1,
36952 const details::operator_type o2)
36953 {
36954 return details::build_string()
36955 << "(t" << expr_gen.to_str(o0)
36956 << "t)" << expr_gen.to_str(o1)
36957 << "(t" << expr_gen.to_str(o2)
36958 << "t)";
36959 }
36960 };
36961
36962 struct synthesize_vovovov_expression1
36963 {
36964 typedef typename vovovov_t::type1 node_type;
36965 typedef typename vovovov_t::sf4_type sf4_type;
36966 typedef typename node_type::T0 T0;
36967 typedef typename node_type::T1 T1;
36968 typedef typename node_type::T2 T2;
36969 typedef typename node_type::T3 T3;
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 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
36977
36978 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
36979 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
36980 const Type& v1 = vovov->t0();
36981 const Type& v2 = vovov->t1();
36982 const Type& v3 = vovov->t2();
36983 const details::operator_type o0 = operation;
36984 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
36985 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
36986
36987 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36988 binary_functor_t f1 = vovov->f0();
36989 binary_functor_t f2 = vovov->f1();
36990
36991 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36992
36993 expression_node_ptr result = error_node();
36994
36995 const bool synthesis_result =
36996 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36997 (expr_gen,id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
36998
36999 if (synthesis_result)
37000 return result;
37001 else if (!expr_gen.valid_operator(o0,f0))
37002 return error_node();
37003
37005
37006 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
37007 }
37008
37009 static inline std::string id(expression_generator<Type>& expr_gen,
37010 const details::operator_type o0,
37011 const details::operator_type o1,
37012 const details::operator_type o2)
37013 {
37014 return details::build_string()
37015 << "t" << expr_gen.to_str(o0)
37016 << "(t" << expr_gen.to_str(o1)
37017 << "(t" << expr_gen.to_str(o2)
37018 << "t))";
37019 }
37020 };
37021
37022 struct synthesize_vovovoc_expression1
37023 {
37024 typedef typename vovovoc_t::type1 node_type;
37025 typedef typename vovovoc_t::sf4_type sf4_type;
37026 typedef typename node_type::T0 T0;
37027 typedef typename node_type::T1 T1;
37028 typedef typename node_type::T2 T2;
37029 typedef typename node_type::T3 T3;
37030
37031 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37032 const details::operator_type& operation,
37033 expression_node_ptr (&branch)[2])
37034 {
37035
37036 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
37037
37038 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
37039 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37040 const Type& v1 = vovoc->t0();
37041 const Type& v2 = vovoc->t1();
37042 const Type c = vovoc->t2();
37043 const details::operator_type o0 = operation;
37044 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
37045 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
37046
37047 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37048 binary_functor_t f1 = vovoc->f0();
37049 binary_functor_t f2 = vovoc->f1();
37050
37051 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37052
37053 expression_node_ptr result = error_node();
37054
37055 const bool synthesis_result =
37056 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37057 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
37058
37059 if (synthesis_result)
37060 return result;
37061 else if (!expr_gen.valid_operator(o0,f0))
37062 return error_node();
37063
37065
37066 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
37067 }
37068
37069 static inline std::string id(expression_generator<Type>& expr_gen,
37070 const details::operator_type o0,
37071 const details::operator_type o1,
37072 const details::operator_type o2)
37073 {
37074 return details::build_string()
37075 << "t" << expr_gen.to_str(o0)
37076 << "(t" << expr_gen.to_str(o1)
37077 << "(t" << expr_gen.to_str(o2)
37078 << "t))";
37079 }
37080 };
37081
37082 struct synthesize_vovocov_expression1
37083 {
37084 typedef typename vovocov_t::type1 node_type;
37085 typedef typename vovocov_t::sf4_type sf4_type;
37086 typedef typename node_type::T0 T0;
37087 typedef typename node_type::T1 T1;
37088 typedef typename node_type::T2 T2;
37089 typedef typename node_type::T3 T3;
37090
37091 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37092 const details::operator_type& operation,
37093 expression_node_ptr (&branch)[2])
37094 {
37095
37096 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
37097
37098 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
37099 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37100 const Type& v1 = vocov->t0();
37101 const Type c = vocov->t1();
37102 const Type& v2 = vocov->t2();
37103 const details::operator_type o0 = operation;
37104 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
37105 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
37106
37107 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37108 binary_functor_t f1 = vocov->f0();
37109 binary_functor_t f2 = vocov->f1();
37110
37111 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37112
37113 expression_node_ptr result = error_node();
37114
37115 const bool synthesis_result =
37116 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37117 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
37118
37119 if (synthesis_result)
37120 return result;
37121 if (!expr_gen.valid_operator(o0,f0))
37122 return error_node();
37123
37125
37126 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
37127 }
37128
37129 static inline std::string id(expression_generator<Type>& expr_gen,
37130 const details::operator_type o0,
37131 const details::operator_type o1,
37132 const details::operator_type o2)
37133 {
37134 return details::build_string()
37135 << "t" << expr_gen.to_str(o0)
37136 << "(t" << expr_gen.to_str(o1)
37137 << "(t" << expr_gen.to_str(o2)
37138 << "t))";
37139 }
37140 };
37141
37142 struct synthesize_vocovov_expression1
37143 {
37144 typedef typename vocovov_t::type1 node_type;
37145 typedef typename vocovov_t::sf4_type sf4_type;
37146 typedef typename node_type::T0 T0;
37147 typedef typename node_type::T1 T1;
37148 typedef typename node_type::T2 T2;
37149 typedef typename node_type::T3 T3;
37150
37151 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37152 const details::operator_type& operation,
37153 expression_node_ptr (&branch)[2])
37154 {
37155
37156 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
37157
37158 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
37159 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37160 const Type c = covov->t0();
37161 const Type& v1 = covov->t1();
37162 const Type& v2 = covov->t2();
37163 const details::operator_type o0 = operation;
37164 const details::operator_type o1 = expr_gen.get_operator(covov->f0());
37165 const details::operator_type o2 = expr_gen.get_operator(covov->f1());
37166
37167 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37168 binary_functor_t f1 = covov->f0();
37169 binary_functor_t f2 = covov->f1();
37170
37171 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37172
37173 expression_node_ptr result = error_node();
37174
37175 const bool synthesis_result =
37176 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37177 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
37178
37179 if (synthesis_result)
37180 return result;
37181 else if (!expr_gen.valid_operator(o0,f0))
37182 return error_node();
37183
37185
37186 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
37187 }
37188
37189 static inline std::string id(expression_generator<Type>& expr_gen,
37190 const details::operator_type o0,
37191 const details::operator_type o1,
37192 const details::operator_type o2)
37193 {
37194 return details::build_string()
37195 << "t" << expr_gen.to_str(o0)
37196 << "(t" << expr_gen.to_str(o1)
37197 << "(t" << expr_gen.to_str(o2)
37198 << "t))";
37199 }
37200 };
37201
37202 struct synthesize_covovov_expression1
37203 {
37204 typedef typename covovov_t::type1 node_type;
37205 typedef typename covovov_t::sf4_type sf4_type;
37206 typedef typename node_type::T0 T0;
37207 typedef typename node_type::T1 T1;
37208 typedef typename node_type::T2 T2;
37209 typedef typename node_type::T3 T3;
37210
37211 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37212 const details::operator_type& operation,
37213 expression_node_ptr (&branch)[2])
37214 {
37215
37216 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
37217
37218 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
37219 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
37220 const Type& v0 = vovov->t0();
37221 const Type& v1 = vovov->t1();
37222 const Type& v2 = vovov->t2();
37223 const details::operator_type o0 = operation;
37224 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
37225 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
37226
37227 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37228 binary_functor_t f1 = vovov->f0();
37229 binary_functor_t f2 = vovov->f1();
37230
37231 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37232 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37233
37234 expression_node_ptr result = error_node();
37235
37236 const bool synthesis_result =
37237 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37238 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
37239
37240 if (synthesis_result)
37241 return result;
37242 if (!expr_gen.valid_operator(o0,f0))
37243 return error_node();
37244
37246
37247 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
37248 }
37249
37250 static inline std::string id(expression_generator<Type>& expr_gen,
37251 const details::operator_type o0,
37252 const details::operator_type o1,
37253 const details::operator_type o2)
37254 {
37255 return details::build_string()
37256 << "t" << expr_gen.to_str(o0)
37257 << "(t" << expr_gen.to_str(o1)
37258 << "(t" << expr_gen.to_str(o2)
37259 << "t))";
37260 }
37261 };
37262
37263 struct synthesize_covocov_expression1
37264 {
37265 typedef typename covocov_t::type1 node_type;
37266 typedef typename covocov_t::sf4_type sf4_type;
37267 typedef typename node_type::T0 T0;
37268 typedef typename node_type::T1 T1;
37269 typedef typename node_type::T2 T2;
37270 typedef typename node_type::T3 T3;
37271
37272 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37273 const details::operator_type& operation,
37274 expression_node_ptr (&branch)[2])
37275 {
37276
37277 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
37278
37279 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
37280 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
37281 const Type& v0 = vocov->t0();
37282 const Type c1 = vocov->t1();
37283 const Type& v1 = vocov->t2();
37284 const details::operator_type o0 = operation;
37285 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
37286 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
37287
37288 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37289 binary_functor_t f1 = vocov->f0();
37290 binary_functor_t f2 = vocov->f1();
37291
37292 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37293 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37294
37295 expression_node_ptr result = error_node();
37296
37297 const bool synthesis_result =
37298 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37299 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
37300
37301 if (synthesis_result)
37302 return result;
37303 else if (!expr_gen.valid_operator(o0,f0))
37304 return error_node();
37305
37307
37308 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
37309 }
37310
37311 static inline std::string id(expression_generator<Type>& expr_gen,
37312 const details::operator_type o0,
37313 const details::operator_type o1,
37314 const details::operator_type o2)
37315 {
37316 return details::build_string()
37317 << "t" << expr_gen.to_str(o0)
37318 << "(t" << expr_gen.to_str(o1)
37319 << "(t" << expr_gen.to_str(o2)
37320 << "t))";
37321 }
37322 };
37323
37324 struct synthesize_vocovoc_expression1
37325 {
37326 typedef typename vocovoc_t::type1 node_type;
37327 typedef typename vocovoc_t::sf4_type sf4_type;
37328 typedef typename node_type::T0 T0;
37329 typedef typename node_type::T1 T1;
37330 typedef typename node_type::T2 T2;
37331 typedef typename node_type::T3 T3;
37332
37333 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37334 const details::operator_type& operation,
37335 expression_node_ptr (&branch)[2])
37336 {
37337
37338 typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
37339
37340 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
37341 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37342 const Type c0 = covoc->t0();
37343 const Type& v1 = covoc->t1();
37344 const Type c1 = covoc->t2();
37345 const details::operator_type o0 = operation;
37346 const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
37347 const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
37348
37349 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37350 binary_functor_t f1 = covoc->f0();
37351 binary_functor_t f2 = covoc->f1();
37352
37353 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37354
37355 expression_node_ptr result = error_node();
37356
37357 const bool synthesis_result =
37358 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37359 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
37360
37361 if (synthesis_result)
37362 return result;
37363 else if (!expr_gen.valid_operator(o0,f0))
37364 return error_node();
37365
37367
37368 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
37369 }
37370
37371 static inline std::string id(expression_generator<Type>& expr_gen,
37372 const details::operator_type o0,
37373 const details::operator_type o1,
37374 const details::operator_type o2)
37375 {
37376 return details::build_string()
37377 << "t" << expr_gen.to_str(o0)
37378 << "(t" << expr_gen.to_str(o1)
37379 << "(t" << expr_gen.to_str(o2)
37380 << "t))";
37381 }
37382 };
37383
37384 struct synthesize_covovoc_expression1
37385 {
37386 typedef typename covovoc_t::type1 node_type;
37387 typedef typename covovoc_t::sf4_type sf4_type;
37388 typedef typename node_type::T0 T0;
37389 typedef typename node_type::T1 T1;
37390 typedef typename node_type::T2 T2;
37391 typedef typename node_type::T3 T3;
37392 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37393 const details::operator_type& operation,
37394 expression_node_ptr (&branch)[2])
37395 {
37396
37397 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
37398
37399 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
37400 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
37401 const Type& v0 = vovoc->t0();
37402 const Type& v1 = vovoc->t1();
37403 const Type c1 = vovoc->t2();
37404 const details::operator_type o0 = operation;
37405 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
37406 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
37407
37408 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37409 binary_functor_t f1 = vovoc->f0();
37410 binary_functor_t f2 = vovoc->f1();
37411
37412 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37413 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37414
37415 expression_node_ptr result = error_node();
37416
37417 const bool synthesis_result =
37418 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37419 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
37420
37421 if (synthesis_result)
37422 return result;
37423 else if (!expr_gen.valid_operator(o0,f0))
37424 return error_node();
37425
37427
37428 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
37429 }
37430
37431 static inline std::string id(expression_generator<Type>& expr_gen,
37432 const details::operator_type o0,
37433 const details::operator_type o1,
37434 const details::operator_type o2)
37435 {
37436 return details::build_string()
37437 << "t" << expr_gen.to_str(o0)
37438 << "(t" << expr_gen.to_str(o1)
37439 << "(t" << expr_gen.to_str(o2)
37440 << "t))";
37441 }
37442 };
37443
37444 struct synthesize_vococov_expression1
37445 {
37446 typedef typename vococov_t::type1 node_type;
37447 typedef typename vococov_t::sf4_type sf4_type;
37448 typedef typename node_type::T0 T0;
37449 typedef typename node_type::T1 T1;
37450 typedef typename node_type::T2 T2;
37451 typedef typename node_type::T3 T3;
37452
37453 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37454 const details::operator_type& operation,
37455 expression_node_ptr (&branch)[2])
37456 {
37457
37458 typedef typename synthesize_cocov_expression1::node_type lcl_cocov_t;
37459
37460 const lcl_cocov_t* cocov = static_cast<const lcl_cocov_t*>(branch[1]);
37461 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37462 const Type c0 = cocov->t0();
37463 const Type c1 = cocov->t1();
37464 const Type& v1 = cocov->t2();
37465 const details::operator_type o0 = operation;
37466 const details::operator_type o1 = expr_gen.get_operator(cocov->f0());
37467 const details::operator_type o2 = expr_gen.get_operator(cocov->f1());
37468
37469 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37470 binary_functor_t f1 = cocov->f0();
37471 binary_functor_t f2 = cocov->f1();
37472
37473 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37474
37475 expression_node_ptr result = error_node();
37476
37477 const bool synthesis_result =
37478 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37479 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
37480
37481 if (synthesis_result)
37482 return result;
37483 else if (!expr_gen.valid_operator(o0,f0))
37484 return error_node();
37485
37487
37488 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
37489 }
37490
37491 static inline std::string id(expression_generator<Type>& expr_gen,
37492 const details::operator_type o0,
37493 const details::operator_type o1,
37494 const details::operator_type o2)
37495 {
37496 return details::build_string()
37497 << "t" << expr_gen.to_str(o0)
37498 << "(t" << expr_gen.to_str(o1)
37499 << "(t" << expr_gen.to_str(o2)
37500 << "t))";
37501 }
37502 };
37503
37504 struct synthesize_vovovov_expression2
37505 {
37506 typedef typename vovovov_t::type2 node_type;
37507 typedef typename vovovov_t::sf4_type sf4_type;
37508 typedef typename node_type::T0 T0;
37509 typedef typename node_type::T1 T1;
37510 typedef typename node_type::T2 T2;
37511 typedef typename node_type::T3 T3;
37512
37513 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37514 const details::operator_type& operation,
37515 expression_node_ptr (&branch)[2])
37516 {
37517
37518 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
37519
37520 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
37521 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37522 const Type& v1 = vovov->t0();
37523 const Type& v2 = vovov->t1();
37524 const Type& v3 = vovov->t2();
37525 const details::operator_type o0 = operation;
37526 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
37527 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
37528
37529 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37530 binary_functor_t f1 = vovov->f0();
37531 binary_functor_t f2 = vovov->f1();
37532
37533 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37534
37535 expression_node_ptr result = error_node();
37536
37537 const bool synthesis_result =
37538 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37539 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
37540
37541 if (synthesis_result)
37542 return result;
37543 else if (!expr_gen.valid_operator(o0,f0))
37544 return error_node();
37545
37547
37548 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
37549 }
37550
37551 static inline std::string id(expression_generator<Type>& expr_gen,
37552 const details::operator_type o0,
37553 const details::operator_type o1,
37554 const details::operator_type o2)
37555 {
37556 return details::build_string()
37557 << "t" << expr_gen.to_str(o0)
37558 << "((t" << expr_gen.to_str(o1)
37559 << "t)" << expr_gen.to_str(o2)
37560 << "t)";
37561 }
37562 };
37563
37564 struct synthesize_vovovoc_expression2
37565 {
37566 typedef typename vovovoc_t::type2 node_type;
37567 typedef typename vovovoc_t::sf4_type sf4_type;
37568 typedef typename node_type::T0 T0;
37569 typedef typename node_type::T1 T1;
37570 typedef typename node_type::T2 T2;
37571 typedef typename node_type::T3 T3;
37572
37573 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37574 const details::operator_type& operation,
37575 expression_node_ptr (&branch)[2])
37576 {
37577
37578 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
37579
37580 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
37581 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37582 const Type& v1 = vovoc->t0();
37583 const Type& v2 = vovoc->t1();
37584 const Type c = vovoc->t2();
37585 const details::operator_type o0 = operation;
37586 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
37587 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
37588
37589 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37590 binary_functor_t f1 = vovoc->f0();
37591 binary_functor_t f2 = vovoc->f1();
37592
37593 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37594
37595 expression_node_ptr result = error_node();
37596
37597 const bool synthesis_result =
37598 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37599 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
37600
37601 if (synthesis_result)
37602 return result;
37603 else if (!expr_gen.valid_operator(o0,f0))
37604 return error_node();
37605
37607
37608 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
37609 }
37610
37611 static inline std::string id(expression_generator<Type>& expr_gen,
37612 const details::operator_type o0,
37613 const details::operator_type o1,
37614 const details::operator_type o2)
37615 {
37616 return details::build_string()
37617 << "t" << expr_gen.to_str(o0)
37618 << "((t" << expr_gen.to_str(o1)
37619 << "t)" << expr_gen.to_str(o2)
37620 << "t)";
37621 }
37622 };
37623
37624 struct synthesize_vovocov_expression2
37625 {
37626 typedef typename vovocov_t::type2 node_type;
37627 typedef typename vovocov_t::sf4_type sf4_type;
37628 typedef typename node_type::T0 T0;
37629 typedef typename node_type::T1 T1;
37630 typedef typename node_type::T2 T2;
37631 typedef typename node_type::T3 T3;
37632
37633 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37634 const details::operator_type& operation,
37635 expression_node_ptr (&branch)[2])
37636 {
37637
37638 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
37639
37640 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
37641 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37642 const Type& v1 = vocov->t0();
37643 const Type c = vocov->t1();
37644 const Type& v2 = vocov->t2();
37645 const details::operator_type o0 = operation;
37646 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
37647 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
37648
37649 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37650 binary_functor_t f1 = vocov->f0();
37651 binary_functor_t f2 = vocov->f1();
37652
37653 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37654
37655 expression_node_ptr result = error_node();
37656
37657 const bool synthesis_result =
37658 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37659 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
37660
37661 if (synthesis_result)
37662 return result;
37663 else if (!expr_gen.valid_operator(o0,f0))
37664 return error_node();
37665
37667
37668 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
37669 }
37670
37671 static inline std::string id(expression_generator<Type>& expr_gen,
37672 const details::operator_type o0,
37673 const details::operator_type o1,
37674 const details::operator_type o2)
37675 {
37676 return details::build_string()
37677 << "t" << expr_gen.to_str(o0)
37678 << "((t" << expr_gen.to_str(o1)
37679 << "t)" << expr_gen.to_str(o2)
37680 << "t)";
37681 }
37682 };
37683
37684 struct synthesize_vocovov_expression2
37685 {
37686 typedef typename vocovov_t::type2 node_type;
37687 typedef typename vocovov_t::sf4_type sf4_type;
37688 typedef typename node_type::T0 T0;
37689 typedef typename node_type::T1 T1;
37690 typedef typename node_type::T2 T2;
37691 typedef typename node_type::T3 T3;
37692
37693 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37694 const details::operator_type& operation,
37695 expression_node_ptr (&branch)[2])
37696 {
37697
37698 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
37699
37700 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
37701 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37702 const Type c = covov->t0();
37703 const Type& v1 = covov->t1();
37704 const Type& v2 = covov->t2();
37705 const details::operator_type o0 = operation;
37706 const details::operator_type o1 = expr_gen.get_operator(covov->f0());
37707 const details::operator_type o2 = expr_gen.get_operator(covov->f1());
37708
37709 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37710 binary_functor_t f1 = covov->f0();
37711 binary_functor_t f2 = covov->f1();
37712
37713 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37714
37715 expression_node_ptr result = error_node();
37716
37717 const bool synthesis_result =
37718 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37719 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
37720
37721 if (synthesis_result)
37722 return result;
37723 else if (!expr_gen.valid_operator(o0,f0))
37724 return error_node();
37725
37727
37728 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
37729 }
37730
37731 static inline std::string id(expression_generator<Type>& expr_gen,
37732 const details::operator_type o0,
37733 const details::operator_type o1,
37734 const details::operator_type o2)
37735 {
37736 return details::build_string()
37737 << "t" << expr_gen.to_str(o0)
37738 << "((t" << expr_gen.to_str(o1)
37739 << "t)" << expr_gen.to_str(o2)
37740 << "t)";
37741 }
37742 };
37743
37744 struct synthesize_covovov_expression2
37745 {
37746 typedef typename covovov_t::type2 node_type;
37747 typedef typename covovov_t::sf4_type sf4_type;
37748 typedef typename node_type::T0 T0;
37749 typedef typename node_type::T1 T1;
37750 typedef typename node_type::T2 T2;
37751 typedef typename node_type::T3 T3;
37752
37753 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37754 const details::operator_type& operation,
37755 expression_node_ptr (&branch)[2])
37756 {
37757
37758 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
37759
37760 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
37761 const Type c =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
37762 const Type& v0 = vovov->t0();
37763 const Type& v1 = vovov->t1();
37764 const Type& v2 = vovov->t2();
37765 const details::operator_type o0 = operation;
37766 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
37767 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
37768
37769 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37770 binary_functor_t f1 = vovov->f0();
37771 binary_functor_t f2 = vovov->f1();
37772
37773 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37774 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37775
37776 expression_node_ptr result = error_node();
37777
37778 const bool synthesis_result =
37779 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37780 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
37781
37782 if (synthesis_result)
37783 return result;
37784 else if (!expr_gen.valid_operator(o0,f0))
37785 return error_node();
37786
37788
37789 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
37790 }
37791
37792 static inline std::string id(expression_generator<Type>& expr_gen,
37793 const details::operator_type o0,
37794 const details::operator_type o1,
37795 const details::operator_type o2)
37796 {
37797 return details::build_string()
37798 << "t" << expr_gen.to_str(o0)
37799 << "((t" << expr_gen.to_str(o1)
37800 << "t)" << expr_gen.to_str(o2)
37801 << "t)";
37802 }
37803 };
37804
37805 struct synthesize_covocov_expression2
37806 {
37807 typedef typename covocov_t::type2 node_type;
37808 typedef typename covocov_t::sf4_type sf4_type;
37809 typedef typename node_type::T0 T0;
37810 typedef typename node_type::T1 T1;
37811 typedef typename node_type::T2 T2;
37812 typedef typename node_type::T3 T3;
37813
37814 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37815 const details::operator_type& operation,
37816 expression_node_ptr (&branch)[2])
37817 {
37818
37819 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
37820
37821 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
37822 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
37823 const Type& v0 = vocov->t0();
37824 const Type c1 = vocov->t1();
37825 const Type& v1 = vocov->t2();
37826 const details::operator_type o0 = operation;
37827 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
37828 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
37829
37830 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37831 binary_functor_t f1 = vocov->f0();
37832 binary_functor_t f2 = vocov->f1();
37833
37834 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37835 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37836
37837 expression_node_ptr result = error_node();
37838
37839 const bool synthesis_result =
37840 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37841 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
37842
37843 if (synthesis_result)
37844 return result;
37845 else if (!expr_gen.valid_operator(o0,f0))
37846 return error_node();
37847
37849
37850 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
37851 }
37852
37853 static inline std::string id(expression_generator<Type>& expr_gen,
37854 const details::operator_type o0,
37855 const details::operator_type o1,
37856 const details::operator_type o2)
37857 {
37858 return details::build_string()
37859 << "t" << expr_gen.to_str(o0)
37860 << "((t" << expr_gen.to_str(o1)
37861 << "t)" << expr_gen.to_str(o2)
37862 << "t)";
37863 }
37864 };
37865
37866 struct synthesize_vocovoc_expression2
37867 {
37868 typedef typename vocovoc_t::type2 node_type;
37869 typedef typename vocovoc_t::sf4_type sf4_type;
37870 typedef typename node_type::T0 T0;
37871 typedef typename node_type::T1 T1;
37872 typedef typename node_type::T2 T2;
37873 typedef typename node_type::T3 T3;
37874
37875 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37876 const details::operator_type& operation,
37877 expression_node_ptr (&branch)[2])
37878 {
37879
37880 typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
37881
37882 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
37883 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37884 const Type c0 = covoc->t0();
37885 const Type& v1 = covoc->t1();
37886 const Type c1 = covoc->t2();
37887 const details::operator_type o0 = operation;
37888 const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
37889 const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
37890
37891 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37892 binary_functor_t f1 = covoc->f0();
37893 binary_functor_t f2 = covoc->f1();
37894
37895 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37896
37897 expression_node_ptr result = error_node();
37898
37899 const bool synthesis_result =
37900 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37901 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
37902
37903 if (synthesis_result)
37904 return result;
37905 else if (!expr_gen.valid_operator(o0,f0))
37906 return error_node();
37907
37909
37910 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
37911 }
37912
37913 static inline std::string id(expression_generator<Type>& expr_gen,
37914 const details::operator_type o0,
37915 const details::operator_type o1,
37916 const details::operator_type o2)
37917 {
37918 return details::build_string()
37919 << "t" << expr_gen.to_str(o0)
37920 << "((t" << expr_gen.to_str(o1)
37921 << "t)" << expr_gen.to_str(o2)
37922 << "t)";
37923 }
37924 };
37925
37926 struct synthesize_covovoc_expression2
37927 {
37928 typedef typename covovoc_t::type2 node_type;
37929 typedef typename covovoc_t::sf4_type sf4_type;
37930 typedef typename node_type::T0 T0;
37931 typedef typename node_type::T1 T1;
37932 typedef typename node_type::T2 T2;
37933 typedef typename node_type::T3 T3;
37934
37935 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
37936 const details::operator_type& operation,
37937 expression_node_ptr (&branch)[2])
37938 {
37939
37940 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
37941
37942 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
37943 const Type c0 =
static_cast<details::literal_node<Type>*
>(branch[0])->
value();
37944 const Type& v0 = vovoc->t0();
37945 const Type& v1 = vovoc->t1();
37946 const Type c1 = vovoc->t2();
37947 const details::operator_type o0 = operation;
37948 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
37949 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
37950
37951 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37952 binary_functor_t f1 = vovoc->f0();
37953 binary_functor_t f2 = vovoc->f1();
37954
37955 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37956 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37957
37958 expression_node_ptr result = error_node();
37959
37960 const bool synthesis_result =
37961 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37962 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
37963
37964 if (synthesis_result)
37965 return result;
37966 else if (!expr_gen.valid_operator(o0,f0))
37967 return error_node();
37968
37970
37971 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
37972 }
37973
37974 static inline std::string id(expression_generator<Type>& expr_gen,
37975 const details::operator_type o0,
37976 const details::operator_type o1,
37977 const details::operator_type o2)
37978 {
37979 return details::build_string()
37980 << "t" << expr_gen.to_str(o0)
37981 << "((t" << expr_gen.to_str(o1)
37982 << "t)" << expr_gen.to_str(o2)
37983 << "t)";
37984 }
37985 };
37986
37987 struct synthesize_vococov_expression2
37988 {
37989 typedef typename vococov_t::type2 node_type;
37990 static inline expression_node_ptr
process(expression_generator<Type>&,
37991 const details::operator_type&,
37992 expression_node_ptr (&)[2])
37993 {
37994
37995 exprtk_debug((
"v0 o0 ((c0 o1 c1) o2 v1) - Not possible\n"));
37996 return error_node();
37997 }
37998
37999 static inline std::string id(expression_generator<Type>&,
38000 const details::operator_type,
38001 const details::operator_type,
38002 const details::operator_type)
38003 {
38004 return "INVALID";
38005 }
38006 };
38007
38008 struct synthesize_vovovov_expression3
38009 {
38010 typedef typename vovovov_t::type3 node_type;
38011 typedef typename vovovov_t::sf4_type sf4_type;
38012 typedef typename node_type::T0 T0;
38013 typedef typename node_type::T1 T1;
38014 typedef typename node_type::T2 T2;
38015 typedef typename node_type::T3 T3;
38016
38017 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38018 const details::operator_type& operation,
38019 expression_node_ptr (&branch)[2])
38020 {
38021
38022 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
38023
38024 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
38025 const Type& v0 = vovov->t0();
38026 const Type& v1 = vovov->t1();
38027 const Type& v2 = vovov->t2();
38028 const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38029 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
38030 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
38031 const details::operator_type o2 = operation;
38032
38033 binary_functor_t f0 = vovov->f0();
38034 binary_functor_t f1 = vovov->f1();
38035 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38036
38037 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38038
38039 expression_node_ptr result = error_node();
38040
38041 const bool synthesis_result =
38042 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38043 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
38044
38045 if (synthesis_result)
38046 return result;
38047 else if (!expr_gen.valid_operator(o2,f2))
38048 return error_node();
38049
38051
38052 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
38053 }
38054
38055 static inline std::string id(expression_generator<Type>& expr_gen,
38056 const details::operator_type o0,
38057 const details::operator_type o1,
38058 const details::operator_type o2)
38059 {
38060 return details::build_string()
38061 << "((t" << expr_gen.to_str(o0)
38062 << "t)" << expr_gen.to_str(o1)
38063 << "t)" << expr_gen.to_str(o2)
38064 << "t";
38065 }
38066 };
38067
38068 struct synthesize_vovovoc_expression3
38069 {
38070 typedef typename vovovoc_t::type3 node_type;
38071 typedef typename vovovoc_t::sf4_type sf4_type;
38072 typedef typename node_type::T0 T0;
38073 typedef typename node_type::T1 T1;
38074 typedef typename node_type::T2 T2;
38075 typedef typename node_type::T3 T3;
38076
38077 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38078 const details::operator_type& operation,
38079 expression_node_ptr (&branch)[2])
38080 {
38081
38082 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
38083
38084 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
38085 const Type& v0 = vovov->t0();
38086 const Type& v1 = vovov->t1();
38087 const Type& v2 = vovov->t2();
38088 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
38089 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
38090 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
38091 const details::operator_type o2 = operation;
38092
38093 binary_functor_t f0 = vovov->f0();
38094 binary_functor_t f1 = vovov->f1();
38095 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38096
38097 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38098 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38099
38100 expression_node_ptr result = error_node();
38101
38102 const bool synthesis_result =
38103 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38104 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
38105
38106 if (synthesis_result)
38107 return result;
38108 else if (!expr_gen.valid_operator(o2,f2))
38109 return error_node();
38110
38112
38113 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
38114 }
38115
38116 static inline std::string id(expression_generator<Type>& expr_gen,
38117 const details::operator_type o0,
38118 const details::operator_type o1,
38119 const details::operator_type o2)
38120 {
38121 return details::build_string()
38122 << "((t" << expr_gen.to_str(o0)
38123 << "t)" << expr_gen.to_str(o1)
38124 << "t)" << expr_gen.to_str(o2)
38125 << "t";
38126 }
38127 };
38128
38129 struct synthesize_vovocov_expression3
38130 {
38131 typedef typename vovocov_t::type3 node_type;
38132 typedef typename vovocov_t::sf4_type sf4_type;
38133 typedef typename node_type::T0 T0;
38134 typedef typename node_type::T1 T1;
38135 typedef typename node_type::T2 T2;
38136 typedef typename node_type::T3 T3;
38137
38138 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38139 const details::operator_type& operation,
38140 expression_node_ptr (&branch)[2])
38141 {
38142
38143 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
38144
38145 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
38146 const Type& v0 = vovoc->t0();
38147 const Type& v1 = vovoc->t1();
38148 const Type c = vovoc->t2();
38149 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38150 const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
38151 const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
38152 const details::operator_type o2 = operation;
38153
38154 binary_functor_t f0 = vovoc->f0();
38155 binary_functor_t f1 = vovoc->f1();
38156 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38157
38158 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38159
38160 expression_node_ptr result = error_node();
38161
38162 const bool synthesis_result =
38163 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38164 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
38165
38166 if (synthesis_result)
38167 return result;
38168 else if (!expr_gen.valid_operator(o2,f2))
38169 return error_node();
38170
38172
38173 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
38174 }
38175
38176 static inline std::string id(expression_generator<Type>& expr_gen,
38177 const details::operator_type o0,
38178 const details::operator_type o1,
38179 const details::operator_type o2)
38180 {
38181 return details::build_string()
38182 << "((t" << expr_gen.to_str(o0)
38183 << "t)" << expr_gen.to_str(o1)
38184 << "t)" << expr_gen.to_str(o2)
38185 << "t";
38186 }
38187 };
38188
38189 struct synthesize_vocovov_expression3
38190 {
38191 typedef typename vocovov_t::type3 node_type;
38192 typedef typename vocovov_t::sf4_type sf4_type;
38193 typedef typename node_type::T0 T0;
38194 typedef typename node_type::T1 T1;
38195 typedef typename node_type::T2 T2;
38196 typedef typename node_type::T3 T3;
38197
38198 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38199 const details::operator_type& operation,
38200 expression_node_ptr (&branch)[2])
38201 {
38202
38203 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
38204
38205 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
38206 const Type& v0 = vocov->t0();
38207 const Type c = vocov->t1();
38208 const Type& v1 = vocov->t2();
38209 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38210 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
38211 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
38212 const details::operator_type o2 = operation;
38213
38214 binary_functor_t f0 = vocov->f0();
38215 binary_functor_t f1 = vocov->f1();
38216 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38217
38218 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38219
38220 expression_node_ptr result = error_node();
38221
38222 const bool synthesis_result =
38223 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38224 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
38225
38226 if (synthesis_result)
38227 return result;
38228 else if (!expr_gen.valid_operator(o2,f2))
38229 return error_node();
38230
38232
38233 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
38234 }
38235
38236 static inline std::string id(expression_generator<Type>& expr_gen,
38237 const details::operator_type o0,
38238 const details::operator_type o1,
38239 const details::operator_type o2)
38240 {
38241 return details::build_string()
38242 << "((t" << expr_gen.to_str(o0)
38243 << "t)" << expr_gen.to_str(o1)
38244 << "t)" << expr_gen.to_str(o2)
38245 << "t";
38246 }
38247 };
38248
38249 struct synthesize_covovov_expression3
38250 {
38251 typedef typename covovov_t::type3 node_type;
38252 typedef typename covovov_t::sf4_type sf4_type;
38253 typedef typename node_type::T0 T0;
38254 typedef typename node_type::T1 T1;
38255 typedef typename node_type::T2 T2;
38256 typedef typename node_type::T3 T3;
38257
38258 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38259 const details::operator_type& operation,
38260 expression_node_ptr (&branch)[2])
38261 {
38262
38263 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
38264
38265 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
38266 const Type c = covov->t0();
38267 const Type& v0 = covov->t1();
38268 const Type& v1 = covov->t2();
38269 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38270 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
38271 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
38272 const details::operator_type o2 = operation;
38273
38274 binary_functor_t f0 = covov->f0();
38275 binary_functor_t f1 = covov->f1();
38276 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38277
38278 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38279
38280 expression_node_ptr result = error_node();
38281
38282 const bool synthesis_result =
38283 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38284 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
38285
38286 if (synthesis_result)
38287 return result;
38288 else if (!expr_gen.valid_operator(o2,f2))
38289 return error_node();
38290
38292
38293 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
38294 }
38295
38296 static inline std::string id(expression_generator<Type>& expr_gen,
38297 const details::operator_type o0,
38298 const details::operator_type o1,
38299 const details::operator_type o2)
38300 {
38301 return details::build_string()
38302 << "((t" << expr_gen.to_str(o0)
38303 << "t)" << expr_gen.to_str(o1)
38304 << "t)" << expr_gen.to_str(o2)
38305 << "t";
38306 }
38307 };
38308
38309 struct synthesize_covocov_expression3
38310 {
38311 typedef typename covocov_t::type3 node_type;
38312 typedef typename covocov_t::sf4_type sf4_type;
38313 typedef typename node_type::T0 T0;
38314 typedef typename node_type::T1 T1;
38315 typedef typename node_type::T2 T2;
38316 typedef typename node_type::T3 T3;
38317
38318 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38319 const details::operator_type& operation,
38320 expression_node_ptr (&branch)[2])
38321 {
38322
38323 typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
38324
38325 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
38326 const Type c0 = covoc->t0();
38327 const Type& v0 = covoc->t1();
38328 const Type c1 = covoc->t2();
38329 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38330 const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
38331 const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
38332 const details::operator_type o2 = operation;
38333
38334 binary_functor_t f0 = covoc->f0();
38335 binary_functor_t f1 = covoc->f1();
38336 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38337
38338 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38339
38340 expression_node_ptr result = error_node();
38341
38342 const bool synthesis_result =
38343 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38344 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
38345
38346 if (synthesis_result)
38347 return result;
38348 else if (!expr_gen.valid_operator(o2,f2))
38349 return error_node();
38350
38352
38353 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
38354 }
38355
38356 static inline std::string id(expression_generator<Type>& expr_gen,
38357 const details::operator_type o0,
38358 const details::operator_type o1,
38359 const details::operator_type o2)
38360 {
38361 return details::build_string()
38362 << "((t" << expr_gen.to_str(o0)
38363 << "t)" << expr_gen.to_str(o1)
38364 << "t)" << expr_gen.to_str(o2)
38365 << "t";
38366 }
38367 };
38368
38369 struct synthesize_vocovoc_expression3
38370 {
38371 typedef typename vocovoc_t::type3 node_type;
38372 typedef typename vocovoc_t::sf4_type sf4_type;
38373 typedef typename node_type::T0 T0;
38374 typedef typename node_type::T1 T1;
38375 typedef typename node_type::T2 T2;
38376 typedef typename node_type::T3 T3;
38377
38378 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38379 const details::operator_type& operation,
38380 expression_node_ptr (&branch)[2])
38381 {
38382
38383 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
38384
38385 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
38386 const Type& v0 = vocov->t0();
38387 const Type c0 = vocov->t1();
38388 const Type& v1 = vocov->t2();
38389 const Type c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
38390 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
38391 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
38392 const details::operator_type o2 = operation;
38393
38394 binary_functor_t f0 = vocov->f0();
38395 binary_functor_t f1 = vocov->f1();
38396 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38397
38398 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38399 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38400
38401 expression_node_ptr result = error_node();
38402
38403 const bool synthesis_result =
38404 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38405 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
38406
38407 if (synthesis_result)
38408 return result;
38409 else if (!expr_gen.valid_operator(o2,f2))
38410 return error_node();
38411
38413
38414 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
38415 }
38416
38417 static inline std::string id(expression_generator<Type>& expr_gen,
38418 const details::operator_type o0,
38419 const details::operator_type o1,
38420 const details::operator_type o2)
38421 {
38422 return details::build_string()
38423 << "((t" << expr_gen.to_str(o0)
38424 << "t)" << expr_gen.to_str(o1)
38425 << "t)" << expr_gen.to_str(o2)
38426 << "t";
38427 }
38428 };
38429
38430 struct synthesize_covovoc_expression3
38431 {
38432 typedef typename covovoc_t::type3 node_type;
38433 typedef typename covovoc_t::sf4_type sf4_type;
38434 typedef typename node_type::T0 T0;
38435 typedef typename node_type::T1 T1;
38436 typedef typename node_type::T2 T2;
38437 typedef typename node_type::T3 T3;
38438
38439 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38440 const details::operator_type& operation,
38441 expression_node_ptr (&branch)[2])
38442 {
38443
38444 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
38445
38446 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
38447 const Type c0 = covov->t0();
38448 const Type& v0 = covov->t1();
38449 const Type& v1 = covov->t2();
38450 const Type c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
38451 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
38452 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
38453 const details::operator_type o2 = operation;
38454
38455 binary_functor_t f0 = covov->f0();
38456 binary_functor_t f1 = covov->f1();
38457 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38458
38459 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38460 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38461
38462 expression_node_ptr result = error_node();
38463
38464 const bool synthesis_result =
38465 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38466 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
38467
38468 if (synthesis_result)
38469 return result;
38470 else if (!expr_gen.valid_operator(o2,f2))
38471 return error_node();
38472
38474
38475 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
38476 }
38477
38478 static inline std::string id(expression_generator<Type>& expr_gen,
38479 const details::operator_type o0,
38480 const details::operator_type o1,
38481 const details::operator_type o2)
38482 {
38483 return details::build_string()
38484 << "((t" << expr_gen.to_str(o0)
38485 << "t)" << expr_gen.to_str(o1)
38486 << "t)" << expr_gen.to_str(o2)
38487 << "t";
38488 }
38489 };
38490
38491 struct synthesize_vococov_expression3
38492 {
38493 typedef typename vococov_t::type3 node_type;
38494 typedef typename vococov_t::sf4_type sf4_type;
38495 typedef typename node_type::T0 T0;
38496 typedef typename node_type::T1 T1;
38497 typedef typename node_type::T2 T2;
38498 typedef typename node_type::T3 T3;
38499
38500 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38501 const details::operator_type& operation,
38502 expression_node_ptr (&branch)[2])
38503 {
38504
38505 typedef typename synthesize_vococ_expression0::node_type lcl_vococ_t;
38506
38507 const lcl_vococ_t* vococ = static_cast<const lcl_vococ_t*>(branch[0]);
38508 const Type& v0 = vococ->t0();
38509 const Type c0 = vococ->t1();
38510 const Type c1 = vococ->t2();
38511 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38512 const details::operator_type o0 = expr_gen.get_operator(vococ->f0());
38513 const details::operator_type o1 = expr_gen.get_operator(vococ->f1());
38514 const details::operator_type o2 = operation;
38515
38516 binary_functor_t f0 = vococ->f0();
38517 binary_functor_t f1 = vococ->f1();
38518 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38519
38520 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38521
38522 expression_node_ptr result = error_node();
38523
38524 const bool synthesis_result =
38525 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38526 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
38527
38528 if (synthesis_result)
38529 return result;
38530 else if (!expr_gen.valid_operator(o2,f2))
38531 return error_node();
38532
38534
38535 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
38536 }
38537
38538 static inline std::string id(expression_generator<Type>& expr_gen,
38539 const details::operator_type o0,
38540 const details::operator_type o1,
38541 const details::operator_type o2)
38542 {
38543 return details::build_string()
38544 << "((t" << expr_gen.to_str(o0)
38545 << "t)" << expr_gen.to_str(o1)
38546 << "t)" << expr_gen.to_str(o2)
38547 << "t";
38548 }
38549 };
38550
38551 struct synthesize_vovovov_expression4
38552 {
38553 typedef typename vovovov_t::type4 node_type;
38554 typedef typename vovovov_t::sf4_type sf4_type;
38555 typedef typename node_type::T0 T0;
38556 typedef typename node_type::T1 T1;
38557 typedef typename node_type::T2 T2;
38558 typedef typename node_type::T3 T3;
38559
38560 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38561 const details::operator_type& operation,
38562 expression_node_ptr (&branch)[2])
38563 {
38564
38565 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
38566
38567 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
38568 const Type& v0 = vovov->t0();
38569 const Type& v1 = vovov->t1();
38570 const Type& v2 = vovov->t2();
38571 const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38572 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
38573 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
38574 const details::operator_type o2 = operation;
38575
38576 binary_functor_t f0 = vovov->f0();
38577 binary_functor_t f1 = vovov->f1();
38578 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38579
38580 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38581
38582 expression_node_ptr result = error_node();
38583
38584 const bool synthesis_result =
38585 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38586 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
38587
38588 if (synthesis_result)
38589 return result;
38590 else if (!expr_gen.valid_operator(o2,f2))
38591 return error_node();
38592
38594
38595 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
38596 }
38597
38598 static inline std::string id(expression_generator<Type>& expr_gen,
38599 const details::operator_type o0,
38600 const details::operator_type o1,
38601 const details::operator_type o2)
38602 {
38603 return details::build_string()
38604 << "(t" << expr_gen.to_str(o0)
38605 << "(t" << expr_gen.to_str(o1)
38606 << "t)" << expr_gen.to_str(o2)
38607 << "t";
38608 }
38609 };
38610
38611 struct synthesize_vovovoc_expression4
38612 {
38613 typedef typename vovovoc_t::type4 node_type;
38614 typedef typename vovovoc_t::sf4_type sf4_type;
38615 typedef typename node_type::T0 T0;
38616 typedef typename node_type::T1 T1;
38617 typedef typename node_type::T2 T2;
38618 typedef typename node_type::T3 T3;
38619
38620 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38621 const details::operator_type& operation,
38622 expression_node_ptr (&branch)[2])
38623 {
38624
38625 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
38626
38627 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
38628 const Type& v0 = vovov->t0();
38629 const Type& v1 = vovov->t1();
38630 const Type& v2 = vovov->t2();
38631 const Type c =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
38632 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
38633 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
38634 const details::operator_type o2 = operation;
38635
38636 binary_functor_t f0 = vovov->f0();
38637 binary_functor_t f1 = vovov->f1();
38638 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38639
38640 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38641 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38642
38643 expression_node_ptr result = error_node();
38644
38645 const bool synthesis_result =
38646 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38647 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
38648
38649 if (synthesis_result)
38650 return result;
38651 else if (!expr_gen.valid_operator(o2,f2))
38652 return error_node();
38653
38655
38656 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
38657 }
38658
38659 static inline std::string id(expression_generator<Type>& expr_gen,
38660 const details::operator_type o0,
38661 const details::operator_type o1,
38662 const details::operator_type o2)
38663 {
38664 return details::build_string()
38665 << "(t" << expr_gen.to_str(o0)
38666 << "(t" << expr_gen.to_str(o1)
38667 << "t)" << expr_gen.to_str(o2)
38668 << "t";
38669 }
38670 };
38671
38672 struct synthesize_vovocov_expression4
38673 {
38674 typedef typename vovocov_t::type4 node_type;
38675 typedef typename vovocov_t::sf4_type sf4_type;
38676 typedef typename node_type::T0 T0;
38677 typedef typename node_type::T1 T1;
38678 typedef typename node_type::T2 T2;
38679 typedef typename node_type::T3 T3;
38680
38681 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38682 const details::operator_type& operation,
38683 expression_node_ptr (&branch)[2])
38684 {
38685
38686 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
38687
38688 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
38689 const Type& v0 = vovoc->t0();
38690 const Type& v1 = vovoc->t1();
38691 const Type c = vovoc->t2();
38692 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38693 const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
38694 const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
38695 const details::operator_type o2 = operation;
38696
38697 binary_functor_t f0 = vovoc->f0();
38698 binary_functor_t f1 = vovoc->f1();
38699 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38700
38701 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38702
38703 expression_node_ptr result = error_node();
38704
38705 const bool synthesis_result =
38706 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38707 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
38708
38709 if (synthesis_result)
38710 return result;
38711 else if (!expr_gen.valid_operator(o2,f2))
38712 return error_node();
38713
38715
38716 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
38717 }
38718
38719 static inline std::string id(expression_generator<Type>& expr_gen,
38720 const details::operator_type o0,
38721 const details::operator_type o1,
38722 const details::operator_type o2)
38723 {
38724 return details::build_string()
38725 << "(t" << expr_gen.to_str(o0)
38726 << "(t" << expr_gen.to_str(o1)
38727 << "t)" << expr_gen.to_str(o2)
38728 << "t";
38729 }
38730 };
38731
38732 struct synthesize_vocovov_expression4
38733 {
38734 typedef typename vocovov_t::type4 node_type;
38735 typedef typename vocovov_t::sf4_type sf4_type;
38736 typedef typename node_type::T0 T0;
38737 typedef typename node_type::T1 T1;
38738 typedef typename node_type::T2 T2;
38739 typedef typename node_type::T3 T3;
38740
38741 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38742 const details::operator_type& operation,
38743 expression_node_ptr (&branch)[2])
38744 {
38745
38746 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
38747
38748 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
38749 const Type& v0 = vocov->t0();
38750 const Type c = vocov->t1();
38751 const Type& v1 = vocov->t2();
38752 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38753 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
38754 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
38755 const details::operator_type o2 = operation;
38756
38757 binary_functor_t f0 = vocov->f0();
38758 binary_functor_t f1 = vocov->f1();
38759 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38760
38761 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38762 expression_node_ptr result = error_node();
38763
38764 const bool synthesis_result =
38765 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38766 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
38767
38768 if (synthesis_result)
38769 return result;
38770 else if (!expr_gen.valid_operator(o2,f2))
38771 return error_node();
38772
38774
38775 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
38776 }
38777
38778 static inline std::string id(expression_generator<Type>& expr_gen,
38779 const details::operator_type o0,
38780 const details::operator_type o1,
38781 const details::operator_type o2)
38782 {
38783 return details::build_string()
38784 << "(t" << expr_gen.to_str(o0)
38785 << "(t" << expr_gen.to_str(o1)
38786 << "t)" << expr_gen.to_str(o2)
38787 << "t";
38788 }
38789 };
38790
38791 struct synthesize_covovov_expression4
38792 {
38793 typedef typename covovov_t::type4 node_type;
38794 typedef typename covovov_t::sf4_type sf4_type;
38795 typedef typename node_type::T0 T0;
38796 typedef typename node_type::T1 T1;
38797 typedef typename node_type::T2 T2;
38798 typedef typename node_type::T3 T3;
38799
38800 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38801 const details::operator_type& operation,
38802 expression_node_ptr (&branch)[2])
38803 {
38804
38805 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
38806
38807 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
38808 const Type c = covov->t0();
38809 const Type& v0 = covov->t1();
38810 const Type& v1 = covov->t2();
38811 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38812 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
38813 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
38814 const details::operator_type o2 = operation;
38815
38816 binary_functor_t f0 = covov->f0();
38817 binary_functor_t f1 = covov->f1();
38818 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38819
38820 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38821
38822 expression_node_ptr result = error_node();
38823
38824 const bool synthesis_result =
38825 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38826 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
38827
38828 if (synthesis_result)
38829 return result;
38830 else if (!expr_gen.valid_operator(o2,f2))
38831 return error_node();
38832
38834
38835 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
38836 }
38837
38838 static inline std::string id(expression_generator<Type>& expr_gen,
38839 const details::operator_type o0,
38840 const details::operator_type o1,
38841 const details::operator_type o2)
38842 {
38843 return details::build_string()
38844 << "(t" << expr_gen.to_str(o0)
38845 << "(t" << expr_gen.to_str(o1)
38846 << "t)" << expr_gen.to_str(o2)
38847 << "t";
38848 }
38849 };
38850
38851 struct synthesize_covocov_expression4
38852 {
38853 typedef typename covocov_t::type4 node_type;
38854 typedef typename covocov_t::sf4_type sf4_type;
38855 typedef typename node_type::T0 T0;
38856 typedef typename node_type::T1 T1;
38857 typedef typename node_type::T2 T2;
38858 typedef typename node_type::T3 T3;
38859
38860 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38861 const details::operator_type& operation,
38862 expression_node_ptr (&branch)[2])
38863 {
38864
38865 typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
38866
38867 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
38868 const Type c0 = covoc->t0();
38869 const Type& v0 = covoc->t1();
38870 const Type c1 = covoc->t2();
38871 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38872 const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
38873 const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
38874 const details::operator_type o2 = operation;
38875
38876 binary_functor_t f0 = covoc->f0();
38877 binary_functor_t f1 = covoc->f1();
38878 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38879
38880 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38881
38882 expression_node_ptr result = error_node();
38883
38884 const bool synthesis_result =
38885 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38886 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
38887
38888 if (synthesis_result)
38889 return result;
38890 else if (!expr_gen.valid_operator(o2,f2))
38891 return error_node();
38892
38894
38895 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
38896 }
38897
38898 static inline std::string id(expression_generator<Type>& expr_gen,
38899 const details::operator_type o0,
38900 const details::operator_type o1,
38901 const details::operator_type o2)
38902 {
38903 return details::build_string()
38904 << "(t" << expr_gen.to_str(o0)
38905 << "(t" << expr_gen.to_str(o1)
38906 << "t)" << expr_gen.to_str(o2)
38907 << "t";
38908 }
38909 };
38910
38911 struct synthesize_vocovoc_expression4
38912 {
38913 typedef typename vocovoc_t::type4 node_type;
38914 typedef typename vocovoc_t::sf4_type sf4_type;
38915 typedef typename node_type::T0 T0;
38916 typedef typename node_type::T1 T1;
38917 typedef typename node_type::T2 T2;
38918 typedef typename node_type::T3 T3;
38919
38920 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38921 const details::operator_type& operation,
38922 expression_node_ptr (&branch)[2])
38923 {
38924
38925 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
38926
38927 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
38928 const Type& v0 = vocov->t0();
38929 const Type c0 = vocov->t1();
38930 const Type& v1 = vocov->t2();
38931 const Type c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
38932 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
38933 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
38934 const details::operator_type o2 = operation;
38935
38936 binary_functor_t f0 = vocov->f0();
38937 binary_functor_t f1 = vocov->f1();
38938 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38939
38940 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38941 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38942
38943 expression_node_ptr result = error_node();
38944
38945 const bool synthesis_result =
38946 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38947 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
38948
38949 if (synthesis_result)
38950 return result;
38951 else if (!expr_gen.valid_operator(o2,f2))
38952 return error_node();
38953
38955
38956 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
38957 }
38958
38959 static inline std::string id(expression_generator<Type>& expr_gen,
38960 const details::operator_type o0,
38961 const details::operator_type o1,
38962 const details::operator_type o2)
38963 {
38964 return details::build_string()
38965 << "(t" << expr_gen.to_str(o0)
38966 << "(t" << expr_gen.to_str(o1)
38967 << "t)" << expr_gen.to_str(o2)
38968 << "t";
38969 }
38970 };
38971
38972 struct synthesize_covovoc_expression4
38973 {
38974 typedef typename covovoc_t::type4 node_type;
38975 typedef typename covovoc_t::sf4_type sf4_type;
38976 typedef typename node_type::T0 T0;
38977 typedef typename node_type::T1 T1;
38978 typedef typename node_type::T2 T2;
38979 typedef typename node_type::T3 T3;
38980
38981 static inline expression_node_ptr
process(expression_generator<Type>& expr_gen,
38982 const details::operator_type& operation,
38983 expression_node_ptr (&branch)[2])
38984 {
38985
38986 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
38987
38988 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
38989 const Type c0 = covov->t0();
38990 const Type& v0 = covov->t1();
38991 const Type& v1 = covov->t2();
38992 const Type c1 =
static_cast<details::literal_node<Type>*
>(branch[1])->
value();
38993 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
38994 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
38995 const details::operator_type o2 = operation;
38996
38997 binary_functor_t f0 = covov->f0();
38998 binary_functor_t f1 = covov->f1();
38999 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39000
39001 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39002 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39003
39004 expression_node_ptr result = error_node();
39005
39006 const bool synthesis_result =
39007 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39008 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
39009
39010 if (synthesis_result)
39011 return result;
39012 else if (!expr_gen.valid_operator(o2,f2))
39013 return error_node();
39014
39016
39017 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
39018 }
39019
39020 static inline std::string id(expression_generator<Type>& expr_gen,
39021 const details::operator_type o0,
39022 const details::operator_type o1,
39023 const details::operator_type o2)
39024 {
39025 return details::build_string()
39026 << "(t" << expr_gen.to_str(o0)
39027 << "(t" << expr_gen.to_str(o1)
39028 << "t)" << expr_gen.to_str(o2)
39029 << "t";
39030 }
39031 };
39032
39033 struct synthesize_vococov_expression4
39034 {
39035 typedef typename vococov_t::type4 node_type;
39036 static inline expression_node_ptr
process(expression_generator<Type>&,
39037 const details::operator_type&,
39038 expression_node_ptr (&)[2])
39039 {
39040
39041 exprtk_debug((
"((v0 o0 (c0 o1 c1)) o2 v1) - Not possible\n"));
39042 return error_node();
39043 }
39044
39045 static inline std::string id(expression_generator<Type>&,
39046 const details::operator_type,
39047 const details::operator_type,
39048 const details::operator_type)
39049 {
39050 return "INVALID";
39051 }
39052 };
39053 #endif
39054
39055 inline expression_node_ptr synthesize_uvouv_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
39056 {
39057
39058 details::operator_type o0 = static_cast<details::uv_base_node<Type>*>(branch[0])->operation();
39059 details::operator_type o1 = static_cast<details::uv_base_node<Type>*>(branch[1])->operation();
39060 const Type& v0 = static_cast<details::uv_base_node<Type>*>(branch[0])->v();
39061 const Type& v1 = static_cast<details::uv_base_node<Type>*>(branch[1])->v();
39062 unary_functor_t u0 = reinterpret_cast<unary_functor_t> (0);
39063 unary_functor_t u1 = reinterpret_cast<unary_functor_t> (0);
39064 binary_functor_t f = reinterpret_cast<binary_functor_t>(0);
39065
39066 if (!valid_operator(o0,u0))
39067 return error_node();
39068 else if (!valid_operator(o1,u1))
39069 return error_node();
39070 else if (!valid_operator(operation,f))
39071 return error_node();
39072
39073 expression_node_ptr result = error_node();
39074
39075 if (
39076 (details::e_neg == o0) &&
39077 (details::e_neg == o1)
39078 )
39079 {
39080 switch (operation)
39081 {
39082
39083 case details::e_add : result = (*this)(details::e_neg,
39084 node_allocator_->
39085 allocate_rr<typename details::
39086 vov_node<Type,details::add_op<Type> > >(v0, v1));
39088 break;
39089
39090
39091 case details::e_sub : result = node_allocator_->
39092 allocate_rr<typename details::
39093 vov_node<Type,details::sub_op<Type> > >(v1, v0);
39095 break;
39096
39097
39098 case details::e_mul : result = node_allocator_->
39099 allocate_rr<typename details::
39100 vov_node<Type,details::mul_op<Type> > >(v0, v1);
39102 break;
39103
39104
39105 case details::e_div : result = node_allocator_->
39106 allocate_rr<typename details::
39107 vov_node<Type,details::div_op<Type> > >(v0, v1);
39109 break;
39110
39111 default : break;
39112 }
39113 }
39114
39115 if (0 == result)
39116 {
39117 result = node_allocator_->
39118 allocate_rrrrr<typename details::uvouv_node<Type> >(v0, v1, u0, u1, f);
39119 }
39120
39121 details::free_all_nodes(*node_allocator_,branch);
39122 return result;
39123 }
39124
39125 #undef basic_opr_switch_statements
39126 #undef extended_opr_switch_statements
39127 #undef unary_opr_switch_statements
39128
39129 #ifndef exprtk_disable_string_capabilities
39130
39131 #define string_opr_switch_statements \
39132 case_stmt(details::e_lt , details::lt_op ) \
39133 case_stmt(details::e_lte , details::lte_op ) \
39134 case_stmt(details::e_gt , details::gt_op ) \
39135 case_stmt(details::e_gte , details::gte_op ) \
39136 case_stmt(details::e_eq , details::eq_op ) \
39137 case_stmt(details::e_ne , details::ne_op ) \
39138 case_stmt(details::e_in , details::in_op ) \
39139 case_stmt(details::e_like , details::like_op ) \
39140 case_stmt(details::e_ilike , details::ilike_op) \
39141
39142 template <typename T0, typename T1>
39143 inline expression_node_ptr synthesize_str_xrox_expression_impl(const details::operator_type& opr,
39144 T0 s0, T1 s1,
39145 range_t rp0)
39146 {
39147 switch (opr)
39148 {
39149 #define case_stmt(op0, op1) \
39150 case op0 : return node_allocator_-> \
39151 allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
39152 (s0, s1, rp0); \
39153
39155 #undef case_stmt
39156 default : return error_node();
39157 }
39158 }
39159
39160 template <typename T0, typename T1>
39161 inline expression_node_ptr synthesize_str_xoxr_expression_impl(const details::operator_type& opr,
39162 T0 s0, T1 s1,
39163 range_t rp1)
39164 {
39165 switch (opr)
39166 {
39167 #define case_stmt(op0, op1) \
39168 case op0 : return node_allocator_-> \
39169 allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
39170 (s0, s1, rp1); \
39171
39173 #undef case_stmt
39174 default : return error_node();
39175 }
39176 }
39177
39178 template <typename T0, typename T1>
39179 inline expression_node_ptr synthesize_str_xroxr_expression_impl(const details::operator_type& opr,
39180 T0 s0, T1 s1,
39181 range_t rp0, range_t rp1)
39182 {
39183 switch (opr)
39184 {
39185 #define case_stmt(op0, op1) \
39186 case op0 : return node_allocator_-> \
39187 allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
39188 (s0, s1, rp0, rp1); \
39189
39191 #undef case_stmt
39192 default : return error_node();
39193 }
39194 }
39195
39196 template <typename T0, typename T1>
39197 inline expression_node_ptr synthesize_sos_expression_impl(const details::operator_type& opr, T0 s0, T1 s1)
39198 {
39199 switch (opr)
39200 {
39201 #define case_stmt(op0, op1) \
39202 case op0 : return node_allocator_-> \
39203 allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0, s1); \
39204
39206 #undef case_stmt
39207 default : return error_node();
39208 }
39209 }
39210
39211 inline expression_node_ptr synthesize_sos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39212 {
39213 std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
39214 std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
39215
39216 return synthesize_sos_expression_impl<std::string&,std::string&>(opr, s0, s1);
39217 }
39218
39219 inline expression_node_ptr synthesize_sros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39220 {
39221 std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
39222 std::string& s1 = static_cast<details::stringvar_node<Type>*> (branch[1])->ref ();
39223 range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
39224
39225 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
39226
39227 details::free_node(*node_allocator_,branch[0]);
39228
39229 return synthesize_str_xrox_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0);
39230 }
39231
39232 inline expression_node_ptr synthesize_sosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39233 {
39234 std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
39235 std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
39236 range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
39237
39238 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
39239
39240 details::free_node(*node_allocator_,branch[1]);
39241
39242 return synthesize_str_xoxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp1);
39243 }
39244
39245 inline expression_node_ptr synthesize_socsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39246 {
39247 std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
39248 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
39249 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
39250
39251 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
39252
39253 details::free_node(*node_allocator_,branch[1]);
39254
39255 return synthesize_str_xoxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp1);
39256 }
39257
39258 inline expression_node_ptr synthesize_srosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39259 {
39260 std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
39261 std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
39262 range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
39263 range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
39264
39265 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
39266 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
39267
39268 details::free_node(*node_allocator_,branch[0]);
39269 details::free_node(*node_allocator_,branch[1]);
39270
39271 return synthesize_str_xroxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0, rp1);
39272 }
39273
39274 inline expression_node_ptr synthesize_socs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39275 {
39276 std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
39277 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
39278
39279 details::free_node(*node_allocator_,branch[1]);
39280
39281 return synthesize_sos_expression_impl<std::string&, const std::string>(opr, s0, s1);
39282 }
39283
39284 inline expression_node_ptr synthesize_csos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39285 {
39286 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
39287 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
39288
39289 details::free_node(*node_allocator_,branch[0]);
39290
39291 return synthesize_sos_expression_impl<const std::string,std::string&>(opr, s0, s1);
39292 }
39293
39294 inline expression_node_ptr synthesize_csosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39295 {
39296 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str ();
39297 std::string& s1 = static_cast<details::string_range_node<Type>* >(branch[1])->ref ();
39298 range_t rp1 = static_cast<details::string_range_node<Type>* >(branch[1])->range();
39299
39300 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
39301
39302 details::free_node(*node_allocator_,branch[0]);
39303 details::free_node(*node_allocator_,branch[1]);
39304
39305 return synthesize_str_xoxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp1);
39306 }
39307
39308 inline expression_node_ptr synthesize_srocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39309 {
39310 std::string& s0 = static_cast<details::string_range_node<Type>* >(branch[0])->ref ();
39311 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str ();
39312 range_t rp0 = static_cast<details::string_range_node<Type>* >(branch[0])->range();
39313
39314 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
39315
39316 details::free_node(*node_allocator_,branch[0]);
39317 details::free_node(*node_allocator_,branch[1]);
39318
39319 return synthesize_str_xrox_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0);
39320 }
39321
39322 inline expression_node_ptr synthesize_srocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39323 {
39324 std::string& s0 = static_cast<details::string_range_node<Type>* >(branch[0])->ref ();
39325 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
39326 range_t rp0 = static_cast<details::string_range_node<Type>* >(branch[0])->range();
39327 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
39328
39329 static_cast<details::string_range_node<Type>*> (branch[0])->range_ref().clear();
39330 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
39331
39332 details::free_node(*node_allocator_,branch[0]);
39333 details::free_node(*node_allocator_,branch[1]);
39334
39335 return synthesize_str_xroxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0, rp1);
39336 }
39337
39338 inline expression_node_ptr synthesize_csocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39339 {
39340 const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
39341 const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
39342
39343 expression_node_ptr result = error_node();
39344
39345 if (details::e_add == opr)
39346 result = node_allocator_->allocate_c<details::string_literal_node<Type> >(s0 + s1);
39347 else if (details::e_in == opr)
39348 result = node_allocator_->allocate_c<details::literal_node<Type> >(details::in_op <Type>::process(s0,s1));
39349 else if (details::e_like == opr)
39350 result = node_allocator_->allocate_c<details::literal_node<Type> >(details::like_op <Type>::process(s0,s1));
39351 else if (details::e_ilike == opr)
39352 result = node_allocator_->allocate_c<details::literal_node<Type> >(details::ilike_op<Type>::process(s0,s1));
39353 else
39354 {
39355 expression_node_ptr temp = synthesize_sos_expression_impl<const std::string, const std::string>(opr, s0, s1);
39356
39357 const Type v = temp->value();
39358
39359 details::free_node(*node_allocator_,temp);
39360
39361 result = node_allocator_->allocate<literal_node_t>(v);
39362 }
39363
39364 details::free_all_nodes(*node_allocator_,branch);
39365
39366 return result;
39367 }
39368
39369 inline expression_node_ptr synthesize_csocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39370 {
39371 const std::string s0 = static_cast<details::string_literal_node<Type>* >(branch[0])->str ();
39372 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
39373 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
39374
39375 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
39376
39377 details::free_node(*node_allocator_,branch[0]);
39378 details::free_node(*node_allocator_,branch[1]);
39379
39380 return synthesize_str_xoxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp1);
39381 }
39382
39383 inline expression_node_ptr synthesize_csros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39384 {
39385 std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
39386 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref ();
39387 range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
39388
39389 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
39390
39391 details::free_node(*node_allocator_,branch[0]);
39392
39393 return synthesize_str_xrox_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0);
39394 }
39395
39396 inline expression_node_ptr synthesize_csrosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39397 {
39398 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
39399 std::string& s1 = static_cast<details::string_range_node<Type>* >(branch[1])->ref ();
39400 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
39401 const range_t rp1 = static_cast<details::string_range_node<Type>* >(branch[1])->range();
39402
39403 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
39404 static_cast<details::string_range_node<Type>*> (branch[1])->range_ref().clear();
39405
39406 details::free_node(*node_allocator_,branch[0]);
39407 details::free_node(*node_allocator_,branch[1]);
39408
39409 return synthesize_str_xroxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0, rp1);
39410 }
39411
39412 inline expression_node_ptr synthesize_csrocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39413 {
39414 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
39415 const std::string s1 = static_cast<details::string_literal_node<Type>* >(branch[1])->str ();
39416 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
39417
39418 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
39419
39420 details::free_all_nodes(*node_allocator_,branch);
39421
39422 return synthesize_str_xrox_expression_impl<const std::string,std::string>(opr, s0, s1, rp0);
39423 }
39424
39425 inline expression_node_ptr synthesize_csrocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39426 {
39427 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
39428 const std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
39429 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
39430 const range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
39431
39432 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
39433 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
39434
39435 details::free_all_nodes(*node_allocator_,branch);
39436
39437 return synthesize_str_xroxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp0, rp1);
39438 }
39439
39440 inline expression_node_ptr synthesize_strogen_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39441 {
39442 switch (opr)
39443 {
39444 #define case_stmt(op0, op1) \
39445 case op0 : return node_allocator_-> \
39446 allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > > \
39447 (opr, branch[0], branch[1]); \
39448
39450 #undef case_stmt
39451 default : return error_node();
39452 }
39453 }
39454 #endif
39455
39456 #ifndef exprtk_disable_string_capabilities
39457 inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
39458 {
39459 if ((0 == branch[0]) || (0 == branch[1]))
39460 {
39461 details::free_all_nodes(*node_allocator_,branch);
39462
39463 return error_node();
39464 }
39465
39466 const bool b0_is_s = details::is_string_node (branch[0]);
39467 const bool b0_is_cs = details::is_const_string_node (branch[0]);
39468 const bool b0_is_sr = details::is_string_range_node (branch[0]);
39469 const bool b0_is_csr = details::is_const_string_range_node(branch[0]);
39470
39471 const bool b1_is_s = details::is_string_node (branch[1]);
39472 const bool b1_is_cs = details::is_const_string_node (branch[1]);
39473 const bool b1_is_sr = details::is_string_range_node (branch[1]);
39474 const bool b1_is_csr = details::is_const_string_range_node(branch[1]);
39475
39476 const bool b0_is_gen = details::is_string_assignment_node (branch[0]) ||
39477 details::is_genricstring_range_node(branch[0]) ||
39478 details::is_string_concat_node (branch[0]) ||
39479 details::is_string_function_node (branch[0]) ||
39480 details::is_string_condition_node (branch[0]) ||
39481 details::is_string_ccondition_node (branch[0]) ||
39482 details::is_string_vararg_node (branch[0]) ;
39483
39484 const bool b1_is_gen = details::is_string_assignment_node (branch[1]) ||
39485 details::is_genricstring_range_node(branch[1]) ||
39486 details::is_string_concat_node (branch[1]) ||
39487 details::is_string_function_node (branch[1]) ||
39488 details::is_string_condition_node (branch[1]) ||
39489 details::is_string_ccondition_node (branch[1]) ||
39490 details::is_string_vararg_node (branch[1]) ;
39491
39492 if (details::e_add == opr)
39493 {
39494 if (!b0_is_cs || !b1_is_cs)
39495 {
39496 return synthesize_expression<string_concat_node_t,2>(opr,branch);
39497 }
39498 }
39499
39500 if (b0_is_gen || b1_is_gen)
39501 {
39502 return synthesize_strogen_expression(opr,branch);
39503 }
39504 else if (b0_is_s)
39505 {
39506 if (b1_is_s ) return synthesize_sos_expression (opr,branch);
39507 else if (b1_is_cs ) return synthesize_socs_expression (opr,branch);
39508 else if (b1_is_sr ) return synthesize_sosr_expression (opr,branch);
39509 else if (b1_is_csr) return synthesize_socsr_expression (opr,branch);
39510 }
39511 else if (b0_is_cs)
39512 {
39513 if (b1_is_s ) return synthesize_csos_expression (opr,branch);
39514 else if (b1_is_cs ) return synthesize_csocs_expression (opr,branch);
39515 else if (b1_is_sr ) return synthesize_csosr_expression (opr,branch);
39516 else if (b1_is_csr) return synthesize_csocsr_expression(opr,branch);
39517 }
39518 else if (b0_is_sr)
39519 {
39520 if (b1_is_s ) return synthesize_sros_expression (opr,branch);
39521 else if (b1_is_sr ) return synthesize_srosr_expression (opr,branch);
39522 else if (b1_is_cs ) return synthesize_srocs_expression (opr,branch);
39523 else if (b1_is_csr) return synthesize_srocsr_expression(opr,branch);
39524 }
39525 else if (b0_is_csr)
39526 {
39527 if (b1_is_s ) return synthesize_csros_expression (opr,branch);
39528 else if (b1_is_sr ) return synthesize_csrosr_expression (opr,branch);
39529 else if (b1_is_cs ) return synthesize_csrocs_expression (opr,branch);
39530 else if (b1_is_csr) return synthesize_csrocsr_expression(opr,branch);
39531 }
39532
39533 return error_node();
39534 }
39535 #else
39536 inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[2])
39537 {
39538 details::free_all_nodes(*node_allocator_,branch);
39539 return error_node();
39540 }
39541 #endif
39542
39543 #ifndef exprtk_disable_string_capabilities
39544 inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[3])
39545 {
39546 if (details::e_inrange != opr)
39547 return error_node();
39548 else if ((0 == branch[0]) || (0 == branch[1]) || (0 == branch[2]))
39549 {
39550 details::free_all_nodes(*node_allocator_,branch);
39551
39552 return error_node();
39553 }
39554 else if (
39555 details::is_const_string_node(branch[0]) &&
39556 details::is_const_string_node(branch[1]) &&
39557 details::is_const_string_node(branch[2])
39558 )
39559 {
39560 const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
39561 const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
39562 const std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
39563
39564 const Type v = (((s0 <= s1) && (s1 <= s2)) ? Type(1) : Type(0));
39565
39566 details::free_all_nodes(*node_allocator_,branch);
39567
39568 return node_allocator_->allocate_c<details::literal_node<Type> >(v);
39569 }
39570 else if (
39571 details::is_string_node(branch[0]) &&
39572 details::is_string_node(branch[1]) &&
39573 details::is_string_node(branch[2])
39574 )
39575 {
39576 std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
39577 std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
39578 std::string& s2 = static_cast<details::stringvar_node<Type>*>(branch[2])->ref();
39579
39580 typedef typename details::sosos_node<Type, std::string&, std::string&, std::string&, details::inrange_op<Type> > inrange_t;
39581
39582 return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string&>(s0, s1, s2);
39583 }
39584 else if (
39585 details::is_const_string_node(branch[0]) &&
39586 details::is_string_node(branch[1]) &&
39587 details::is_const_string_node(branch[2])
39588 )
39589 {
39590 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
39591 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
39592 std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
39593
39594 typedef typename details::sosos_node<Type, std::string, std::string&, std::string, details::inrange_op<Type> > inrange_t;
39595
39596 details::free_node(*node_allocator_,branch[0]);
39597 details::free_node(*node_allocator_,branch[2]);
39598
39599 return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string>(s0, s1, s2);
39600 }
39601 else if (
39602 details::is_string_node(branch[0]) &&
39603 details::is_const_string_node(branch[1]) &&
39604 details::is_string_node(branch[2])
39605 )
39606 {
39607 std::string& s0 = static_cast<details::stringvar_node<Type>* >(branch[0])->ref();
39608 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
39609 std::string& s2 = static_cast<details::stringvar_node<Type>* >(branch[2])->ref();
39610
39611 typedef typename details::sosos_node<Type, std::string&, std::string, std::string&, details::inrange_op<Type> > inrange_t;
39612
39613 details::free_node(*node_allocator_,branch[1]);
39614
39615 return node_allocator_->allocate_type<inrange_t, std::string&, std::string, std::string&>(s0, s1, s2);
39616 }
39617 else if (
39618 details::is_string_node(branch[0]) &&
39619 details::is_string_node(branch[1]) &&
39620 details::is_const_string_node(branch[2])
39621 )
39622 {
39623 std::string& s0 = static_cast<details::stringvar_node<Type>* >(branch[0])->ref();
39624 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
39625 std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
39626
39627 typedef typename details::sosos_node<Type, std::string&, std::string&, std::string, details::inrange_op<Type> > inrange_t;
39628
39629 details::free_node(*node_allocator_,branch[2]);
39630
39631 return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string>(s0, s1, s2);
39632 }
39633 else if (
39634 details::is_const_string_node(branch[0]) &&
39635 details:: is_string_node(branch[1]) &&
39636 details:: is_string_node(branch[2])
39637 )
39638 {
39639 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
39640 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
39641 std::string& s2 = static_cast<details::stringvar_node<Type>* >(branch[2])->ref();
39642
39643 typedef typename details::sosos_node<Type, std::string, std::string&, std::string&, details::inrange_op<Type> > inrange_t;
39644
39645 details::free_node(*node_allocator_,branch[0]);
39646
39647 return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string&>(s0, s1, s2);
39648 }
39649 else
39650 return error_node();
39651 }
39652 #else
39653 inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[3])
39654 {
39655 details::free_all_nodes(*node_allocator_,branch);
39656 return error_node();
39657 }
39658 #endif
39659
39660 inline expression_node_ptr synthesize_null_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
39661 {
39662
39663
39664
39665
39666
39667
39668
39669
39670
39671
39672
39673 typedef typename details::null_eq_node<T> nulleq_node_t;
39674
39675 const bool b0_null = details::is_null_node(branch[0]);
39676 const bool b1_null = details::is_null_node(branch[1]);
39677
39678 if (b0_null && b1_null)
39679 {
39680 expression_node_ptr result = error_node();
39681
39682 if (details::e_eq == operation)
39683 result = node_allocator_->allocate_c<literal_node_t>(T(1));
39684 else if (details::e_ne == operation)
39685 result = node_allocator_->allocate_c<literal_node_t>(T(0));
39686
39687 if (result)
39688 {
39689 details::free_node(*node_allocator_,branch[0]);
39690 details::free_node(*node_allocator_,branch[1]);
39691
39692 return result;
39693 }
39694
39695 details::free_node(*node_allocator_,branch[1]);
39696
39697 return branch[0];
39698 }
39699 else if (details::e_eq == operation)
39700 {
39701 expression_node_ptr result = node_allocator_->
39702 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],true);
39703
39704 details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
39705
39706 return result;
39707 }
39708 else if (details::e_ne == operation)
39709 {
39710 expression_node_ptr result = node_allocator_->
39711 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],false);
39712
39713 details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
39714
39715 return result;
39716 }
39717 else if (b0_null)
39718 {
39719 details::free_node(*node_allocator_,branch[0]);
39720 branch[0] = branch[1];
39721 branch[1] = error_node();
39722 }
39723 else if (b1_null)
39724 {
39725 details::free_node(*node_allocator_,branch[1]);
39726 branch[1] = error_node();
39727 }
39728
39729 if (
39730 (details::e_add == operation) || (details::e_sub == operation) ||
39731 (details::e_mul == operation) || (details::e_div == operation) ||
39732 (details::e_mod == operation) || (details::e_pow == operation)
39733 )
39734 {
39735 return branch[0];
39736 }
39737
39738 details::free_node(*node_allocator_, branch[0]);
39739
39740 if (
39741 (details::e_lt == operation) || (details::e_lte == operation) ||
39742 (details::e_gt == operation) || (details::e_gte == operation) ||
39743 (details::e_and == operation) || (details::e_nand == operation) ||
39744 (details::e_or == operation) || (details::e_nor == operation) ||
39745 (details::e_xor == operation) || (details::e_xnor == operation) ||
39746 (details::e_in == operation) || (details::e_like == operation) ||
39747 (details::e_ilike == operation)
39748 )
39749 {
39750 return node_allocator_->allocate_c<literal_node_t>(T(0));
39751 }
39752
39753 return node_allocator_->allocate<details::null_node<Type> >();
39754 }
39755
39756 template <typename NodeType, std::size_t N>
39757 inline expression_node_ptr synthesize_expression(const details::operator_type& operation, expression_node_ptr (&branch)[N])
39758 {
39759 if (
39760 (details::e_in == operation) ||
39761 (details::e_like == operation) ||
39762 (details::e_ilike == operation)
39763 )
39764 {
39766
39767 return error_node();
39768 }
39769 else if (!details::all_nodes_valid<N>(branch))
39770 {
39772
39773 return error_node();
39774 }
39775 else if ((details::e_default != operation))
39776 {
39777
39778 expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(operation,branch);
39779
39780 if (is_constant_foldable<N>(branch))
39781 {
39782 const Type v = expression_point->value();
39783 details::free_node(*node_allocator_,expression_point);
39784
39785 return node_allocator_->allocate<literal_node_t>(v);
39786 }
39787
39788 if (expression_point && expression_point->valid())
39789 {
39790 return expression_point;
39791 }
39792
39793 parser_->set_error(parser_error::make_error(
39794 parser_error::e_parser,
39795 token_t(),
39796 "ERR246 - Failed to synthesize node: NodeType",
39798
39799 details::free_node(*node_allocator_, expression_point);
39800 }
39801
39802 return error_node();
39803 }
39804
39805 template <typename NodeType, std::size_t N>
39806 inline expression_node_ptr synthesize_expression(F* f, expression_node_ptr (&branch)[N])
39807 {
39808 if (!details::all_nodes_valid<N>(branch))
39809 {
39811
39812 return error_node();
39813 }
39814
39815 typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
39816
39817
39818
39819 expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
39820 function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(expression_point);
39821
39822 if (0 == func_node_ptr)
39823 {
39825
39826 return error_node();
39827 }
39828 else
39829 func_node_ptr->init_branches(branch);
39830
39831 if (is_constant_foldable<N>(branch) && !f->has_side_effects())
39832 {
39833 Type v = expression_point->value();
39834 details::free_node(*node_allocator_,expression_point);
39835
39836 return node_allocator_->allocate<literal_node_t>(v);
39837 }
39838
39839 parser_->state_.activate_side_effect("synthesize_expression(function<NT,N>)");
39840
39841 return expression_point;
39842 }
39843
39844 bool strength_reduction_enabled_;
39845 details::node_allocator* node_allocator_;
39846 synthesize_map_t synthesize_map_;
39847 unary_op_map_t* unary_op_map_;
39848 binary_op_map_t* binary_op_map_;
39849 inv_binary_op_map_t* inv_binary_op_map_;
39850 sf3_map_t* sf3_map_;
39851 sf4_map_t* sf4_map_;
39852 parser_t* parser_;
39853 };
39854
39855 inline void set_error(const parser_error::type& error_type)
39856 {
39857 error_list_.push_back(error_type);
39858 }
39859
39860 inline void remove_last_error()
39861 {
39862 if (!error_list_.empty())
39863 {
39864 error_list_.pop_back();
39865 }
39866 }
39867
39868 inline void set_synthesis_error(const std::string& synthesis_error_message)
39869 {
39870 if (synthesis_error_.empty())
39871 {
39872 synthesis_error_ = synthesis_error_message;
39873 }
39874 }
39875
39876 inline void register_local_vars(expression<T>& e)
39877 {
39878 for (std::size_t i = 0; i < sem_.size(); ++i)
39879 {
39880 scope_element& se = sem_.get_element(i);
39881
39882 if (
39883 (scope_element::e_variable == se.type) ||
39884 (scope_element::e_vecelem == se.type)
39885 )
39886 {
39887 if (se.var_node)
39888 {
39889 e.register_local_var(se.var_node);
39890 }
39891
39892 if (se.data)
39893 {
39894 e.register_local_data(se.data, 1, 0);
39895 }
39896 }
39897 else if (scope_element::e_vector == se.type)
39898 {
39899 if (se.vec_node)
39900 {
39901 e.register_local_var(se.vec_node);
39902 }
39903
39904 if (se.data)
39905 {
39906 e.register_local_data(se.data, se.size, 1);
39907 }
39908 }
39909 #ifndef exprtk_disable_string_capabilities
39910 else if (scope_element::e_string == se.type)
39911 {
39912 if (se.str_node)
39913 {
39914 e.register_local_var(se.str_node);
39915 }
39916
39917 if (se.data)
39918 {
39919 e.register_local_data(se.data, se.size, 2);
39920 }
39921 }
39922 #endif
39923
39924 se.var_node = 0;
39925 se.vec_node = 0;
39926 #ifndef exprtk_disable_string_capabilities
39927 se.str_node = 0;
39928 #endif
39929 se.data = 0;
39930 se.ref_count = 0;
39931 se.active = false;
39932 }
39933 }
39934
39935 inline void register_return_results(expression<T>& e)
39936 {
39937 e.register_return_results(results_context_);
39938 results_context_ = 0;
39939 }
39940
39941 inline void load_unary_operations_map(unary_op_map_t& m)
39942 {
39943 #define register_unary_op(Op, UnaryFunctor) \
39944 m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \
39945
39985 #undef register_unary_op
39986 }
39987
39988 inline void load_binary_operations_map(binary_op_map_t& m)
39989 {
39990 typedef typename binary_op_map_t::value_type value_type;
39991
39992 #define register_binary_op(Op, BinaryFunctor) \
39993 m.insert(value_type(Op,BinaryFunctor<T>::process)); \
39994
40013 #undef register_binary_op
40014 }
40015
40016 inline void load_inv_binary_operations_map(inv_binary_op_map_t& m)
40017 {
40018 typedef typename inv_binary_op_map_t::value_type value_type;
40019
40020 #define register_binary_op(Op, BinaryFunctor) \
40021 m.insert(value_type(BinaryFunctor<T>::process,Op)); \
40022
40041 #undef register_binary_op
40042 }
40043
40044 inline void load_sf3_map(sf3_map_t& sf3_map)
40045 {
40046 typedef std::pair<trinary_functor_t,details::operator_type> pair_t;
40047
40048 #define register_sf3(Op) \
40049 sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
40050
40059 #undef register_sf3
40060
40061 #define register_sf3_extid(Id, Op) \
40062 sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
40063
40065 #undef register_sf3_extid
40066 }
40067
40068 inline void load_sf4_map(sf4_map_t& sf4_map)
40069 {
40070 typedef std::pair<quaternary_functor_t,details::operator_type> pair_t;
40071
40072 #define register_sf4(Op) \
40073 sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
40074
40084 #undef register_sf4
40085
40086 #define register_sf4ext(Op) \
40087 sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \
40088
40105 #undef register_sf4ext
40106 }
40107
40108 inline results_context_t& results_ctx()
40109 {
40110 if (0 == results_context_)
40111 {
40112 results_context_ = new results_context_t();
40113 }
40114
40115 return (*results_context_);
40116 }
40117
40118 inline void return_cleanup()
40119 {
40120 #ifndef exprtk_disable_return_statement
40121 if (results_context_)
40122 {
40123 delete results_context_;
40124 results_context_ = 0;
40125 }
40126
40127 state_.return_stmt_present = false;
40128 #endif
40129 }
40130
40131 private:
40132
40135
40136 settings_store settings_;
40137 expression_generator<T> expression_generator_;
40138 details::node_allocator node_allocator_;
40139 symtab_store symtab_store_;
40140 dependent_entity_collector dec_;
40141 std::deque<parser_error::type> error_list_;
40142 std::deque<bool> brkcnt_list_;
40143 parser_state state_;
40144 bool resolve_unknown_symbol_;
40145 results_context_t* results_context_;
40146 unknown_symbol_resolver* unknown_symbol_resolver_;
40147 unknown_symbol_resolver default_usr_;
40148 base_ops_map_t base_ops_map_;
40149 unary_op_map_t unary_op_map_;
40150 binary_op_map_t binary_op_map_;
40151 inv_binary_op_map_t inv_binary_op_map_;
40152 sf3_map_t sf3_map_;
40153 sf4_map_t sf4_map_;
40154 std::string synthesis_error_;
40155 scope_element_manager sem_;
40156 std::vector<state_t> current_state_stack_;
40157
40158 immutable_memory_map_t immutable_memory_map_;
40159 immutable_symtok_map_t immutable_symtok_map_;
40160
40161 lexer::helper::helper_assembly helper_assembly_;
40162
40163 lexer::helper::commutative_inserter commutative_inserter_;
40164 lexer::helper::operator_joiner operator_joiner_2_;
40165 lexer::helper::operator_joiner operator_joiner_3_;
40166 lexer::helper::symbol_replacer symbol_replacer_;
40167 lexer::helper::bracket_checker bracket_checker_;
40168 lexer::helper::numeric_checker<T> numeric_checker_;
40169 lexer::helper::sequence_validator sequence_validator_;
40170 lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_;
40171
40175
40176 template <typename ParserType>
40177 friend void details::disable_type_checking(ParserType& p);
40178 };
40179
40180 namespace details
40181 {
40182 template <typename T>
40183 struct collector_helper
40184 {
40188 typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
40189 typedef typename parser_t::unknown_symbol_resolver usr_t;
40190
40191 struct resolve_as_vector : public parser_t::unknown_symbol_resolver
40192 {
40194
40195 resolve_as_vector()
40196 : usr_t(usr_t::e_usrmode_extended)
40197 {}
40198
40199 virtual bool process(
const std::string& unknown_symbol,
40200 symbol_table_t& symbol_table,
40201 std::string&)
40202 {
40203 static T v[1];
40204 symbol_table.add_vector(unknown_symbol,v);
40205 return true;
40206 }
40207 };
40208
40209 static inline bool collection_pass(const std::string& expression_string,
40210 std::set<std::string>& symbol_set,
40211 const bool collect_variables,
40212 const bool collect_functions,
40213 const bool vector_pass,
40214 symbol_table_t& ext_symbol_table)
40215 {
40216 symbol_table_t symbol_table;
40217 expression_t expression;
40218 parser_t parser;
40219
40220 resolve_as_vector vect_resolver;
40221
40222 expression.register_symbol_table(symbol_table );
40223 expression.register_symbol_table(ext_symbol_table);
40224
40225 if (vector_pass)
40226 parser.enable_unknown_symbol_resolver(&vect_resolver);
40227 else
40228 parser.enable_unknown_symbol_resolver();
40229
40230 if (collect_variables)
40231 parser.dec().collect_variables() = true;
40232
40233 if (collect_functions)
40234 parser.dec().collect_functions() = true;
40235
40236 bool pass_result = false;
40237
40238 details::disable_type_checking(parser);
40239
40240 if (parser.compile(expression_string, expression))
40241 {
40242 pass_result = true;
40243
40244 std::deque<symbol_t> symb_list;
40245 parser.dec().symbols(symb_list);
40246
40247 for (std::size_t i = 0; i < symb_list.size(); ++i)
40248 {
40249 symbol_set.insert(symb_list[i].first);
40250 }
40251 }
40252
40253 return pass_result;
40254 }
40255 };
40256 }
40257
40258 template <typename Allocator,
40259 template <typename, typename> class Sequence>
40261 Sequence<std::string, Allocator>& symbol_list)
40262 {
40263 typedef double T;
40264 typedef details::collector_helper<T> collect_t;
40265
40266 collect_t::symbol_table_t null_symbol_table;
40267
40268 std::set<std::string> symbol_set;
40269
40270 const bool variable_pass = collect_t::collection_pass
40271 (expression, symbol_set, true, false, false, null_symbol_table);
40272 const bool vector_pass = collect_t::collection_pass
40273 (expression, symbol_set, true, false, true, null_symbol_table);
40274
40275 if (!variable_pass && !vector_pass)
40276 return false;
40277
40278 std::set<std::string>::iterator itr = symbol_set.begin();
40279
40280 while (symbol_set.end() != itr)
40281 {
40282 symbol_list.push_back(*itr);
40283 ++itr;
40284 }
40285
40286 return true;
40287 }
40288
40289 template <typename T,
40290 typename Allocator,
40291 template <typename, typename> class Sequence>
40294 Sequence<std::string, Allocator>& symbol_list)
40295 {
40296 typedef details::collector_helper<T> collect_t;
40297
40298 std::set<std::string> symbol_set;
40299
40300 const bool variable_pass = collect_t::collection_pass
40301 (expression, symbol_set, true, false, false, extrnl_symbol_table);
40302 const bool vector_pass = collect_t::collection_pass
40303 (expression, symbol_set, true, false, true, extrnl_symbol_table);
40304
40305 if (!variable_pass && !vector_pass)
40306 return false;
40307
40308 std::set<std::string>::iterator itr = symbol_set.begin();
40309
40310 while (symbol_set.end() != itr)
40311 {
40312 symbol_list.push_back(*itr);
40313 ++itr;
40314 }
40315
40316 return true;
40317 }
40318
40319 template <typename Allocator,
40320 template <typename, typename> class Sequence>
40322 Sequence<std::string, Allocator>& symbol_list)
40323 {
40324 typedef double T;
40325 typedef details::collector_helper<T> collect_t;
40326
40327 collect_t::symbol_table_t null_symbol_table;
40328
40329 std::set<std::string> symbol_set;
40330
40331 const bool variable_pass = collect_t::collection_pass
40332 (expression, symbol_set, false, true, false, null_symbol_table);
40333 const bool vector_pass = collect_t::collection_pass
40334 (expression, symbol_set, false, true, true, null_symbol_table);
40335
40336 if (!variable_pass && !vector_pass)
40337 return false;
40338
40339 std::set<std::string>::iterator itr = symbol_set.begin();
40340
40341 while (symbol_set.end() != itr)
40342 {
40343 symbol_list.push_back(*itr);
40344 ++itr;
40345 }
40346
40347 return true;
40348 }
40349
40350 template <typename T,
40351 typename Allocator,
40352 template <typename, typename> class Sequence>
40355 Sequence<std::string, Allocator>& symbol_list)
40356 {
40357 typedef details::collector_helper<T> collect_t;
40358
40359 std::set<std::string> symbol_set;
40360
40361 const bool variable_pass = collect_t::collection_pass
40362 (expression, symbol_set, false, true, false, extrnl_symbol_table);
40363 const bool vector_pass = collect_t::collection_pass
40364 (expression, symbol_set, false, true, true, extrnl_symbol_table);
40365
40366 if (!variable_pass && !vector_pass)
40367 return false;
40368
40369 std::set<std::string>::iterator itr = symbol_set.begin();
40370
40371 while (symbol_set.end() != itr)
40372 {
40373 symbol_list.push_back(*itr);
40374 ++itr;
40375 }
40376
40377 return true;
40378 }
40379
40380 template <typename T>
40381 inline T
integrate(
const expression<T>& e,
40382 T& x,
40383 const T& r0, const T& r1,
40384 const std::size_t number_of_intervals = 1000000)
40385 {
40386 if (r0 > r1)
40387 return T(0);
40388
40389 const T h = (r1 - r0) / (T(2) * number_of_intervals);
40390 T total_area = T(0);
40391
40392 for (std::size_t i = 0; i < number_of_intervals; ++i)
40393 {
40394 x = r0 + T(2) * i * h;
40395 const T y0 =
e.value(); x += h;
40396 const T y1 =
e.value(); x += h;
40397 const T y2 =
e.value(); x += h;
40398 total_area += h * (y0 + T(4) * y1 + y2) / T(3);
40399 }
40400
40401 return total_area;
40402 }
40403
40404 template <typename T>
40405 inline T
integrate(
const expression<T>& e,
40406 const std::string& variable_name,
40407 const T& r0, const T& r1,
40408 const std::size_t number_of_intervals = 1000000)
40409 {
40410 const symbol_table<T>& sym_table =
e.get_symbol_table();
40411
40412 if (!sym_table.valid())
40413 {
40414 return std::numeric_limits<T>::quiet_NaN();
40415 }
40416
40417 details::variable_node<T>* var = sym_table.get_variable(variable_name);
40418
40419 if (var)
40420 {
40421 T& x = var->ref();
40422 const T x_original = x;
40423 const T result =
integrate(e, x, r0, r1, number_of_intervals);
40424 x = x_original;
40425
40426 return result;
40427 }
40428
40429 return std::numeric_limits<T>::quiet_NaN();
40430 }
40431
40432 template <typename T>
40434 T& x,
40435 const T& h = T(0.00000001))
40436 {
40437 const T x_init = x;
40438 const T _2h = T(2) * h;
40439
40440 x = x_init + _2h;
40441 const T y0 =
e.value();
40442 x = x_init + h;
40443 const T y1 =
e.value();
40444 x = x_init - h;
40445 const T y2 =
e.value();
40446 x = x_init - _2h;
40447 const T y3 =
e.value();
40448 x = x_init;
40449
40450 return (-y0 + T(8) * (y1 - y2) + y3) / (T(12) * h);
40451 }
40452
40453 template <typename T>
40455 T& x,
40456 const T& h = T(0.00001))
40457 {
40458 const T x_init = x;
40459 const T _2h = T(2) * h;
40460
40461 const T y =
e.value();
40462 x = x_init + _2h;
40463 const T y0 =
e.value();
40464 x = x_init + h;
40465 const T y1 =
e.value();
40466 x = x_init - h;
40467 const T y2 =
e.value();
40468 x = x_init - _2h;
40469 const T y3 =
e.value();
40470 x = x_init;
40471
40472 return (-y0 + T(16) * (y1 + y2) - T(30) * y - y3) / (T(12) * h * h);
40473 }
40474
40475 template <typename T>
40477 T& x,
40478 const T& h = T(0.0001))
40479 {
40480 const T x_init = x;
40481 const T _2h = T(2) * h;
40482
40483 x = x_init + _2h;
40484 const T y0 =
e.value();
40485 x = x_init + h;
40486 const T y1 =
e.value();
40487 x = x_init - h;
40488 const T y2 =
e.value();
40489 x = x_init - _2h;
40490 const T y3 =
e.value();
40491 x = x_init;
40492
40493 return (y0 + T(2) * (y2 - y1) - y3) / (T(2) * h * h * h);
40494 }
40495
40496 template <typename T>
40498 const std::string& variable_name,
40499 const T& h = T(0.00000001))
40500 {
40501 const symbol_table<T>& sym_table =
e.get_symbol_table();
40502
40503 if (!sym_table.valid())
40504 {
40505 return std::numeric_limits<T>::quiet_NaN();
40506 }
40507
40508 details::variable_node<T>* var = sym_table.get_variable(variable_name);
40509
40510 if (var)
40511 {
40512 T& x = var->ref();
40513 const T x_original = x;
40515 x = x_original;
40516
40517 return result;
40518 }
40519
40520 return std::numeric_limits<T>::quiet_NaN();
40521 }
40522
40523 template <typename T>
40525 const std::string& variable_name,
40526 const T& h = T(0.00001))
40527 {
40528 const symbol_table<T>& sym_table =
e.get_symbol_table();
40529
40530 if (!sym_table.valid())
40531 {
40532 return std::numeric_limits<T>::quiet_NaN();
40533 }
40534
40535 details::variable_node<T>* var = sym_table.get_variable(variable_name);
40536
40537 if (var)
40538 {
40539 T& x = var->ref();
40540 const T x_original = x;
40542 x = x_original;
40543
40544 return result;
40545 }
40546
40547 return std::numeric_limits<T>::quiet_NaN();
40548 }
40549
40550 template <typename T>
40552 const std::string& variable_name,
40553 const T& h = T(0.0001))
40554 {
40555 const symbol_table<T>& sym_table =
e.get_symbol_table();
40556
40557 if (!sym_table.valid())
40558 {
40559 return std::numeric_limits<T>::quiet_NaN();
40560 }
40561
40562 details::variable_node<T>* var = sym_table.get_variable(variable_name);
40563
40564 if (var)
40565 {
40566 T& x = var->ref();
40567 const T x_original = x;
40569 x = x_original;
40570
40571 return result;
40572 }
40573
40574 return std::numeric_limits<T>::quiet_NaN();
40575 }
40576
40577
40578
40579
40580
40581
40582
40583
40584
40585
40586
40587 template <typename T>
40588 inline bool compute(
const std::string& expression_string, T& result)
40589 {
40590
40591 symbol_table<T> symbol_table;
40592 symbol_table.add_constants();
40593
40594 expression<T> expression;
40595 expression.register_symbol_table(symbol_table);
40596
40597 parser<T> parser;
40598
40599 if (parser.compile(expression_string,expression))
40600 {
40601 result = expression.value();
40602
40603 return true;
40604 }
40605 else
40606 return false;
40607 }
40608
40609 template <typename T>
40610 inline bool compute(
const std::string& expression_string,
40611 const T& x,
40612 T& result)
40613 {
40614
40615 static const std::string x_var("x");
40616
40617 symbol_table<T> symbol_table;
40618 symbol_table.add_constants();
40619 symbol_table.add_constant(x_var,x);
40620
40621 expression<T> expression;
40622 expression.register_symbol_table(symbol_table);
40623
40624 parser<T> parser;
40625
40626 if (parser.compile(expression_string,expression))
40627 {
40628 result = expression.value();
40629
40630 return true;
40631 }
40632 else
40633 return false;
40634 }
40635
40636 template <typename T>
40637 inline bool compute(
const std::string& expression_string,
40638 const T&x, const T& y,
40639 T& result)
40640 {
40641
40642 static const std::string x_var("x");
40643 static const std::string y_var("y");
40644
40645 symbol_table<T> symbol_table;
40646 symbol_table.add_constants();
40647 symbol_table.add_constant(x_var,x);
40648 symbol_table.add_constant(y_var,y);
40649
40650 expression<T> expression;
40651 expression.register_symbol_table(symbol_table);
40652
40653 parser<T> parser;
40654
40655 if (parser.compile(expression_string,expression))
40656 {
40657 result = expression.value();
40658
40659 return true;
40660 }
40661 else
40662 return false;
40663 }
40664
40665 template <typename T>
40666 inline bool compute(
const std::string& expression_string,
40667 const T& x, const T& y, const T& z,
40668 T& result)
40669 {
40670
40671 static const std::string x_var("x");
40672 static const std::string y_var("y");
40673 static const std::string z_var("z");
40674
40675 symbol_table<T> symbol_table;
40676 symbol_table.add_constants();
40677 symbol_table.add_constant(x_var,x);
40678 symbol_table.add_constant(y_var,y);
40679 symbol_table.add_constant(z_var,z);
40680
40681 expression<T> expression;
40682 expression.register_symbol_table(symbol_table);
40683
40684 parser<T> parser;
40685
40686 if (parser.compile(expression_string,expression))
40687 {
40688 result = expression.value();
40689
40690 return true;
40691 }
40692 else
40693 return false;
40694 }
40695
40696 template <typename T, std::size_t N>
40698 {
40699 private:
40700
40701 template <typename Type, std::size_t NumberOfCoefficients>
40702 struct poly_impl { };
40703
40704 template <typename Type>
40705 struct poly_impl <Type,12>
40706 {
40707 static inline T evaluate(const Type x,
40708 const Type c12, const Type c11, const Type c10, const Type c9, const Type c8,
40709 const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
40710 const Type c2, const Type c1, const Type c0)
40711 {
40712
40713 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);
40714 }
40715 };
40716
40717 template <typename Type>
40718 struct poly_impl <Type,11>
40719 {
40720 static inline T evaluate(const Type x,
40721 const Type c11, const Type c10, const Type c9, const Type c8, const Type c7,
40722 const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
40723 const Type c1, const Type c0)
40724 {
40725
40726 return (((((((((((c11 * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40727 }
40728 };
40729
40730 template <typename Type>
40731 struct poly_impl <Type,10>
40732 {
40733 static inline T evaluate(const Type x,
40734 const Type c10, const Type c9, const Type c8, const Type c7, const Type c6,
40735 const Type c5, const Type c4, const Type c3, const Type c2, const Type c1,
40736 const Type c0)
40737 {
40738
40739 return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40740 }
40741 };
40742
40743 template <typename Type>
40744 struct poly_impl <Type,9>
40745 {
40746 static inline T evaluate(const Type x,
40747 const Type c9, const Type c8, const Type c7, const Type c6, const Type c5,
40748 const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
40749 {
40750
40751 return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40752 }
40753 };
40754
40755 template <typename Type>
40756 struct poly_impl <Type,8>
40757 {
40758 static inline T evaluate(const Type x,
40759 const Type c8, const Type c7, const Type c6, const Type c5, const Type c4,
40760 const Type c3, const Type c2, const Type c1, const Type c0)
40761 {
40762
40763 return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40764 }
40765 };
40766
40767 template <typename Type>
40768 struct poly_impl <Type,7>
40769 {
40770 static inline T evaluate(const Type x,
40771 const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
40772 const Type c2, const Type c1, const Type c0)
40773 {
40774
40775 return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40776 }
40777 };
40778
40779 template <typename Type>
40780 struct poly_impl <Type,6>
40781 {
40782 static inline T evaluate(const Type x,
40783 const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
40784 const Type c1, const Type c0)
40785 {
40786
40787 return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40788 }
40789 };
40790
40791 template <typename Type>
40792 struct poly_impl <Type,5>
40793 {
40794 static inline T evaluate(const Type x,
40795 const Type c5, const Type c4, const Type c3, const Type c2,
40796 const Type c1, const Type c0)
40797 {
40798
40799 return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40800 }
40801 };
40802
40803 template <typename Type>
40804 struct poly_impl <Type,4>
40805 {
40806 static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
40807 {
40808
40809 return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0);
40810 }
40811 };
40812
40813 template <typename Type>
40814 struct poly_impl <Type,3>
40815 {
40816 static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
40817 {
40818
40819 return (((c3 * x + c2) * x + c1) * x + c0);
40820 }
40821 };
40822
40823 template <typename Type>
40824 struct poly_impl <Type,2>
40825 {
40826 static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
40827 {
40828
40829 return ((c2 * x + c1) * x + c0);
40830 }
40831 };
40832
40833 template <typename Type>
40834 struct poly_impl <Type,1>
40835 {
40836 static inline T evaluate(const Type x, const Type c1, const Type c0)
40837 {
40838
40839 return (c1 * x + c0);
40840 }
40841 };
40842
40843 public:
40844
40845 using ifunction<T>::operator();
40846
40848 : ifunction<T>((N+2 <= 20) ? (N + 2) :
std::numeric_limits<
std::size_t>::
max())
40849 {
40851 }
40852
40853 virtual ~polynomial()
40854 {}
40855
40856 #define poly_rtrn(NN) \
40857 return (NN != N) ? std::numeric_limits<T>::quiet_NaN() :
40858
40859 inline virtual T operator() (
const T& x,
const T& c1,
const T& c0)
exprtk_override
40860 {
40861 poly_rtrn(1) (poly_impl<T,1>::evaluate(x, c1, c0));
40862 }
40863
40864 inline virtual T operator() (
const T& x,
const T& c2,
const T& c1,
const T& c0)
exprtk_override
40865 {
40866 poly_rtrn(2) (poly_impl<T,2>::evaluate(x, c2, c1, c0));
40867 }
40868
40869 inline virtual T operator() (
const T& x,
const T& c3,
const T& c2,
const T& c1,
const T& c0)
exprtk_override
40870 {
40871 poly_rtrn(3) (poly_impl<T,3>::evaluate(x, c3, c2, c1, c0));
40872 }
40873
40874 inline virtual T operator() (const T& x, const T& c4, const T& c3, const T& c2, const T& c1,
40876 {
40877 poly_rtrn(4) (poly_impl<T,4>::evaluate(x, c4, c3, c2, c1, c0));
40878 }
40879
40880 inline virtual T operator() (const T& x, const T& c5, const T& c4, const T& c3, const T& c2,
40882 {
40883 poly_rtrn(5) (poly_impl<T,5>::evaluate(x, c5, c4, c3, c2, c1, c0));
40884 }
40885
40886 inline virtual T operator() (const T& x, const T& c6, const T& c5, const T& c4, const T& c3,
40888 {
40889 poly_rtrn(6) (poly_impl<T,6>::evaluate(x, c6, c5, c4, c3, c2, c1, c0));
40890 }
40891
40892 inline virtual T operator() (const T& x, const T& c7, const T& c6, const T& c5, const T& c4,
40894 {
40895 poly_rtrn(7) (poly_impl<T,7>::evaluate(x, c7, c6, c5, c4, c3, c2, c1, c0));
40896 }
40897
40898 inline virtual T operator() (const T& x, const T& c8, const T& c7, const T& c6, const T& c5,
40899 const T& c4,
const T& c3,
const T& c2,
const T& c1,
const T& c0)
exprtk_override
40900 {
40901 poly_rtrn(8) (poly_impl<T,8>::evaluate(x, c8, c7, c6, c5, c4, c3, c2, c1, c0));
40902 }
40903
40904 inline virtual T operator() (const T& x, const T& c9, const T& c8, const T& c7, const T& c6,
40905 const T& c5, const T& c4, const T& c3, const T& c2, const T& c1,
40907 {
40908 poly_rtrn(9) (poly_impl<T,9>::evaluate(x, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
40909 }
40910
40911 inline virtual T operator() (const T& x, const T& c10, const T& c9, const T& c8, const T& c7,
40912 const T& c6, const T& c5, const T& c4, const T& c3, const T& c2,
40914 {
40915 poly_rtrn(10) (poly_impl<T,10>::evaluate(x, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
40916 }
40917
40918 inline virtual T operator() (const T& x, const T& c11, const T& c10, const T& c9, const T& c8,
40919 const T& c7, const T& c6, const T& c5, const T& c4, const T& c3,
40921 {
40922 poly_rtrn(11) (poly_impl<T,11>::evaluate(x, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
40923 }
40924
40925 inline virtual T operator() (const T& x, const T& c12, const T& c11, const T& c10, const T& c9,
40926 const T& c8, const T& c7, const T& c6, const T& c5, const T& c4,
40928 {
40929 poly_rtrn(12) (poly_impl<T,12>::evaluate(x, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
40930 }
40931
40932 #undef poly_rtrn
40933
40935 {
40936 return std::numeric_limits<T>::quiet_NaN();
40937 }
40938
40940 {
40941 return std::numeric_limits<T>::quiet_NaN();
40942 }
40943
40945 {
40946 return std::numeric_limits<T>::quiet_NaN();
40947 }
40948 };
40949
40950 template <typename T>
40951 class function_compositor
40952 {
40953 public:
40954
40958 typedef typename parser_t::settings_store settings_t;
40959
40960 struct function
40961 {
40962 function()
40963 {}
40964
40965 function(const std::string& n)
40966 : name_(n)
40967 {}
40968
40969 function(const std::string& name,
40970 const std::string& expression)
40971 : name_(name)
40972 , expression_(expression)
40973 {}
40974
40975 function(const std::string& name,
40976 const std::string& expression,
40977 const std::string& v0)
40978 : name_(name)
40979 , expression_(expression)
40980 {
40981 v_.push_back(v0);
40982 }
40983
40984 function(const std::string& name,
40985 const std::string& expression,
40986 const std::string& v0, const std::string& v1)
40987 : name_(name)
40988 , expression_(expression)
40989 {
40990 v_.push_back(v0); v_.push_back(v1);
40991 }
40992
40993 function(const std::string& name,
40994 const std::string& expression,
40995 const std::string& v0, const std::string& v1,
40996 const std::string& v2)
40997 : name_(name)
40998 , expression_(expression)
40999 {
41000 v_.push_back(v0); v_.push_back(v1);
41001 v_.push_back(v2);
41002 }
41003
41004 function(const std::string& name,
41005 const std::string& expression,
41006 const std::string& v0, const std::string& v1,
41007 const std::string& v2, const std::string& v3)
41008 : name_(name)
41009 , expression_(expression)
41010 {
41011 v_.push_back(v0); v_.push_back(v1);
41012 v_.push_back(v2); v_.push_back(v3);
41013 }
41014
41015 function(const std::string& name,
41016 const std::string& expression,
41017 const std::string& v0, const std::string& v1,
41018 const std::string& v2, const std::string& v3,
41019 const std::string& v4)
41020 : name_(name)
41021 , expression_(expression)
41022 {
41023 v_.push_back(v0); v_.push_back(v1);
41024 v_.push_back(v2); v_.push_back(v3);
41025 v_.push_back(v4);
41026 }
41027
41028 inline function& name(const std::string& n)
41029 {
41030 name_ = n;
41031 return (*this);
41032 }
41033
41034 inline function& expression(const std::string& e)
41035 {
41037 return (*this);
41038 }
41039
41040 inline function& var(const std::string& v)
41041 {
41042 v_.push_back(v);
41043 return (*this);
41044 }
41045
41046 inline function& vars(const std::string& v0,
41047 const std::string& v1)
41048 {
41049 v_.push_back(v0);
41050 v_.push_back(v1);
41051 return (*this);
41052 }
41053
41054 inline function& vars(const std::string& v0,
41055 const std::string& v1,
41056 const std::string& v2)
41057 {
41058 v_.push_back(v0);
41059 v_.push_back(v1);
41060 v_.push_back(v2);
41061 return (*this);
41062 }
41063
41064 inline function& vars(const std::string& v0,
41065 const std::string& v1,
41066 const std::string& v2,
41067 const std::string& v3)
41068 {
41069 v_.push_back(v0);
41070 v_.push_back(v1);
41071 v_.push_back(v2);
41072 v_.push_back(v3);
41073 return (*this);
41074 }
41075
41076 inline function& vars(const std::string& v0,
41077 const std::string& v1,
41078 const std::string& v2,
41079 const std::string& v3,
41080 const std::string& v4)
41081 {
41082 v_.push_back(v0);
41083 v_.push_back(v1);
41084 v_.push_back(v2);
41085 v_.push_back(v3);
41086 v_.push_back(v4);
41087 return (*this);
41088 }
41089
41090 std::string name_;
41091 std::string expression_;
41092 std::deque<std::string> v_;
41093 };
41094
41095 private:
41096
41098 {
41099 typedef const T& type;
41101 typedef std::vector<T*> varref_t;
41102 typedef std::vector<T> var_t;
41103 typedef std::pair<T*,std::size_t> lvarref_t;
41104 typedef std::vector<lvarref_t> lvr_vec_t;
41105
41107
41109 :
exprtk::ifunction<T>(pc)
41110 , local_var_stack_size(0)
41111 , stack_depth(0)
41112 {
41113 v.resize(pc);
41114 }
41115
41117 {}
41118
41119 #define exprtk_assign(Index) \
41120 (*v[Index]) = v##Index; \
41121
41122 inline void update(const T& v0)
41123 {
41125 }
41126
41127 inline void update(const T& v0, const T& v1)
41128 {
41130 }
41131
41132 inline void update(const T& v0, const T& v1, const T& v2)
41133 {
41136 }
41137
41138 inline void update(const T& v0, const T& v1, const T& v2, const T& v3)
41139 {
41142 }
41143
41144 inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
41145 {
41149 }
41150
41151 inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
41152 {
41156 }
41157
41158 #ifdef exprtk_assign
41159 #undef exprtk_assign
41160 #endif
41161
41162 inline function_t& setup(expression_t& expr)
41163 {
41164 expression = expr;
41165
41166 typedef typename expression_t::control_block::local_data_list_t ldl_t;
41167
41168 const ldl_t ldl = expr.local_data_list();
41169
41170 std::vector<std::size_t> index_list;
41171
41172 for (std::size_t i = 0; i < ldl.size(); ++i)
41173 {
41174 if (ldl[i].size)
41175 {
41176 index_list.push_back(i);
41177 }
41178 }
41179
41180 std::size_t input_param_count = 0;
41181
41182 for (std::size_t i = 0; i < index_list.size(); ++i)
41183 {
41184 const std::size_t index = index_list[i];
41185
41186 if (i < (index_list.size() - v.size()))
41187 {
41188 lv.push_back(
41189 std::make_pair(
41190 reinterpret_cast<T*>(ldl[index].pointer),
41191 ldl[index].size));
41192
41193 local_var_stack_size += ldl[index].size;
41194 }
41195 else
41196 v[input_param_count++] = reinterpret_cast<T*>(ldl[index].pointer);
41197 }
41198
41199 clear_stack();
41200
41201 return (*this);
41202 }
41203
41204 inline void pre()
41205 {
41206 if (stack_depth++)
41207 {
41208 if (!v.empty())
41209 {
41210 var_t var_stack(v.size(),T(0));
41211 copy(v,var_stack);
41212 param_stack.push_back(var_stack);
41213 }
41214
41215 if (!lv.empty())
41216 {
41217 var_t local_var_stack(local_var_stack_size,T(0));
41218 copy(lv,local_var_stack);
41219 local_stack.push_back(local_var_stack);
41220 }
41221 }
41222 }
41223
41224 inline void post()
41225 {
41226 if (--stack_depth)
41227 {
41228 if (!v.empty())
41229 {
41230 copy(param_stack.back(),v);
41231 param_stack.pop_back();
41232 }
41233
41234 if (!lv.empty())
41235 {
41236 copy(local_stack.back(),lv);
41237 local_stack.pop_back();
41238 }
41239 }
41240 }
41241
41242 void copy(const varref_t& src_v, var_t& dest_v)
41243 {
41244 for (std::size_t i = 0; i < src_v.size(); ++i)
41245 {
41246 dest_v[i] = (*src_v[i]);
41247 }
41248 }
41249
41250 void copy(const var_t& src_v, varref_t& dest_v)
41251 {
41252 for (std::size_t i = 0; i < src_v.size(); ++i)
41253 {
41254 (*dest_v[i]) = src_v[i];
41255 }
41256 }
41257
41258 void copy(const lvr_vec_t& src_v, var_t& dest_v)
41259 {
41260 typename var_t::iterator itr = dest_v.begin();
41261 typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
41262
41263 for (std::size_t i = 0; i < src_v.size(); ++i)
41264 {
41265 lvarref_t vr = src_v[i];
41266
41267 if (1 == vr.second)
41268 *itr++ = (*vr.first);
41269 else
41270 {
41271 std::copy(vr.first, vr.first + vr.second, itr);
41272 itr += static_cast<diff_t>(vr.second);
41273 }
41274 }
41275 }
41276
41277 void copy(const var_t& src_v, lvr_vec_t& dest_v)
41278 {
41279 typename var_t::const_iterator itr = src_v.begin();
41280 typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
41281
41282 for (std::size_t i = 0; i < src_v.size(); ++i)
41283 {
41284 lvarref_t vr = dest_v[i];
41285
41286 if (1 == vr.second)
41287 (*vr.first) = *itr++;
41288 else
41289 {
41290 std::copy(itr, itr + static_cast<diff_t>(vr.second), vr.first);
41291 itr += static_cast<diff_t>(vr.second);
41292 }
41293 }
41294 }
41295
41296 inline void clear_stack()
41297 {
41298 for (std::size_t i = 0; i < v.size(); ++i)
41299 {
41300 (*v[i]) = 0;
41301 }
41302 }
41303
41304 inline virtual T
value(expression_t& e)
41305 {
41307 }
41308
41309 expression_t expression;
41310 varref_t v;
41311 lvr_vec_t lv;
41312 std::size_t local_var_stack_size;
41313 std::size_t stack_depth;
41314 std::deque<var_t> param_stack;
41315 std::deque<var_t> local_stack;
41316 };
41317
41318 typedef std::map<std::string,base_func*> funcparam_t;
41319
41321 {
41323
41325
41327 {
41328 return this->
value(base_func::expression);
41329 }
41330 };
41331
41332 typedef const T& type;
41333
41334 template <typename BaseFuncType>
41335 struct scoped_bft
41336 {
41337 explicit scoped_bft(BaseFuncType& bft)
41338 : bft_(bft)
41339 {
41340 bft_.pre ();
41341 }
41342
41343 ~scoped_bft()
41344 {
41345 bft_.post();
41346 }
41347
41348 BaseFuncType& bft_;
41349
41350 private:
41351
41354 };
41355
41357 {
41359
41361
41363 {
41364 scoped_bft<func_1param> sb(*this);
41365 base_func::update(v0);
41366 return this->
value(base_func::expression);
41367 }
41368 };
41369
41371 {
41373
41375
41377 {
41378 scoped_bft<func_2param> sb(*this);
41379 base_func::update(v0, v1);
41380 return this->
value(base_func::expression);
41381 }
41382 };
41383
41385 {
41387
41389
41391 {
41392 scoped_bft<func_3param> sb(*this);
41393 base_func::update(v0, v1, v2);
41394 return this->
value(base_func::expression);
41395 }
41396 };
41397
41399 {
41401
41403
41404 inline T operator() (type v0, type v1, type v2, type v3)
exprtk_override
41405 {
41406 scoped_bft<func_4param> sb(*this);
41407 base_func::update(v0, v1, v2, v3);
41408 return this->
value(base_func::expression);
41409 }
41410 };
41411
41413 {
41415
41417
41418 inline T operator() (type v0, type v1, type v2, type v3, type v4)
exprtk_override
41419 {
41420 scoped_bft<func_5param> sb(*this);
41421 base_func::update(v0, v1, v2, v3, v4);
41422 return this->
value(base_func::expression);
41423 }
41424 };
41425
41427 {
41429
41431
41432 inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5)
exprtk_override
41433 {
41434 scoped_bft<func_6param> sb(*this);
41435 base_func::update(v0, v1, v2, v3, v4, v5);
41436 return this->
value(base_func::expression);
41437 }
41438 };
41439
41440 static T return_value(expression_t& e)
41441 {
41443 typedef typename results_context_t::type_store_t type_t;
41444 typedef typename type_t::scalar_view scalar_t;
41445
41446 const T result =
e.value();
41447
41448 if (
e.return_invoked())
41449 {
41450
41451
41452
41453 return scalar_t(
e.results()[0])();
41454 }
41455
41456 return result;
41457 }
41458
41459 #define def_fp_retval(N) \
41460 struct func_##N##param_retval exprtk_final : public func_##N##param \
41461 { \
41462 inline T value(expression_t& e) exprtk_override \
41463 { \
41464 return return_value(e); \
41465 } \
41466 }; \
41467
41475
41476 template <typename Allocator,
41477 template <typename, typename> class Sequence>
41478 inline
bool add(const
std::
string& name,
41479 const
std::
string& expression,
41480 const Sequence<
std::
string,Allocator>& var_list,
41481 const bool override = false)
41482 {
41483 const typename std::map<std::string,expression_t>::iterator itr = expr_map_.find(name);
41484
41485 if (expr_map_.end() != itr)
41486 {
41487 if (!override)
41488 {
41489 exprtk_debug((
"Compositor error(add): function '%s' already defined\n",
41490 name.c_str()));
41491
41492 return false;
41493 }
41494
41495 remove(name, var_list.size());
41496 }
41497
41498 if (compile_expression(name, expression, var_list))
41499 {
41500 const std::size_t n = var_list.size();
41501
41502 fp_map_[n][name]->setup(expr_map_[name]);
41503
41504 return true;
41505 }
41506 else
41507 {
41508 exprtk_debug((
"Compositor error(add): Failed to compile function '%s'\n",
41509 name.c_str()));
41510
41511 return false;
41512 }
41513 }
41514
41515 public:
41516
41517 function_compositor()
41518 : parser_(settings_t::default_compile_all_opts +
41519 settings_t::e_disable_zero_return)
41520 , fp_map_(7)
41521 , load_variables_(false)
41522 , load_vectors_(false)
41523 {}
41524
41525 explicit function_compositor(const symbol_table_t& st)
41526 : symbol_table_(st)
41527 , parser_(settings_t::default_compile_all_opts +
41528 settings_t::e_disable_zero_return)
41529 , fp_map_(7)
41530 , load_variables_(false)
41531 , load_vectors_(false)
41532 {}
41533
41534 ~function_compositor()
41535 {
41536 clear();
41537 }
41538
41539 inline symbol_table_t& symbol_table()
41540 {
41541 return symbol_table_;
41542 }
41543
41544 inline const symbol_table_t& symbol_table() const
41545 {
41546 return symbol_table_;
41547 }
41548
41549 inline void add_auxiliary_symtab(symbol_table_t& symtab)
41550 {
41551 auxiliary_symtab_list_.push_back(&symtab);
41552 }
41553
41554 void load_variables(const bool load)
41555 {
41556 load_variables_ = load;
41557 }
41558
41559 void load_vectors(const bool load)
41560 {
41561 load_vectors_ = load;
41562 }
41563
41564 void clear()
41565 {
41566 symbol_table_.clear();
41567 expr_map_ .clear();
41568
41569 for (std::size_t i = 0; i < fp_map_.size(); ++i)
41570 {
41571 typename funcparam_t::iterator itr = fp_map_[i].begin();
41572 typename funcparam_t::iterator end = fp_map_[i].end ();
41573
41574 while (itr != end)
41575 {
41576 delete itr->second;
41577 ++itr;
41578 }
41579
41580 fp_map_[i].clear();
41581 }
41582 }
41583
41584 inline bool add(const function& f, const bool override = false)
41585 {
41586 return add(f.name_, f.expression_, f.v_,override);
41587 }
41588
41589 inline std::string error() const
41590 {
41591 if (!error_list_.empty())
41592 {
41593 return error_list_[0].diagnostic;
41594 }
41595 else
41596 return std::string("No Error");
41597 }
41598
41599 inline std::size_t error_count() const
41600 {
41601 return error_list_.size();
41602 }
41603
41604 inline parser_error::type get_error(const std::size_t& index) const
41605 {
41606 if (index < error_list_.size())
41607 return error_list_[index];
41608 else
41609 throw std::invalid_argument("compositor::get_error() - Invalid error index specified");
41610 }
41611
41612 private:
41613
41614 template <typename Allocator,
41615 template <typename, typename> class Sequence>
41616 bool compile_expression(const std::string& name,
41617 const std::string& expression,
41618 const Sequence<std::string,Allocator>& input_var_list,
41619 bool return_present = false)
41620 {
41621 expression_t compiled_expression;
41622 symbol_table_t local_symbol_table;
41623
41624 local_symbol_table.load_from(symbol_table_);
41625 local_symbol_table.add_constants();
41626
41627 if (load_variables_)
41628 {
41629 local_symbol_table.load_variables_from(symbol_table_);
41630 }
41631
41632 if (load_vectors_)
41633 {
41634 local_symbol_table.load_vectors_from(symbol_table_);
41635 }
41636
41637 error_list_.clear();
41638
41639 if (!valid(name,input_var_list.size()))
41640 {
41641 parser_error::type error =
41642 parser_error::make_error(
41643 parser_error::e_parser,
41644 lexer::token(),
41645 "ERR247 - Function '" + name + "' is an invalid overload",
41647
41648 error_list_.push_back(error);
41649 return false;
41650 }
41651
41652 if (!forward(name,
41653 input_var_list.size(),
41654 local_symbol_table,
41655 return_present))
41656 return false;
41657
41658 compiled_expression.register_symbol_table(local_symbol_table);
41659
41660 for (std::size_t i = 0; i < auxiliary_symtab_list_.size(); ++i)
41661 {
41662 compiled_expression.register_symbol_table((*auxiliary_symtab_list_[i]));
41663 }
41664
41665 std::string mod_expression;
41666
41667 for (std::size_t i = 0; i < input_var_list.size(); ++i)
41668 {
41669 mod_expression += " var " + input_var_list[i] + "{};\n";
41670 }
41671
41672 if (
41673 ('{' == details::front(expression)) &&
41674 ('}' == details::back (expression))
41675 )
41676 mod_expression += "~" + expression + ";";
41677 else
41678 mod_expression += "~{" + expression + "};";
41679
41680 if (!parser_.compile(mod_expression,compiled_expression))
41681 {
41682 exprtk_debug((
"Compositor Error: %s\n",parser_.error().c_str()));
41683 exprtk_debug((
"Compositor modified expression: \n%s\n",mod_expression.c_str()));
41684
41685 remove(name,input_var_list.size());
41686
41687 for (std::size_t err_index = 0; err_index < parser_.error_count(); ++err_index)
41688 {
41689 error_list_.push_back(parser_.get_error(err_index));
41690 }
41691
41692 return false;
41693 }
41694
41695 if (!return_present && parser_.dec().return_present())
41696 {
41697 remove(name,input_var_list.size());
41698 return compile_expression(name, expression, input_var_list, true);
41699 }
41700
41701
41702 if (parser_.dec().return_present())
41703 {
41704 typedef std::vector<std::string> str_list_t;
41705
41706 str_list_t ret_param_list = parser_.dec().return_param_type_list();
41707
41708 for (std::size_t i = 0; i < ret_param_list.size(); ++i)
41709 {
41710 const std::string& params = ret_param_list[i];
41711
41712 if (params.empty() || ('T' != params[0]))
41713 {
41714 exprtk_debug((
"Compositor Error: Return statement in function '%s' is invalid\n",
41715 name.c_str()));
41716
41717 remove(name,input_var_list.size());
41718
41719 return false;
41720 }
41721 }
41722 }
41723
41724 expr_map_[name] = compiled_expression;
41725
41727
41728 if (symbol_table_.add_function(name,ifunc))
41729 return true;
41730 else
41731 {
41732 exprtk_debug((
"Compositor Error: Failed to add function '%s' to symbol table\n",
41733 name.c_str()));
41734 return false;
41735 }
41736 }
41737
41738 inline bool symbol_used(const std::string& symbol) const
41739 {
41740 return (
41741 symbol_table_.is_variable (symbol) ||
41742 symbol_table_.is_stringvar (symbol) ||
41743 symbol_table_.is_function (symbol) ||
41744 symbol_table_.is_vector (symbol) ||
41745 symbol_table_.is_vararg_function(symbol)
41746 );
41747 }
41748
41749 inline bool valid(const std::string& name,
41750 const std::size_t& arg_count) const
41751 {
41752 if (arg_count > 6)
41753 return false;
41754 else if (symbol_used(name))
41755 return false;
41756 else if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name))
41757 return false;
41758 else
41759 return true;
41760 }
41761
41762 inline bool forward(const std::string& name,
41763 const std::size_t& arg_count,
41764 symbol_table_t& sym_table,
41765 const bool ret_present = false)
41766 {
41767 switch (arg_count)
41768 {
41769 #define case_stmt(N) \
41770 case N : (fp_map_[arg_count])[name] = \
41771 (!ret_present) ? static_cast<base_func*> \
41772 (new func_##N##param) : \
41773 static_cast<base_func*> \
41774 (new func_##N##param_retval) ; \
41775 break; \
41776
41780 #undef case_stmt
41781 }
41782
41784
41785 return sym_table.add_function(name,ifunc);
41786 }
41787
41788 inline void remove(const std::string& name, const std::size_t& arg_count)
41789 {
41790 if (arg_count > 6)
41791 return;
41792
41793 const typename std::map<std::string,expression_t>::iterator em_itr = expr_map_.find(name);
41794
41795 if (expr_map_.end() != em_itr)
41796 {
41797 expr_map_.erase(em_itr);
41798 }
41799
41800 const typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name);
41801
41802 if (fp_map_[arg_count].end() != fp_itr)
41803 {
41804 delete fp_itr->second;
41805 fp_map_[arg_count].erase(fp_itr);
41806 }
41807
41808 symbol_table_.remove_function(name);
41809 }
41810
41811 private:
41812
41813 symbol_table_t symbol_table_;
41814 parser_t parser_;
41815 std::map<std::string,expression_t> expr_map_;
41816 std::vector<funcparam_t> fp_map_;
41817 std::vector<symbol_table_t*> auxiliary_symtab_list_;
41818 std::deque<parser_error::type> error_list_;
41819 bool load_variables_;
41820 bool load_vectors_;
41821 };
41822
41823}
41824
41825#if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
41826# ifndef NOMINMAX
41827# define NOMINMAX
41828# endif
41829# ifndef WIN32_LEAN_AND_MEAN
41830# define WIN32_LEAN_AND_MEAN
41831# endif
41832# include <windows.h>
41833# include <ctime>
41834#else
41835# include <ctime>
41836# include <sys/time.h>
41837# include <sys/types.h>
41838#endif
41839
41841{
41842 class timer
41843 {
41844 public:
41845
41846 #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
41847 timer()
41848 : in_use_(false)
41849 , start_time_{ 0 }
41850 , stop_time_ { 0 }
41851 {
41852 QueryPerformanceFrequency(&clock_frequency_);
41853 }
41854
41855 inline void start()
41856 {
41857 in_use_ = true;
41858 QueryPerformanceCounter(&start_time_);
41859 }
41860
41861 inline void stop()
41862 {
41863 QueryPerformanceCounter(&stop_time_);
41864 in_use_ = false;
41865 }
41866
41867 inline double time() const
41868 {
41869 return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart);
41870 }
41871
41872 #else
41873
41874 timer()
41875 : in_use_(false)
41876 {
41877 start_time_.tv_sec = 0;
41878 start_time_.tv_usec = 0;
41879
41880 stop_time_.tv_sec = 0;
41881 stop_time_.tv_usec = 0;
41882 }
41883
41884 inline void start()
41885 {
41886 in_use_ = true;
41887 gettimeofday(&start_time_,0);
41888 }
41889
41890 inline void stop()
41891 {
41892 gettimeofday(&stop_time_, 0);
41893 in_use_ = false;
41894 }
41895
41896 inline unsigned long long int usec_time() const
41897 {
41898 if (!in_use_)
41899 {
41900 if (stop_time_.tv_sec >= start_time_.tv_sec)
41901 {
41902 return 1000000LLU * static_cast<details::_uint64_t>(stop_time_.tv_sec - start_time_.tv_sec ) +
41903 static_cast<details::_uint64_t>(stop_time_.tv_usec - start_time_.tv_usec) ;
41904 }
41905 else
41906 return std::numeric_limits<details::_uint64_t>::max();
41907 }
41908 else
41909 return std::numeric_limits<details::_uint64_t>::max();
41910 }
41911
41912 inline double time() const
41913 {
41914 return usec_time() * 0.000001;
41915 }
41916
41917 #endif
41918
41919 inline bool in_use() const
41920 {
41921 return in_use_;
41922 }
41923
41924 private:
41925
41926 bool in_use_;
41927
41928 #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
41929 LARGE_INTEGER start_time_;
41930 LARGE_INTEGER stop_time_;
41931 LARGE_INTEGER clock_frequency_;
41932 #else
41933 struct timeval start_time_;
41934 struct timeval stop_time_;
41935 #endif
41936 };
41937
41938 template <typename T>
41939 struct type_defs
41940 {
41941 typedef symbol_table<T> symbol_table_t;
41942 typedef expression<T> expression_t;
41943 typedef parser<T> parser_t;
41944 typedef parser_error::type error_t;
41945 typedef function_compositor<T> compositor_t;
41946 typedef typename compositor_t::function function_t;
41947 };
41948
41949}
41950
41951#ifndef exprtk_disable_rtl_io
41953{
41954 namespace rtl { namespace io { namespace details
41955 {
41956 template <typename T>
41957 inline void print_type(
const std::string& fmt,
41958 const T v,
41960 {
41961 #if defined(__clang__)
41962 #pragma clang diagnostic push
41963 #pragma clang diagnostic ignored "-Wformat-nonliteral"
41964 #elif defined(__GNUC__) || defined(__GNUG__)
41965 #pragma GCC diagnostic push
41966 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
41967 #elif defined(_MSC_VER)
41968 #endif
41969
41970 printf(fmt.c_str(), v);
41971
41972 #if defined(__clang__)
41973 #pragma clang diagnostic pop
41974 #elif defined(__GNUC__) || defined(__GNUG__)
41975 #pragma GCC diagnostic pop
41976 #elif defined(_MSC_VER)
41977 #endif
41978 }
41979
41980 template <typename T>
41981 struct print_impl
41982 {
41983 typedef typename igeneric_function<T>::generic_type generic_type;
41984 typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
41985 typedef typename generic_type::scalar_view scalar_t;
41986 typedef typename generic_type::vector_view vector_t;
41987 typedef typename generic_type::string_view string_t;
41989
41990 static void process(
const std::string& scalar_format, parameter_list_t parameters)
41991 {
41992 for (std::size_t i = 0; i < parameters.size(); ++i)
41993 {
41994 generic_type& gt = parameters[i];
41995
41996 switch (gt.type)
41997 {
41998 case generic_type::e_scalar : print(scalar_format,scalar_t(gt));
41999 break;
42000
42001 case generic_type::e_vector : print(scalar_format,vector_t(gt));
42002 break;
42003
42004 case generic_type::e_string : print(string_t(gt));
42005 break;
42006
42007 default : continue;
42008 }
42009 }
42010 }
42011
42012 static inline void print(const std::string& scalar_format, const scalar_t& s)
42013 {
42015 }
42016
42017 static inline void print(const std::string& scalar_format, const vector_t& v)
42018 {
42019 for (std::size_t i = 0; i < v.size(); ++i)
42020 {
42022
42023 if ((i + 1) < v.size())
42024 printf(" ");
42025 }
42026 }
42027
42028 static inline void print(const string_t& s)
42029 {
42030 printf(
"%s",
to_str(s).c_str());
42031 }
42032 };
42033
42034 }
42035
42036 template <typename T>
42038 {
42039 typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
42040
42042
42043 explicit print(const std::string& scalar_format = "%10.5f")
42044 : scalar_format_(scalar_format)
42045 {
42047 }
42048
42050 {
42051 details::print_impl<T>::process(scalar_format_,parameters);
42052 return T(0);
42053 }
42054
42055 std::string scalar_format_;
42056 };
42057
42058 template <typename T>
42060 {
42061 typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
42062
42064
42065 explicit println(const std::string& scalar_format = "%10.5f")
42066 : scalar_format_(scalar_format)
42067 {
42069 }
42070
42072 {
42073 details::print_impl<T>::process(scalar_format_,parameters);
42074 printf("\n");
42075 return T(0);
42076 }
42077
42078 std::string scalar_format_;
42079 };
42080
42081 template <typename T>
42082 struct package
42083 {
42084 print <T> p;
42085 println<T> pl;
42086
42088 {
42089 #define exprtk_register_function(FunctionName, FunctionType) \
42090 if (!symtab.add_function(FunctionName,FunctionType)) \
42091 { \
42092 exprtk_debug(( \
42093 "exprtk::rtl::io::register_package - Failed to add function: %s\n", \
42094 FunctionName)); \
42095 return false; \
42096 } \
42097
42100 #undef exprtk_register_function
42101
42102 return true;
42103 }
42104 };
42105
42106 }
42107 }
42108}
42109#endif
42110
42111#ifndef exprtk_disable_rtl_io_file
42112#include <fstream>
42114{
42115 namespace rtl { namespace io { namespace file { namespace details
42116 {
42117 using ::exprtk::details::char_ptr;
42118 using ::exprtk::details::char_cptr;
42119
42121 {
42126 };
42127
42128 struct file_descriptor
42129 {
42130 file_descriptor(const std::string& fname, const std::string& access)
42131 : stream_ptr(0)
42132 , mode(get_file_mode(access))
42133 , file_name(fname)
42134 {}
42135
42136 void* stream_ptr;
42138 std::string file_name;
42139
42140 bool open()
42141 {
42142 if (e_read == mode)
42143 {
42144 std::ifstream* stream = new std::ifstream(file_name.c_str(),std::ios::binary);
42145
42146 if (!(*stream))
42147 {
42148 file_name.clear();
42149 delete stream;
42150
42151 return false;
42152 }
42153
42154 stream_ptr = stream;
42155
42156 return true;
42157 }
42158 else if (e_write == mode)
42159 {
42160 std::ofstream* stream = new std::ofstream(file_name.c_str(),std::ios::binary);
42161
42162 if (!(*stream))
42163 {
42164 file_name.clear();
42165 delete stream;
42166
42167 return false;
42168 }
42169
42170 stream_ptr = stream;
42171
42172 return true;
42173 }
42174 else if (e_rdwrt == mode)
42175 {
42176 std::fstream* stream = new std::fstream(file_name.c_str(),std::ios::binary);
42177
42178 if (!(*stream))
42179 {
42180 file_name.clear();
42181 delete stream;
42182
42183 return false;
42184 }
42185
42186 stream_ptr = stream;
42187
42188 return true;
42189 }
42190
42191 return false;
42192 }
42193
42194 template <typename Stream, typename Ptr>
42195 void close(Ptr& p)
42196 {
42197 Stream* stream = reinterpret_cast<Stream*>(p);
42198 stream->close();
42199 delete stream;
42200 p = reinterpret_cast<Ptr>(0);
42201 }
42202
42203 bool close()
42204 {
42205 switch (mode)
42206 {
42207 case e_read : close<std::ifstream>(stream_ptr);
42208 break;
42209
42210 case e_write : close<std::ofstream>(stream_ptr);
42211 break;
42212
42213 case e_rdwrt : close<std::fstream> (stream_ptr);
42214 break;
42215
42216 default : return false;
42217 }
42218
42219 return true;
42220 }
42221
42222 template <typename View>
42223 bool write(const View& view, const std::size_t amount, const std::size_t offset = 0)
42224 {
42225 switch (mode)
42226 {
42227 case e_write :
reinterpret_cast<std::ofstream*
>(stream_ptr)->
42228 write(
reinterpret_cast<char_cptr>(view.begin() + offset), amount *
sizeof(
typename View::value_t));
42229 break;
42230
42231 case e_rdwrt :
reinterpret_cast<std::fstream*
>(stream_ptr)->
42232 write(
reinterpret_cast<char_cptr>(view.begin() + offset) , amount *
sizeof(
typename View::value_t));
42233 break;
42234
42235 default : return false;
42236 }
42237
42238 return true;
42239 }
42240
42241 template <typename View>
42242 bool read(View& view, const std::size_t amount, const std::size_t offset = 0)
42243 {
42244 switch (mode)
42245 {
42246 case e_read :
reinterpret_cast<std::ifstream*
>(stream_ptr)->
42247 read(
reinterpret_cast<char_ptr>(view.begin() + offset), amount *
sizeof(
typename View::value_t));
42248 break;
42249
42250 case e_rdwrt :
reinterpret_cast<std::fstream*
>(stream_ptr)->
42251 read(
reinterpret_cast<char_ptr>(view.begin() + offset) , amount *
sizeof(
typename View::value_t));
42252 break;
42253
42254 default : return false;
42255 }
42256
42257 return true;
42258 }
42259
42260 bool getline(std::string& s)
42261 {
42262 switch (mode)
42263 {
42264 case e_read :
return (!!std::getline(*
reinterpret_cast<std::ifstream*
>(stream_ptr),s));
42265 case e_rdwrt :
return (!!std::getline(*
reinterpret_cast<std::fstream*
>(stream_ptr),s));
42266 default : return false;
42267 }
42268 }
42269
42270 bool eof() const
42271 {
42272 switch (mode)
42273 {
42274 case e_read :
return reinterpret_cast<std::ifstream*
>(stream_ptr)->eof();
42275 case e_write :
return reinterpret_cast<std::ofstream*
>(stream_ptr)->eof();
42276 case e_rdwrt :
return reinterpret_cast<std::fstream*
>(stream_ptr)->eof();
42277 default : return true;
42278 }
42279 }
42280
42281 file_mode get_file_mode(
const std::string& access)
const
42282 {
42283 if (access.empty() || access.size() > 2)
42285
42286 std::size_t w_cnt = 0;
42287 std::size_t r_cnt = 0;
42288
42289 for (std::size_t i = 0; i < access.size(); ++i)
42290 {
42291 switch (std::tolower(access[i]))
42292 {
42293 case 'r' : r_cnt++; break;
42294 case 'w' : w_cnt++; break;
42296 }
42297 }
42298
42299 if ((0 == r_cnt) && (0 == w_cnt))
42301 else if ((r_cnt > 1) || (w_cnt > 1))
42303 else if ((1 == r_cnt) && (1 == w_cnt))
42305 else if (1 == r_cnt)
42307 else
42309 }
42310 };
42311
42312 template <typename T>
42314 {
42315 const std::size_t fd_size = sizeof(details::file_descriptor*);
42316 details::file_descriptor* fd = reinterpret_cast<file_descriptor*>(0);
42317
42318 std::memcpy(
reinterpret_cast<char_ptr >(&fd),
42320 fd_size);
42321 return fd;
42322 }
42323
42324 template <typename T>
42326 {
42327 #ifdef _MSC_VER
42328 #pragma warning(push)
42329 #pragma warning(disable: 4127)
42330 #endif
42331 if (sizeof(T) < sizeof(void*))
42332 {
42333 throw std::runtime_error("exprtk::rtl::io::file - Error - pointer size larger than holder.");
42334 }
42335 #ifdef _MSC_VER
42336 #pragma warning(pop)
42337 #endif
42338 assert(sizeof(T) <= sizeof(void*));
42339 }
42340
42341 }
42342
42343 template <typename T>
42345 {
42346 public:
42347
42349 typedef typename igfun_t::parameter_list_t parameter_list_t;
42350 typedef typename igfun_t::generic_type generic_type;
42351 typedef typename generic_type::string_view string_t;
42352
42353 using igfun_t::operator();
42354
42355 open()
42356 :
exprtk::igeneric_function<T>(
"S|SS")
42357 { details::perform_check<T>(); }
42358
42359 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
42360 {
42361 const std::string file_name =
to_str(string_t(parameters[0]));
42362
42363 if (file_name.empty())
42364 return T(0);
42365
42366 if ((1 == ps_index) && (0 == string_t(parameters[1]).size()))
42367 {
42368 return T(0);
42369 }
42370
42371 const std::string access =
42372 (0 == ps_index) ?
"r" :
to_str(string_t(parameters[1]));
42373
42374 details::file_descriptor* fd = new details::file_descriptor(file_name,access);
42375
42376 if (fd->open())
42377 {
42378 T t = T(0);
42379
42380 const std::size_t fd_size = sizeof(details::file_descriptor*);
42381
42382 std::memcpy(reinterpret_cast<char*>(&t ),
42383 reinterpret_cast<char*>(&fd),
42384 fd_size);
42385 return t;
42386 }
42387 else
42388 {
42389 delete fd;
42390 return T(0);
42391 }
42392 }
42393 };
42394
42395 template <typename T>
42397 {
42399
42400 close()
42401 :
exprtk::ifunction<T>(1)
42402 { details::perform_check<T>(); }
42403
42405 {
42406 details::file_descriptor* fd = details::make_handle(v);
42407
42408 if (!fd->close())
42409 return T(0);
42410
42411 delete fd;
42412
42413 return T(1);
42414 }
42415 };
42416
42417 template <typename T>
42419 {
42420 public:
42421
42423 typedef typename igfun_t::parameter_list_t parameter_list_t;
42424 typedef typename igfun_t::generic_type generic_type;
42425 typedef typename generic_type::string_view string_t;
42426 typedef typename generic_type::scalar_view scalar_t;
42427 typedef typename generic_type::vector_view vector_t;
42428
42429 using igfun_t::operator();
42430
42431 write()
42432 : igfun_t("TS|TST|TV|TVT")
42433 { details::perform_check<T>(); }
42434
42435 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
42436 {
42437 details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
42438
42439 switch (ps_index)
42440 {
42441 case 0 : {
42442 const string_t buffer(parameters[1]);
42443 const std::size_t amount = buffer.size();
42444 return T(fd->write(buffer, amount) ? 1 : 0);
42445 }
42446
42447 case 1 : {
42448 const string_t buffer(parameters[1]);
42449 const std::size_t amount =
42450 std::min(buffer.size(),
42451 static_cast<std::size_t>(scalar_t(parameters[2])()));
42452 return T(fd->write(buffer, amount) ? 1 : 0);
42453 }
42454
42455 case 2 : {
42456 const vector_t vec(parameters[1]);
42457 const std::size_t amount = vec.size();
42458 return T(fd->write(vec, amount) ? 1 : 0);
42459 }
42460
42461 case 3 : {
42462 const vector_t vec(parameters[1]);
42463 const std::size_t amount =
42464 std::min(vec.size(),
42465 static_cast<std::size_t>(scalar_t(parameters[2])()));
42466 return T(fd->write(vec, amount) ? 1 : 0);
42467 }
42468 }
42469
42470 return T(0);
42471 }
42472 };
42473
42474 template <typename T>
42476 {
42477 public:
42478
42480 typedef typename igfun_t::parameter_list_t parameter_list_t;
42481 typedef typename igfun_t::generic_type generic_type;
42482 typedef typename generic_type::string_view string_t;
42483 typedef typename generic_type::scalar_view scalar_t;
42484 typedef typename generic_type::vector_view vector_t;
42485
42486 using igfun_t::operator();
42487
42488 read()
42489 : igfun_t("TS|TST|TV|TVT")
42490 { details::perform_check<T>(); }
42491
42492 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
42493 {
42494 details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
42495
42496 switch (ps_index)
42497 {
42498 case 0 : {
42499 string_t buffer(parameters[1]);
42500 const std::size_t amount = buffer.size();
42501 return T(fd->read(buffer,amount) ? 1 : 0);
42502 }
42503
42504 case 1 : {
42505 string_t buffer(parameters[1]);
42506 const std::size_t amount =
42507 std::min(buffer.size(),
42508 static_cast<std::size_t>(scalar_t(parameters[2])()));
42509 return T(fd->read(buffer,amount) ? 1 : 0);
42510 }
42511
42512 case 2 : {
42513 vector_t vec(parameters[1]);
42514 const std::size_t amount = vec.size();
42515 return T(fd->read(vec,amount) ? 1 : 0);
42516 }
42517
42518 case 3 : {
42519 vector_t vec(parameters[1]);
42520 const std::size_t amount =
42521 std::min(vec.size(),
42522 static_cast<std::size_t>(scalar_t(parameters[2])()));
42523 return T(fd->read(vec,amount) ? 1 : 0);
42524 }
42525 }
42526
42527 return T(0);
42528 }
42529 };
42530
42531 template <typename T>
42533 {
42534 public:
42535
42537 typedef typename igfun_t::parameter_list_t parameter_list_t;
42538 typedef typename igfun_t::generic_type generic_type;
42539 typedef typename generic_type::string_view string_t;
42540 typedef typename generic_type::scalar_view scalar_t;
42541
42542 using igfun_t::operator();
42543
42544 getline()
42545 : igfun_t("T",igfun_t::e_rtrn_string)
42546 { details::perform_check<T>(); }
42547
42548 inline T operator() (std::string& result, parameter_list_t parameters)
exprtk_override
42549 {
42550 details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
42551 return T(fd->getline(result) ? 1 : 0);
42552 }
42553 };
42554
42555 template <typename T>
42557 {
42559
42560 eof()
42561 :
exprtk::ifunction<T>(1)
42562 { details::perform_check<T>(); }
42563
42565 {
42566 details::file_descriptor* fd = details::make_handle(v);
42567
42568 return (fd->eof() ? T(1) : T(0));
42569 }
42570 };
42571
42572 template <typename T>
42573 struct package
42574 {
42575 open <T> o;
42576 close <T> c;
42577 write <T> w;
42578 read <T> r;
42579 getline<T> g;
42581
42583 {
42584 #define exprtk_register_function(FunctionName, FunctionType) \
42585 if (!symtab.add_function(FunctionName,FunctionType)) \
42586 { \
42587 exprtk_debug(( \
42588 "exprtk::rtl::io::file::register_package - Failed to add function: %s\n", \
42589 FunctionName)); \
42590 return false; \
42591 } \
42592
42599 #undef exprtk_register_function
42600
42601 return true;
42602 }
42603 };
42604
42605 }
42606 }
42607 }
42608}
42609#endif
42610
42611#ifndef exprtk_disable_rtl_vecops
42613{
42614 namespace rtl { namespace vecops {
42615
42616 namespace helper
42617 {
42618 template <typename Vector>
42619 inline bool invalid_range(
const Vector& v,
const std::size_t r0,
const std::size_t r1)
42620 {
42621 if (r0 > (v.size() - 1))
42622 return true;
42623 else if (r1 > (v.size() - 1))
42624 return true;
42625 else if (r1 < r0)
42626 return true;
42627 else
42628 return false;
42629 }
42630
42631 template <typename T>
42632 struct load_vector_range
42633 {
42635 typedef typename igfun_t::parameter_list_t parameter_list_t;
42636 typedef typename igfun_t::generic_type generic_type;
42637 typedef typename generic_type::scalar_view scalar_t;
42638 typedef typename generic_type::vector_view vector_t;
42639
42640 static inline bool process(parameter_list_t& parameters,
42641 std::size_t& r0, std::size_t& r1,
42642 const std::size_t& r0_prmidx,
42643 const std::size_t& r1_prmidx,
42644 const std::size_t vec_idx = 0)
42645 {
42646 if (r0_prmidx >= parameters.size())
42647 return false;
42648
42649 if (r1_prmidx >= parameters.size())
42650 return false;
42651
42652 if (!scalar_t(parameters[r0_prmidx]).to_uint(r0))
42653 return false;
42654
42655 if (!scalar_t(parameters[r1_prmidx]).to_uint(r1))
42656 return false;
42657
42658 return !
invalid_range(vector_t(parameters[vec_idx]), r0, r1);
42659 }
42660 };
42661 }
42662
42663 namespace details
42664 {
42665 template <typename T>
42666 inline void kahan_sum(T& sum, T& error,
const T v)
42667 {
42668 const T x = v - error;
42669 const T y = sum + x;
42670 error = (y - sum) - x;
42671 sum = y;
42672 }
42673
42674 }
42675
42676 template <typename T>
42678 {
42679 public:
42680
42682 typedef typename igfun_t::parameter_list_t parameter_list_t;
42683 typedef typename igfun_t::generic_type generic_type;
42684 typedef typename generic_type::vector_view vector_t;
42685
42686 using igfun_t::operator();
42687
42688 all_true()
42689 :
exprtk::igeneric_function<T>(
"V|VTT")
42690
42691
42692
42693
42694
42695 {}
42696
42697 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
42698 {
42699 const vector_t vec(parameters[0]);
42700
42701 std::size_t r0 = 0;
42702 std::size_t r1 = vec.size() - 1;
42703
42704 if (
42705 (1 == ps_index) &&
42706 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
42707 )
42708 {
42709 return std::numeric_limits<T>::quiet_NaN();
42710 }
42711
42712 for (std::size_t i = r0; i <= r1; ++i)
42713 {
42714 if (vec[i] == T(0))
42715 {
42716 return T(0);
42717 }
42718 }
42719
42720 return T(1);
42721 }
42722 };
42723
42724 template <typename T>
42726 {
42727 public:
42728
42730 typedef typename igfun_t::parameter_list_t parameter_list_t;
42731 typedef typename igfun_t::generic_type generic_type;
42732 typedef typename generic_type::vector_view vector_t;
42733
42734 using igfun_t::operator();
42735
42736 all_false()
42737 :
exprtk::igeneric_function<T>(
"V|VTT")
42738
42739
42740
42741
42742
42743 {}
42744
42745 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
42746 {
42747 const vector_t vec(parameters[0]);
42748
42749 std::size_t r0 = 0;
42750 std::size_t r1 = vec.size() - 1;
42751
42752 if (
42753 (1 == ps_index) &&
42754 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
42755 )
42756 {
42757 return std::numeric_limits<T>::quiet_NaN();
42758 }
42759
42760 for (std::size_t i = r0; i <= r1; ++i)
42761 {
42762 if (vec[i] != T(0))
42763 {
42764 return T(0);
42765 }
42766 }
42767
42768 return T(1);
42769 }
42770 };
42771
42772 template <typename T>
42774 {
42775 public:
42776
42778 typedef typename igfun_t::parameter_list_t parameter_list_t;
42779 typedef typename igfun_t::generic_type generic_type;
42780 typedef typename generic_type::vector_view vector_t;
42781
42782 using igfun_t::operator();
42783
42784 any_true()
42785 :
exprtk::igeneric_function<T>(
"V|VTT")
42786
42787
42788
42789
42790
42791 {}
42792
42793 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
42794 {
42795 const vector_t vec(parameters[0]);
42796
42797 std::size_t r0 = 0;
42798 std::size_t r1 = vec.size() - 1;
42799
42800 if (
42801 (1 == ps_index) &&
42802 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
42803 )
42804 {
42805 return std::numeric_limits<T>::quiet_NaN();
42806 }
42807
42808 for (std::size_t i = r0; i <= r1; ++i)
42809 {
42810 if (vec[i] != T(0))
42811 {
42812 return T(1);
42813 }
42814 }
42815
42816 return T(0);
42817 }
42818 };
42819
42820 template <typename T>
42822 {
42823 public:
42824
42826 typedef typename igfun_t::parameter_list_t parameter_list_t;
42827 typedef typename igfun_t::generic_type generic_type;
42828 typedef typename generic_type::vector_view vector_t;
42829
42830 using igfun_t::operator();
42831
42832 any_false()
42833 :
exprtk::igeneric_function<T>(
"V|VTT")
42834
42835
42836
42837
42838
42839 {}
42840
42841 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
42842 {
42843 const vector_t vec(parameters[0]);
42844
42845 std::size_t r0 = 0;
42846 std::size_t r1 = vec.size() - 1;
42847
42848 if (
42849 (1 == ps_index) &&
42850 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
42851 )
42852 {
42853 return std::numeric_limits<T>::quiet_NaN();
42854 }
42855
42856 for (std::size_t i = r0; i <= r1; ++i)
42857 {
42858 if (vec[i] == T(0))
42859 {
42860 return T(1);
42861 }
42862 }
42863
42864 return T(0);
42865 }
42866 };
42867
42868 template <typename T>
42870 {
42871 public:
42872
42874 typedef typename igfun_t::parameter_list_t parameter_list_t;
42875 typedef typename igfun_t::generic_type generic_type;
42876 typedef typename generic_type::vector_view vector_t;
42877
42878 using igfun_t::operator();
42879
42880 count()
42881 :
exprtk::igeneric_function<T>(
"V|VTT")
42882
42883
42884
42885
42886
42887 {}
42888
42889 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
42890 {
42891 const vector_t vec(parameters[0]);
42892
42893 std::size_t r0 = 0;
42894 std::size_t r1 = vec.size() - 1;
42895
42896 if (
42897 (1 == ps_index) &&
42898 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
42899 )
42900 {
42901 return std::numeric_limits<T>::quiet_NaN();
42902 }
42903
42904 std::size_t cnt = 0;
42905
42906 for (std::size_t i = r0; i <= r1; ++i)
42907 {
42908 if (vec[i] != T(0)) ++cnt;
42909 }
42910
42911 return T(cnt);
42912 }
42913 };
42914
42915 template <typename T>
42917 {
42918 public:
42919
42921 typedef typename igfun_t::parameter_list_t parameter_list_t;
42922 typedef typename igfun_t::generic_type generic_type;
42923 typedef typename generic_type::scalar_view scalar_t;
42924 typedef typename generic_type::vector_view vector_t;
42925
42926 using igfun_t::operator();
42927
42928 copy()
42929 :
exprtk::igeneric_function<T>(
"VV|VTTVTT")
42930
42931
42932
42933
42934
42935 {}
42936
42937 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
42938 {
42939 const vector_t x(parameters[0]);
42940 vector_t y(parameters[(0 == ps_index) ? 1 : 3]);
42941
42942 std::size_t xr0 = 0;
42943 std::size_t xr1 = x.size() - 1;
42944
42945 std::size_t yr0 = 0;
42946 std::size_t yr1 = y.size() - 1;
42947
42948 if (1 == ps_index)
42949 {
42950 if (
42951 !helper::load_vector_range<T>::process(parameters, xr0, xr1, 1, 2, 0) ||
42952 !helper::load_vector_range<T>::process(parameters, yr0, yr1, 4, 5, 3)
42953 )
42954 return T(0);
42955 }
42956
42957 const std::size_t n = std::min(xr1 - xr0 + 1, yr1 - yr0 + 1);
42958
42959 std::copy(
42960 x.begin() + xr0,
42961 x.begin() + xr0 + n,
42962 y.begin() + yr0);
42963
42964 return T(n);
42965 }
42966 };
42967
42968 template <typename T>
42970 {
42971 public:
42972
42974 typedef typename igfun_t::parameter_list_t parameter_list_t;
42975 typedef typename igfun_t::generic_type generic_type;
42976 typedef typename generic_type::scalar_view scalar_t;
42977 typedef typename generic_type::vector_view vector_t;
42978
42979 using igfun_t::operator();
42980
42981 rol()
42982 :
exprtk::igeneric_function<T>(
"VT|VTTT")
42983
42984
42985
42986
42987
42988 {}
42989
42990 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
42991 {
42992 vector_t vec(parameters[0]);
42993
42994 std::size_t n = 0;
42995 std::size_t r0 = 0;
42996 std::size_t r1 = vec.size() - 1;
42997
42998 if (!scalar_t(parameters[1]).to_uint(n))
42999 return T(0);
43000
43001 if (
43002 (1 == ps_index) &&
43003 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
43004 )
43005 return T(0);
43006
43007 const std::size_t dist = r1 - r0 + 1;
43008 const std::size_t shift = n % dist;
43009
43010 std::rotate(
43011 vec.begin() + r0,
43012 vec.begin() + r0 + shift,
43013 vec.begin() + r1 + 1);
43014
43015 return T(1);
43016 }
43017 };
43018
43019 template <typename T>
43021 {
43022 public:
43023
43025 typedef typename igfun_t::parameter_list_t parameter_list_t;
43026 typedef typename igfun_t::generic_type generic_type;
43027 typedef typename generic_type::scalar_view scalar_t;
43028 typedef typename generic_type::vector_view vector_t;
43029
43030 using igfun_t::operator();
43031
43032 ror()
43033 :
exprtk::igeneric_function<T>(
"VT|VTTT")
43034
43035
43036
43037
43038
43039 {}
43040
43041 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43042 {
43043 vector_t vec(parameters[0]);
43044
43045 std::size_t n = 0;
43046 std::size_t r0 = 0;
43047 std::size_t r1 = vec.size() - 1;
43048
43049 if (!scalar_t(parameters[1]).to_uint(n))
43050 return T(0);
43051
43052 if (
43053 (1 == ps_index) &&
43054 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
43055 )
43056 return T(0);
43057
43058 const std::size_t dist = r1 - r0 + 1;
43059 const std::size_t shift = (dist - (n % dist)) % dist;
43060
43061 std::rotate(
43062 vec.begin() + r0,
43063 vec.begin() + r0 + shift,
43064 vec.begin() + r1 + 1);
43065
43066 return T(1);
43067 }
43068 };
43069
43070 template <typename T>
43072 {
43073 public:
43074
43076 typedef typename igfun_t::parameter_list_t parameter_list_t;
43077 typedef typename igfun_t::generic_type generic_type;
43078 typedef typename generic_type::scalar_view scalar_t;
43079 typedef typename generic_type::vector_view vector_t;
43080
43081 using igfun_t::operator();
43082
43083 shift_left()
43084 :
exprtk::igeneric_function<T>(
"VT|VTTT")
43085
43086
43087
43088
43089
43090 {}
43091
43092 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43093 {
43094 vector_t vec(parameters[0]);
43095
43096 std::size_t n = 0;
43097 std::size_t r0 = 0;
43098 std::size_t r1 = vec.size() - 1;
43099
43100 if (!scalar_t(parameters[1]).to_uint(n))
43101 return T(0);
43102
43103 if (
43104 (1 == ps_index) &&
43105 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
43106 )
43107 return T(0);
43108
43109 const std::size_t dist = r1 - r0 + 1;
43110
43111 if (n > dist)
43112 return T(0);
43113
43114 std::rotate(
43115 vec.begin() + r0,
43116 vec.begin() + r0 + n,
43117 vec.begin() + r1 + 1);
43118
43119 for (std::size_t i = r1 - n + 1; i <= r1; ++i)
43120 {
43121 vec[i] = T(0);
43122 }
43123
43124 return T(1);
43125 }
43126 };
43127
43128 template <typename T>
43130 {
43131 public:
43132
43134 typedef typename igfun_t::parameter_list_t parameter_list_t;
43135 typedef typename igfun_t::generic_type generic_type;
43136 typedef typename generic_type::scalar_view scalar_t;
43137 typedef typename generic_type::vector_view vector_t;
43138
43139 using igfun_t::operator();
43140
43141 shift_right()
43142 :
exprtk::igeneric_function<T>(
"VT|VTTT")
43143
43144
43145
43146
43147
43148 {}
43149
43150 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43151 {
43152 vector_t vec(parameters[0]);
43153
43154 std::size_t n = 0;
43155 std::size_t r0 = 0;
43156 std::size_t r1 = vec.size() - 1;
43157
43158 if (!scalar_t(parameters[1]).to_uint(n))
43159 return T(0);
43160
43161 if (
43162 (1 == ps_index) &&
43163 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
43164 )
43165 return T(0);
43166
43167 const std::size_t dist = r1 - r0 + 1;
43168
43169 if (n > dist)
43170 return T(0);
43171
43172 const std::size_t shift = (dist - (n % dist)) % dist;
43173
43174 std::rotate(
43175 vec.begin() + r0,
43176 vec.begin() + r0 + shift,
43177 vec.begin() + r1 + 1);
43178
43179 for (std::size_t i = r0; i < r0 + n; ++i)
43180 {
43181 vec[i] = T(0);
43182 }
43183
43184 return T(1);
43185 }
43186 };
43187
43188 template <typename T>
43190 {
43191 public:
43192
43194 typedef typename igfun_t::parameter_list_t parameter_list_t;
43195 typedef typename igfun_t::generic_type generic_type;
43196 typedef typename generic_type::string_view string_t;
43197 typedef typename generic_type::vector_view vector_t;
43198
43199 using igfun_t::operator();
43200
43201 sort()
43202 :
exprtk::igeneric_function<T>(
"V|VTT|VS|VSTT")
43203
43204
43205
43206
43207
43208
43209
43210 {}
43211
43212 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43213 {
43214 vector_t vec(parameters[0]);
43215
43216 std::size_t r0 = 0;
43217 std::size_t r1 = vec.size() - 1;
43218
43219 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0))
43220 return T(0);
43221 if ((3 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
43222 return T(0);
43223
43224 bool ascending = true;
43225
43226 if ((2 == ps_index) || (3 == ps_index))
43227 {
43229 ascending = true;
43231 ascending = false;
43232 else
43233 return T(0);
43234 }
43235
43236 if (ascending)
43237 std::sort(
43238 vec.begin() + r0,
43239 vec.begin() + r1 + 1,
43240 std::less<T>());
43241 else
43242 std::sort(
43243 vec.begin() + r0,
43244 vec.begin() + r1 + 1,
43245 std::greater<T>());
43246
43247 return T(1);
43248 }
43249 };
43250
43251 template <typename T>
43253 {
43254 public:
43255
43257 typedef typename igfun_t::parameter_list_t parameter_list_t;
43258 typedef typename igfun_t::generic_type generic_type;
43259 typedef typename generic_type::scalar_view scalar_t;
43260 typedef typename generic_type::vector_view vector_t;
43261
43262 using igfun_t::operator();
43263
43264 nthelement()
43265 :
exprtk::igeneric_function<T>(
"VT|VTTT")
43266
43267
43268
43269
43270
43271 {}
43272
43273 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43274 {
43275 vector_t vec(parameters[0]);
43276
43277 std::size_t n = 0;
43278 std::size_t r0 = 0;
43279 std::size_t r1 = vec.size() - 1;
43280
43281 if (!scalar_t(parameters[1]).to_uint(n))
43282 return T(0);
43283
43284 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
43285 {
43286 return std::numeric_limits<T>::quiet_NaN();
43287 }
43288
43289 std::nth_element(
43290 vec.begin() + r0,
43291 vec.begin() + r0 + n ,
43292 vec.begin() + r1 + 1);
43293
43294 return T(1);
43295 }
43296 };
43297
43298 template <typename T>
43300 {
43301 public:
43302
43304 typedef typename igfun_t::parameter_list_t parameter_list_t;
43305 typedef typename igfun_t::generic_type generic_type;
43306 typedef typename generic_type::scalar_view scalar_t;
43307 typedef typename generic_type::vector_view vector_t;
43308
43309 using igfun_t::operator();
43310
43311 assign()
43312 :
exprtk::igeneric_function<T>(
"VT|VTTT|VTTTT")
43313
43314
43315
43316
43317
43318
43319 {}
43320
43321 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43322 {
43323 vector_t vec(parameters[0]);
43324
43325 const T assign_value = scalar_t(parameters[1]);
43326
43327 const T step_size = (2 == ps_index) ?
43328 scalar_t(parameters.back())() :
43329 T(1) ;
43330
43331 std::size_t r0 = 0;
43332 std::size_t r1 = vec.size() - 1;
43333
43334 if (
43335 ((ps_index == 1) || (ps_index == 2)) &&
43336 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
43337 )
43338 {
43339 return T(0);
43340 }
43341
43342 for (std::size_t i = r0; i <= r1; i += step_size)
43343 {
43344 vec[i] = assign_value;
43345 }
43346
43347 return T(1);
43348 }
43349 };
43350
43351 template <typename T>
43353 {
43354 public:
43355
43357 typedef typename igfun_t::parameter_list_t parameter_list_t;
43358 typedef typename igfun_t::generic_type generic_type;
43359 typedef typename generic_type::scalar_view scalar_t;
43360 typedef typename generic_type::vector_view vector_t;
43361
43362 using igfun_t::operator();
43363
43364 iota()
43365 :
exprtk::igeneric_function<T>(
"VTT|VT|VTTTT|VTTT")
43366
43367
43368
43369
43370
43371
43372
43373
43374
43375
43376
43377 {}
43378
43379 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43380 {
43381 vector_t vec(parameters[0]);
43382
43383 const T start_value = (ps_index <= 1) ?
43384 scalar_t(parameters[1]) :
43385 scalar_t(parameters[3]) ;
43386
43387 const T step_size = ((0 == ps_index) || (2 == ps_index)) ?
43388 scalar_t(parameters.back())() :
43389 T(1) ;
43390
43391 std::size_t r0 = 0;
43392 std::size_t r1 = vec.size() - 1;
43393
43394 if (
43395 ((ps_index == 2) || (ps_index == 3)) &&
43396 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
43397 )
43398 {
43399 return T(0);
43400 }
43401
43402 for (std::size_t i = r0; i <= r1; ++i)
43403 {
43404 vec[i] = start_value + ((i - r0) * step_size);
43405 }
43406
43407 return T(1);
43408 }
43409 };
43410
43411 template <typename T>
43413 {
43414 public:
43415
43417 typedef typename igfun_t::parameter_list_t parameter_list_t;
43418 typedef typename igfun_t::generic_type generic_type;
43419 typedef typename generic_type::scalar_view scalar_t;
43420 typedef typename generic_type::vector_view vector_t;
43421
43422 using igfun_t::operator();
43423
43424 sumk()
43425 :
exprtk::igeneric_function<T>(
"V|VTT|VTTT")
43426
43427
43428
43429
43430
43431
43432 {}
43433
43434 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43435 {
43436 const vector_t vec(parameters[0]);
43437
43438 const std::size_t stride = (2 != ps_index) ?
43439 1 :
43440 static_cast<
std::size_t>(scalar_t(parameters[3]));
43441
43442 std::size_t r0 = 0;
43443 std::size_t r1 = vec.size() - 1;
43444
43445 if (
43446 ((1 == ps_index) || (2 == ps_index)) &&
43447 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
43448 )
43449 {
43450 return std::numeric_limits<T>::quiet_NaN();
43451 }
43452
43453 T result = T(0);
43454 T error = T(0);
43455
43456 for (std::size_t i = r0; i <= r1; i += stride)
43457 {
43458 details::kahan_sum(result, error, vec[i]);
43459 }
43460
43461 return result;
43462 }
43463 };
43464
43465 template <typename T>
43467 {
43468 public:
43469
43471 typedef typename igfun_t::parameter_list_t parameter_list_t;
43472 typedef typename igfun_t::generic_type generic_type;
43473 typedef typename generic_type::scalar_view scalar_t;
43474 typedef typename generic_type::vector_view vector_t;
43475
43476 using igfun_t::operator();
43477
43478 axpy()
43479 :
exprtk::igeneric_function<T>(
"TVV|TVVTT")
43480
43481
43482
43483
43484
43485
43486 {}
43487
43488 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43489 {
43490 const vector_t x(parameters[1]);
43491 vector_t y(parameters[2]);
43492
43493 std::size_t r0 = 0;
43494 std::size_t r1 = std::min(x.size(),y.size()) - 1;
43495
43496 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 1))
43497 return std::numeric_limits<T>::quiet_NaN();
43498 else if (helper::invalid_range(y, r0, r1))
43499 return std::numeric_limits<T>::quiet_NaN();
43500
43501 const T a = scalar_t(parameters[0])();
43502
43503 for (std::size_t i = r0; i <= r1; ++i)
43504 {
43505 y[i] = (a * x[i]) + y[i];
43506 }
43507
43508 return T(1);
43509 }
43510 };
43511
43512 template <typename T>
43514 {
43515 public:
43516
43518 typedef typename igfun_t::parameter_list_t parameter_list_t;
43519 typedef typename igfun_t::generic_type generic_type;
43520 typedef typename generic_type::scalar_view scalar_t;
43521 typedef typename generic_type::vector_view vector_t;
43522
43523 using igfun_t::operator();
43524
43525 axpby()
43526 :
exprtk::igeneric_function<T>(
"TVTV|TVTVTT")
43527
43528
43529
43530
43531
43532
43533 {}
43534
43535 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43536 {
43537 const vector_t x(parameters[1]);
43538 vector_t y(parameters[3]);
43539
43540 std::size_t r0 = 0;
43541 std::size_t r1 = std::min(x.size(),y.size()) - 1;
43542
43543 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
43544 return std::numeric_limits<T>::quiet_NaN();
43545 else if (helper::invalid_range(y, r0, r1))
43546 return std::numeric_limits<T>::quiet_NaN();
43547
43548 const T a = scalar_t(parameters[0])();
43549 const T b = scalar_t(parameters[2])();
43550
43551 for (std::size_t i = r0; i <= r1; ++i)
43552 {
43553 y[i] = (a * x[i]) + (b * y[i]);
43554 }
43555
43556 return T(1);
43557 }
43558 };
43559
43560 template <typename T>
43562 {
43563 public:
43564
43566 typedef typename igfun_t::parameter_list_t parameter_list_t;
43567 typedef typename igfun_t::generic_type generic_type;
43568 typedef typename generic_type::scalar_view scalar_t;
43569 typedef typename generic_type::vector_view vector_t;
43570
43571 using igfun_t::operator();
43572
43573 axpyz()
43574 :
exprtk::igeneric_function<T>(
"TVVV|TVVVTT")
43575
43576
43577
43578
43579
43580
43581 {}
43582
43583 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43584 {
43585 const vector_t x(parameters[1]);
43586 const vector_t y(parameters[2]);
43587 vector_t z(parameters[3]);
43588
43589 std::size_t r0 = 0;
43590 std::size_t r1 = std::min(x.size(),y.size()) - 1;
43591
43592 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
43593 return std::numeric_limits<T>::quiet_NaN();
43594 else if (helper::invalid_range(y, r0, r1))
43595 return std::numeric_limits<T>::quiet_NaN();
43596 else if (helper::invalid_range(z, r0, r1))
43597 return std::numeric_limits<T>::quiet_NaN();
43598
43599 const T a = scalar_t(parameters[0])();
43600
43601 for (std::size_t i = r0; i <= r1; ++i)
43602 {
43603 z[i] = (a * x[i]) + y[i];
43604 }
43605
43606 return T(1);
43607 }
43608 };
43609
43610 template <typename T>
43612 {
43613 public:
43614
43616 typedef typename igfun_t::parameter_list_t parameter_list_t;
43617 typedef typename igfun_t::generic_type generic_type;
43618 typedef typename generic_type::scalar_view scalar_t;
43619 typedef typename generic_type::vector_view vector_t;
43620
43621 using igfun_t::operator();
43622
43623 axpbyz()
43624 :
exprtk::igeneric_function<T>(
"TVTVV|TVTVVTT")
43625
43626
43627
43628
43629
43630
43631 {}
43632
43633 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43634 {
43635 const vector_t x(parameters[1]);
43636 const vector_t y(parameters[3]);
43637 vector_t z(parameters[4]);
43638
43639 std::size_t r0 = 0;
43640 std::size_t r1 = std::min(x.size(),y.size()) - 1;
43641
43642 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
43643 return std::numeric_limits<T>::quiet_NaN();
43644 else if (helper::invalid_range(y, r0, r1))
43645 return std::numeric_limits<T>::quiet_NaN();
43646 else if (helper::invalid_range(z, r0, r1))
43647 return std::numeric_limits<T>::quiet_NaN();
43648
43649 const T a = scalar_t(parameters[0])();
43650 const T b = scalar_t(parameters[2])();
43651
43652 for (std::size_t i = r0; i <= r1; ++i)
43653 {
43654 z[i] = (a * x[i]) + (b * y[i]);
43655 }
43656
43657 return T(1);
43658 }
43659 };
43660
43661 template <typename T>
43663 {
43664 public:
43665
43667 typedef typename igfun_t::parameter_list_t parameter_list_t;
43668 typedef typename igfun_t::generic_type generic_type;
43669 typedef typename generic_type::scalar_view scalar_t;
43670 typedef typename generic_type::vector_view vector_t;
43671
43672 using igfun_t::operator();
43673
43674 axpbsy()
43675 :
exprtk::igeneric_function<T>(
"TVTTV|TVTTVTT")
43676
43677
43678
43679
43680
43681
43682 {}
43683
43684 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43685 {
43686 const vector_t x(parameters[1]);
43687 vector_t y(parameters[4]);
43688
43689 std::size_t r0 = 0;
43690 std::size_t r1 = std::min(x.size(),y.size()) - 1;
43691
43692 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
43693 return std::numeric_limits<T>::quiet_NaN();
43694 else if (helper::invalid_range(y, r0, r1))
43695 return std::numeric_limits<T>::quiet_NaN();
43696
43697 const T a = scalar_t(parameters[0])();
43698 const T b = scalar_t(parameters[2])();
43699
43700 const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
43701
43702 for (std::size_t i = r0; i <= r1; ++i)
43703 {
43704 y[i] = (a * x[i]) + (b * y[i + s]);
43705 }
43706
43707 return T(1);
43708 }
43709 };
43710
43711 template <typename T>
43713 {
43714 public:
43715
43717 typedef typename igfun_t::parameter_list_t parameter_list_t;
43718 typedef typename igfun_t::generic_type generic_type;
43719 typedef typename generic_type::scalar_view scalar_t;
43720 typedef typename generic_type::vector_view vector_t;
43721
43722 using igfun_t::operator();
43723
43724 axpbsyz()
43725 :
exprtk::igeneric_function<T>(
"TVTTVV|TVTTVVTT")
43726
43727
43728
43729
43730
43731
43732 {}
43733
43734 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43735 {
43736 const vector_t x(parameters[1]);
43737 const vector_t y(parameters[4]);
43738 vector_t z(parameters[5]);
43739
43740 std::size_t r0 = 0;
43741 std::size_t r1 = std::min(x.size(),y.size()) - 1;
43742
43743 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 6, 7, 1))
43744 return std::numeric_limits<T>::quiet_NaN();
43745 else if (helper::invalid_range(y, r0, r1))
43746 return std::numeric_limits<T>::quiet_NaN();
43747 else if (helper::invalid_range(z, r0, r1))
43748 return std::numeric_limits<T>::quiet_NaN();
43749
43750 const T a = scalar_t(parameters[0])();
43751 const T b = scalar_t(parameters[2])();
43752
43753 const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
43754
43755 for (std::size_t i = r0; i <= r1; ++i)
43756 {
43757 z[i] = (a * x[i]) + (b * y[i + s]);
43758 }
43759
43760 return T(1);
43761 }
43762 };
43763
43764 template <typename T>
43766 {
43767 public:
43768
43770 typedef typename igfun_t::parameter_list_t parameter_list_t;
43771 typedef typename igfun_t::generic_type generic_type;
43772 typedef typename generic_type::scalar_view scalar_t;
43773 typedef typename generic_type::vector_view vector_t;
43774
43775 using igfun_t::operator();
43776
43777 axpbz()
43778 :
exprtk::igeneric_function<T>(
"TVTV|TVTVTT")
43779
43780
43781
43782
43783
43784
43785 {}
43786
43787 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43788 {
43789 const vector_t x(parameters[1]);
43790 vector_t z(parameters[3]);
43791
43792 std::size_t r0 = 0;
43793 std::size_t r1 = x.size() - 1;
43794
43795 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
43796 return std::numeric_limits<T>::quiet_NaN();
43797 else if (helper::invalid_range(z, r0, r1))
43798 return std::numeric_limits<T>::quiet_NaN();
43799
43800 const T a = scalar_t(parameters[0])();
43801 const T b = scalar_t(parameters[2])();
43802
43803 for (std::size_t i = r0; i <= r1; ++i)
43804 {
43805 z[i] = (a * x[i]) + b;
43806 }
43807
43808 return T(1);
43809 }
43810 };
43811
43812 template <typename T>
43814 {
43815 public:
43816
43818 typedef typename igfun_t::parameter_list_t parameter_list_t;
43819 typedef typename igfun_t::generic_type generic_type;
43820 typedef typename generic_type::scalar_view scalar_t;
43821 typedef typename generic_type::vector_view vector_t;
43822
43823 using igfun_t::operator();
43824
43825 diff()
43826 :
exprtk::igeneric_function<T>(
"VV|VVT")
43827
43828
43829
43830
43831
43832
43833 {}
43834
43835 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43836 {
43837 const vector_t x(parameters[0]);
43838 vector_t y(parameters[1]);
43839
43840 const std::size_t r0 = 0;
43841 const std::size_t r1 = std::min(x.size(),y.size()) - 1;
43842
43843 const std::size_t stride = (1 != ps_index) ? 1 :
43844 std::
min(r1,static_cast<
std::size_t>(scalar_t(parameters[2])));
43845
43846 for (std::size_t i = 0; i < stride; ++i)
43847 {
43848 y[i] = std::numeric_limits<T>::quiet_NaN();
43849 }
43850
43851 for (std::size_t i = (r0 + stride); i <= r1; ++i)
43852 {
43853 y[i] = x[i] - x[i - stride];
43854 }
43855
43856 return T(1);
43857 }
43858 };
43859
43860 template <typename T>
43862 {
43863 public:
43864
43866 typedef typename igfun_t::parameter_list_t parameter_list_t;
43867 typedef typename igfun_t::generic_type generic_type;
43868 typedef typename generic_type::scalar_view scalar_t;
43869 typedef typename generic_type::vector_view vector_t;
43870
43871 using igfun_t::operator();
43872
43873 dot()
43874 :
exprtk::igeneric_function<T>(
"VV|VVTT")
43875
43876
43877
43878
43879
43880 {}
43881
43882 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43883 {
43884 const vector_t x(parameters[0]);
43885 const vector_t y(parameters[1]);
43886
43887 std::size_t r0 = 0;
43888 std::size_t r1 = std::min(x.size(),y.size()) - 1;
43889
43890 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
43891 return std::numeric_limits<T>::quiet_NaN();
43892 else if (helper::invalid_range(y, r0, r1))
43893 return std::numeric_limits<T>::quiet_NaN();
43894
43895 T result = T(0);
43896
43897 for (std::size_t i = r0; i <= r1; ++i)
43898 {
43899 result += (x[i] * y[i]);
43900 }
43901
43902 return result;
43903 }
43904 };
43905
43906 template <typename T>
43908 {
43909 public:
43910
43912 typedef typename igfun_t::parameter_list_t parameter_list_t;
43913 typedef typename igfun_t::generic_type generic_type;
43914 typedef typename generic_type::scalar_view scalar_t;
43915 typedef typename generic_type::vector_view vector_t;
43916
43917 using igfun_t::operator();
43918
43919 dotk()
43920 :
exprtk::igeneric_function<T>(
"VV|VVTT")
43921
43922
43923
43924
43925
43926 {}
43927
43928 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43929 {
43930 const vector_t x(parameters[0]);
43931 const vector_t y(parameters[1]);
43932
43933 std::size_t r0 = 0;
43934 std::size_t r1 = std::min(x.size(),y.size()) - 1;
43935
43936 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
43937 return std::numeric_limits<T>::quiet_NaN();
43938 else if (helper::invalid_range(y, r0, r1))
43939 return std::numeric_limits<T>::quiet_NaN();
43940
43941 T result = T(0);
43942 T error = T(0);
43943
43944 for (std::size_t i = r0; i <= r1; ++i)
43945 {
43946 details::kahan_sum(result, error, (x[i] * y[i]));
43947 }
43948
43949 return result;
43950 }
43951 };
43952
43953 template <typename T>
43955 {
43956 public:
43957
43959 typedef typename igfun_t::parameter_list_t parameter_list_t;
43960 typedef typename igfun_t::generic_type generic_type;
43961 typedef typename generic_type::scalar_view scalar_t;
43962 typedef typename generic_type::vector_view vector_t;
43963
43964 using igfun_t::operator();
43965
43966 threshold_below()
43967 :
exprtk::igeneric_function<T>(
"VTT|VTTTT")
43968
43969
43970
43971
43972
43973
43974
43975
43976
43977 {}
43978
43979 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
43980 {
43981 vector_t vec(parameters[0]);
43982
43983 const T threshold_value = (0 == ps_index) ?
43984 scalar_t(parameters[1]) :
43985 scalar_t(parameters[3]) ;
43986
43987 const T snap_value = scalar_t(parameters.back());
43988
43989 std::size_t r0 = 0;
43990 std::size_t r1 = vec.size() - 1;
43991
43992 if (
43993 (1 == ps_index) &&
43994 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
43995 )
43996 {
43997 return T(0);
43998 }
43999
44000 for (std::size_t i = r0; i <= r1; ++i)
44001 {
44002 if (vec[i] < threshold_value)
44003 {
44004 vec[i] = snap_value;
44005 }
44006 }
44007
44008 return T(1);
44009 }
44010 };
44011
44012 template <typename T>
44014 {
44015 public:
44016
44018 typedef typename igfun_t::parameter_list_t parameter_list_t;
44019 typedef typename igfun_t::generic_type generic_type;
44020 typedef typename generic_type::scalar_view scalar_t;
44021 typedef typename generic_type::vector_view vector_t;
44022
44023 using igfun_t::operator();
44024
44025 threshold_above()
44026 :
exprtk::igeneric_function<T>(
"VTT|VTTTT")
44027
44028
44029
44030
44031
44032
44033
44034
44035
44036 {}
44037
44038 inline T operator() (
const std::size_t& ps_index, parameter_list_t parameters)
exprtk_override
44039 {
44040 vector_t vec(parameters[0]);
44041
44042 const T threshold_value = (0 == ps_index) ?
44043 scalar_t(parameters[1]) :
44044 scalar_t(parameters[3]) ;
44045
44046 const T snap_value = scalar_t(parameters.back());
44047
44048 std::size_t r0 = 0;
44049 std::size_t r1 = vec.size() - 1;
44050
44051 if (
44052 (1 == ps_index) &&
44053 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44054 )
44055 {
44056 return T(0);
44057 }
44058
44059 for (std::size_t i = r0; i <= r1; ++i)
44060 {
44061 if (vec[i] > threshold_value)
44062 {
44063 vec[i] = snap_value;
44064 }
44065 }
44066
44067 return T(1);
44068 }
44069 };
44070
44071 template <typename T>
44072 struct package
44073 {
44074 all_true <T> at;
44075 all_false <T> af;
44076 any_true <T> nt;
44077 any_false <T> nf;
44078 count <T> c;
44079 copy <T> cp;
44080 rol <T> rl;
44081 ror <T> rr;
44082 shift_left <T> sl;
44083 shift_right <T> sr;
44084 sort <T> st;
44085 nthelement <T> ne;
44086 assign <T> an;
44087 iota <T> ia;
44088 sumk <T> sk;
44089 axpy <T> b1_axpy;
44090 axpby <T> b1_axpby;
44091 axpyz <T> b1_axpyz;
44092 axpbyz <T> b1_axpbyz;
44093 axpbsy <T> b1_axpbsy;
44094 axpbsyz <T> b1_axpbsyz;
44095 axpbz <T> b1_axpbz;
44096 diff <T> df;
44097 dot <T> dt;
44098 dotk <T> dtk;
44099 threshold_above<T> ta;
44100 threshold_below<T> tb;
44101
44103 {
44104 #define exprtk_register_function(FunctionName, FunctionType) \
44105 if (!symtab.add_function(FunctionName,FunctionType)) \
44106 { \
44107 exprtk_debug(( \
44108 "exprtk::rtl::vecops::register_package - Failed to add function: %s\n", \
44109 FunctionName)); \
44110 return false; \
44111 } \
44112
44142 #undef exprtk_register_function
44143
44144 return true;
44145 }
44146 };
44147
44148 }
44149 }
44150}
44151#endif
44152
44154{
44155 namespace information
44156 {
44157 using ::exprtk::details::char_cptr;
44158
44161 "49775724709369995957496696762772407"
44162 "66303535475945713821785251664274274"
44163 "66391932003059921817413596629043572";
44166
44167 static inline std::string
data()
44168 {
44169 static const std::string info_str = std::string(library) +
44170 std::string(" v") + std::string(version) +
44171 std::string(
" (") +
date + std::string(
")") +
44172 std::string(
" (") +
min_cpp + std::string(
")");
44173 return info_str;
44174 }
44175
44176 }
44177
44178 #ifdef exprtk_debug
44179 #undef exprtk_debug
44180 #endif
44181
44182 #ifdef exprtk_error_location
44183 #undef exprtk_error_location
44184 #endif
44185
44186 #ifdef exprtk_override
44187 #undef exprtk_override
44188 #endif
44189
44190 #ifdef exprtk_final
44191 #undef exprtk_final
44192 #endif
44193
44194 #ifdef exprtk_delete
44195 #undef exprtk_delete
44196 #endif
44197
44198}
44199
44200#endif
#define basic_opr_switch_statements
#define register_binary_op(Op, BinaryFunctor)
#define exprtk_register_function(FunctionName, FunctionType)
#define register_unary_op(Op, UnaryFunctor)
#define register_sf4ext(Op)
#define extended_opr_switch_statements
#define exprtk_debug(params)
#define exprtk_error_location
#define string_opr_switch_statements
#define exprtk_assign(Index)
#define register_sf3_extid(Id, Op)
complex_t min(const complex_t v0, const complex_t v1)
complex_t max(const complex_t v0, const complex_t v1)
T process(const operator_type operation, const T arg)
bool imatch(const char_t c1, const char_t c2)
T value(details::expression_node< T > *n)
std::string to_str(int i)
void free_node(NodeAllocator &, expression_node< T > *&node)
void free_all_nodes(NodeAllocator &node_allocator, expression_node< T > *(&b)[N])
bool is_neg_unary_node(const expression_node< T > *node)
void print_type(const std::string &fmt, const T v, exprtk::details::numeric::details::real_type_tag)
file_descriptor * make_handle(T v)
void kahan_sum(T &sum, T &error, const T v)
bool invalid_range(const Vector &v, const std::size_t r0, const std::size_t r1)
void enable_zero_parameters(FunctionType &func)
bool collect_variables(const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
vector_access_runtime_check * vector_access_runtime_check_ptr
void disable_has_side_effects(FunctionType &func)
compilation_check * compilation_check_ptr
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)