1 #ifndef _RHEOLEF_FIELD_EXPR_RECURSIVE_H
2 #define _RHEOLEF_FIELD_EXPR_RECURSIVE_H
47 #include "rheolef/field_expr_terminal.h"
58 template<
class UnaryFunction,
class Expr>
82 std::is_same<UnaryFunction,details::unary_plus>
83 ,std::is_same<UnaryFunction,details::negate>
84 ,std::is_same<UnaryFunction,details::binder_first <details::plus, scalar_type>>
85 ,std::is_same<UnaryFunction,details::binder_second<details::plus, scalar_type>>
86 ,std::is_same<UnaryFunction,details::binder_first <details::minus, scalar_type>>
87 ,std::is_same<UnaryFunction,details::binder_second<details::minus, scalar_type>>
88 ,std::is_same<UnaryFunction,details::binder_first <details::multiplies,scalar_type>>
89 ,std::is_same<UnaryFunction,details::binder_second<details::multiplies,scalar_type>>
90 ,std::is_same<UnaryFunction,details::binder_second<details::divides, scalar_type>>
96 return is_affine_homogeneous::value
97 &&
_expr.have_homogeneous_space (Vh);
111 const UnaryFunction
_f;
133 {
_expr.initialize (pops, iopt); }
139 {
_expr.initialize (Xh, pops, iopt); }
144 template<
class Result,
class Arg,
class Status>
151 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
153 fatal_macro (
"invalid type resolution: Result="<<typename_macro(Result)
154 <<
", Arg="<<typename_macro(Arg)
155 <<
", UnaryFunction="<<typename_macro(UnaryFunction));
163 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
165 fatal_macro (
"invalid type resolution: Result="<<typename_macro(Result)
166 <<
", Arg="<<typename_macro(Arg)
167 <<
", UnaryFunction="<<typename_macro(UnaryFunction));
170 template<
class Result,
class Arg>
178 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
180 Eigen::Matrix<Arg,Eigen::Dynamic,1> value1;
181 obj.
_expr.evaluate (omega_K, K, value1);
182 value.resize(value1.size());
184 value[i] = obj._f (value1[i]);
194 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
196 Eigen::Matrix<Arg,Eigen::Dynamic,1> value1;
197 obj.
_expr.evaluate_on_side (omega_K, K, sid, value1);
198 value.resize (value1.size());
200 value[i] = obj._f (value1[i]);
207 template<
class Result,
class Arg,
class M>
211 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
220 eval (*
this, omega_K, K,
value);
225 template<
class Result,
class Arg,
class M>
230 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
239 eval (*
this, omega_K, K, sid,
value);
244 template<class This, class Result, class Arg, space_constant::valued_type ArgTag = space_constant::valued_tag_traits<Arg>::value>
248 template<
class This,
class Result,
class Arg>
255 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
259 switch (arg_valued_tag) {
261 obj.template evaluate_call<Result,T,M> (omega_K, K,
value);
break;
263 obj.template evaluate_call<Result, point_basic<T> > (omega_K, K,
value);
break;
266 obj.template evaluate_call<Result, tensor_basic<T> > (omega_K, K,
value);
break;
267 default: {
error_macro (
"unexpected valued tag="<<arg_valued_tag); }
276 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
280 switch (arg_valued_tag) {
282 obj.template evaluate_call<Result,T> (omega_K, K, sid,
value);
break;
284 obj.template evaluate_call<Result, point_basic<T> > (omega_K, K,
value);
break;
287 obj.template evaluate_call<Result, tensor_basic<T> > (omega_K, K,
value);
break;
288 default: {
error_macro (
"unexpected valued tag="<<arg_valued_tag); }
293 #define _RHEOLEF_evaluate_switch_specialization(VALUED,VALUE) \
294 template<class This, class Result, class Arg> \
295 struct evaluate_switch <This, Result, Arg, VALUED> { \
296 typedef typename scalar_traits<Arg>::type T; \
297 typedef typename float_traits<Arg>::type float_type; \
301 const geo_basic<float_type,memory_type>& omega_K, \
302 const geo_element& K, \
303 Eigen::Matrix<Result,Eigen::Dynamic,1>& value) const \
304 { obj.template evaluate_call<Result, VALUE> (omega_K, K, value); } \
307 void evaluate_on_side ( \
309 const geo_basic<float_type,M>& omega_K, \
310 const geo_element& K, \
311 const side_information_type& sid, \
312 Eigen::Matrix<Result,Eigen::Dynamic,1>& value) const \
313 { obj.template evaluate_call<Result, VALUE> (omega_K, K, sid, value); } \
321 #undef _RHEOLEF_evaluate_switch_specialization
326 template<
class Result>
329 const geo_basic<float_type,memory_type>& omega_K,
330 const geo_element& K,
331 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
333 typedef field_expr_v2_nonlinear_node_unary<UnaryFunction, Expr> This;
334 typedef typename details::generic_unary_traits<UnaryFunction>::template hint<typename Expr::value_type,Result>::argument_type
336 evaluate_switch <This, Result, A1> helper;
337 helper.evaluate (*
this, omega_K, K,
value);
342 template<
class Result>
345 const geo_basic<float_type,memory_type>& omega_K,
346 const geo_element& K,
347 const side_information_type& sid,
348 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
350 typedef field_expr_v2_nonlinear_node_unary<UnaryFunction, Expr> This;
351 typedef typename details::generic_unary_traits<UnaryFunction>::template hint<typename Expr::value_type,Result>::argument_type
353 evaluate_switch <This, Result, A1> helper;
354 helper.evaluate_on_side (*
this, omega_K, K, sid,
value);
357 template<
class Result>
359 typedef typename details::generic_unary_traits<UnaryFunction>::template hint<typename Expr::value_type,Result>::argument_type
361 if (! is_undeterminated<A1>::value)
return _expr.template valued_check<A1>();
371 Eigen::Matrix<scalar_type,Eigen::Dynamic,1>
374 Eigen::Matrix<point_basic<scalar_type>,Eigen::Dynamic,1>
377 Eigen::Matrix<tensor_basic<scalar_type>,Eigen::Dynamic,1>
380 Eigen::Matrix<tensor3_basic<scalar_type>,Eigen::Dynamic,1>
383 Eigen::Matrix<tensor4_basic<scalar_type>,Eigen::Dynamic,1>
387 template<
class UnaryFunction,
class Expr>
389 const UnaryFunction&
f,
403 field_expr_v2_nonlinear_node_unary<F,Expr>::is_affine_homogeneous::value>
::type>: std::true_type {};
411 #define _RHEOLEF_make_field_expr_v2_nonlinear_unary_operator(FUNCTION,FUNCTOR) \
412 template<class Expr> \
416 details::is_field_expr_v2_nonlinear_arg<Expr>::value \
417 && ! details::is_field_expr_v2_constant <Expr>::value \
418 ,details::field_expr_v2_nonlinear_node_unary< \
420 ,typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr>::type \
423 FUNCTION (const Expr& expr) \
425 typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr>::type wrap_t; \
426 return details::field_expr_v2_nonlinear_node_unary <FUNCTOR,wrap_t> (FUNCTOR(), wrap_t(expr)); \
429 #define _RHEOLEF_make_field_expr_v2_nonlinear_unary_function(FUNCTION) \
430 _RHEOLEF_make_field_expr_v2_nonlinear_unary_operator(FUNCTION, details::FUNCTION##_)
462 #undef _RHEOLEF_make_field_expr_v2_nonlinear_unary_function
463 #undef _RHEOLEF_make_field_expr_v2_nonlinear_unary_operator
469 template<
class Function,
class Expr>
492 template<
class BinaryFunction,
class Expr1,
class Expr2>
498 using result_type =
typename details::generic_binary_traits<BinaryFunction>::template result_hint<typename Expr1::result_type,typename Expr2::result_type>::type;
524 std::is_same<BinaryFunction,details::plus>
525 ,std::is_same<BinaryFunction,details::minus>
527 ,is_field_expr_affine_homogeneous<Expr1>
528 ,is_field_expr_affine_homogeneous<Expr2>
532 std::is_same<BinaryFunction,details::multiplies>
533 ,std::is_same<BinaryFunction,details::divides>
535 ,is_field_expr_affine_homogeneous<Expr1>
536 ,is_field_expr_v2_constant <Expr2>
539 std::is_same<BinaryFunction,details::multiplies>
540 ,is_field_expr_v2_constant <Expr1>
541 ,is_field_expr_affine_homogeneous<Expr2>
546 return is_affine_homogeneous::value
547 &&
_expr1.have_homogeneous_space (Vh)
548 &&
_expr2.have_homogeneous_space (Vh2)
549 && Vh.name() == Vh2.name();
555 typename Expr1::scalar_type,
556 typename Expr2::scalar_type>
::type;
561 :
_f(
f), _iter1 (iter1), _iter2 (iter2) {}
589 _expr1.initialize (pops, iopt);
590 _expr2.initialize (pops, iopt);
597 _expr1.initialize (Xh, pops, iopt);
598 _expr2.initialize (Xh, pops, iopt);
603 template<
class Result,
class Arg1,
class Arg2,
class M>
607 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
609 Eigen::Matrix<Arg1,Eigen::Dynamic,1> value1;
_expr1.evaluate (omega_K, K, value1);
610 Eigen::Matrix<Arg2,Eigen::Dynamic,1> value2;
_expr2.evaluate (omega_K, K, value2);
611 value.resize (value1.size());
613 for (
size_t i = 0, ni =
value.rows(); i < ni; ++i) {
614 value[i] =
_f (value1[i], value2[i]);
617 template<
class Result,
class Arg1,
class Arg2,
class M>
622 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
624 Eigen::Matrix<Arg1,Eigen::Dynamic,1> value1;
_expr1.evaluate_on_side (omega_K, K, sid, value1);
625 Eigen::Matrix<Arg2,Eigen::Dynamic,1> value2;
_expr2.evaluate_on_side (omega_K, K, sid, value2);
626 value.resize (value1.size());
627 for (
size_t i = 0, ni =
value.rows(); i < ni; ++i) {
628 value[i] =
_f (value1[i], value2[i]);
631 template<
class This,
class Result,
class ReturnType,
class Arg1,
class Arg2>
632 struct evaluate_internal {
636 const geo_basic<float_type,M>& omega_K,
637 const geo_element& K,
638 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
641 << pretty_typename_macro(ReturnType) <<
": "
642 << pretty_typename_macro(Result) <<
" was expected for function "
644 << pretty_typename_macro(Arg1) <<
","
645 << pretty_typename_macro(Arg2) <<
")");
650 const geo_basic<float_type,M>& omega_K,
651 const geo_element& K,
652 const side_information_type& sid,
653 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
656 << pretty_typename_macro(ReturnType) <<
": "
657 << pretty_typename_macro(Result) <<
" was expected for function "
659 << pretty_typename_macro(Arg1) <<
","
660 << pretty_typename_macro(Arg2) <<
")");
663 template<
class This,
class Result,
class Arg1,
class Arg2>
664 struct evaluate_internal<This,Result,Result,Arg1,Arg2> {
670 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
671 { obj.template evaluate_internal2<Result,Arg1,Arg2,M> (omega_K, K,
value); }
679 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
680 { obj.template evaluate_internal2 <Result,Arg1,Arg2,M> (omega_K, K, sid,
value);
683 template<
class Result,
class Arg1,
class Arg2,
class M>
687 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
689 typedef typename details::generic_binary_traits<BinaryFunction>::template result_hint<Arg1,Arg2>::type ReturnType;
690 typedef field_expr_v2_nonlinear_node_binary<BinaryFunction, Expr1, Expr2> This;
691 evaluate_internal<This,Result,ReturnType,Arg1,Arg2> eval_int;
692 eval_int (*
this, omega_K, K,
value);
694 template<
class Result,
class Arg1,
class Arg2,
class M>
699 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
701 typedef typename details::generic_binary_traits<BinaryFunction>::template result_hint<Arg1,Arg2>::type ReturnType;
702 typedef field_expr_v2_nonlinear_node_binary<BinaryFunction, Expr1, Expr2> This;
703 evaluate_internal<This,Result,ReturnType,Arg1,Arg2> eval_int;
704 eval_int (*
this, omega_K, K, sid,
value);
707 template<
class This,
class Result,
716 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
717 { obj.template evaluate_call<Result, Arg1, Arg2> (omega_K, K,
value); }
725 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
726 { obj.template evaluate_call<Result, Arg1, Arg2> (omega_K, K, sid,
value); }
729 template<
class This,
class Result,
740 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
746 switch (arg1_valued_tag) {
748 switch (arg2_valued_tag) {
750 return obj.template evaluate_call<Result, T1, T2> (omega_K, K,
value);
break;
752 return obj.template evaluate_call<Result, T1, point_basic<T2> > (omega_K, K,
value);
break;
755 return obj.template evaluate_call<Result, T1, tensor_basic<T2> > (omega_K, K,
value);
break;
757 return obj.template evaluate_call<Result, T1, tensor3_basic<T2> >(omega_K, K,
value);
break;
758 default:
error_macro (
"unexpected second argument valued tag="<<arg2_valued_tag);
763 switch (arg2_valued_tag) {
765 return obj.template evaluate_call<Result, point_basic<T1>, T2> (omega_K, K,
value);
break;
767 return obj.template evaluate_call<Result, point_basic<T1>,
point_basic<T2> > (omega_K, K,
value);
break;
770 return obj.template evaluate_call<Result, point_basic<T1>,
tensor_basic<T2> > (omega_K, K,
value);
break;
773 default:
error_macro (
"unexpected second argument valued tag="<<arg2_valued_tag);
779 switch (arg2_valued_tag) {
781 return obj.template evaluate_call<Result, tensor_basic<T1>, T2> (omega_K, K,
value);
break;
783 return obj.template evaluate_call<Result, tensor_basic<T1>,
point_basic<T2> > (omega_K, K,
value);
break;
786 return obj.template evaluate_call<Result, tensor_basic<T1>,
tensor_basic<T2> > (omega_K, K,
value);
break;
788 return obj.template evaluate_call<Result, tensor_basic<T1>,
tensor3_basic<T2> >(omega_K, K,
value);
break;
789 default:
error_macro (
"unexpected second argument valued tag="<<arg2_valued_tag);
794 switch (arg2_valued_tag) {
796 return obj.template evaluate_call<Result, tensor3_basic<T1>, T2> (omega_K, K,
value);
break;
798 return obj.template evaluate_call<Result, tensor3_basic<T1>,
point_basic<T2> > (omega_K, K,
value);
break;
801 return obj.template evaluate_call<Result, tensor3_basic<T1>,
tensor_basic<T2> > (omega_K, K,
value);
break;
803 return obj.template evaluate_call<Result, tensor3_basic<T1>,
tensor3_basic<T2> >(omega_K, K,
value);
break;
804 default:
error_macro (
"unexpected second argument valued tag="<<arg2_valued_tag);
808 default:
error_macro (
"unexpected first argument valued tag="<<arg1_valued_tag);
813 template<
class This,
class Result,
824 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
828 switch (arg2_valued_tag) {
830 return obj.template evaluate_call<Result, Arg1, T2> (omega_K, K,
value);
break;
832 return obj.template evaluate_call<Result, Arg1, point_basic<T2> > (omega_K, K,
value);
break;
835 return obj.template evaluate_call<Result, Arg1, tensor_basic<T2> > (omega_K, K,
value);
break;
837 return obj.template evaluate_call<Result, Arg1, tensor3_basic<T2> > (omega_K, K,
value);
break;
838 default:
error_macro (
"unexpected second argument valued tag="<<arg2_valued_tag);
843 template<
class This,
class Result,
854 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
858 switch (arg1_valued_tag) {
860 return obj.template evaluate_call<Result, T1, Arg2> (omega_K, K,
value);
break;
862 return obj.template evaluate_call<Result, point_basic<T1>, Arg2> (omega_K, K,
value);
break;
865 return obj.template evaluate_call<Result, tensor_basic<T1>, Arg2> (omega_K, K,
value);
break;
867 return obj.template evaluate_call<Result, tensor3_basic<T1>, Arg2>(omega_K, K,
value);
break;
868 default:
error_macro (
"unexpected first argument valued tag="<<arg1_valued_tag);
872 template<
class Result,
class M>
876 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
878 typedef typename details::generic_binary_traits<BinaryFunction>::template hint<
879 typename Expr1::value_type
880 ,
typename Expr2::value_type
881 ,Result>::first_argument_type A1;
882 typedef typename details::generic_binary_traits<BinaryFunction>::template hint<
883 typename Expr1::value_type
884 ,
typename Expr2::value_type
885 ,Result>::second_argument_type A2;
888 typedef field_expr_v2_nonlinear_node_binary<BinaryFunction, Expr1, Expr2> This;
890 eval (*
this, omega_K, K,
value);
892 template<
class Result,
class M>
898 Eigen::Matrix<Result,Eigen::Dynamic,1>&
value)
const
900 typedef typename details::generic_binary_traits<BinaryFunction>::template hint<
901 typename Expr1::value_type
902 ,
typename Expr2::value_type
903 ,Result>::first_argument_type A1;
904 typedef typename details::generic_binary_traits<BinaryFunction>::template hint<
905 typename Expr1::value_type
906 ,
typename Expr2::value_type
907 ,Result>::second_argument_type A2;
910 typedef field_expr_v2_nonlinear_node_binary<BinaryFunction, Expr1, Expr2> This;
912 eval (*
this, omega_K, K, sid,
value);
914 template<
class Result>
916 typedef typename details::generic_binary_traits<BinaryFunction>::template hint<
917 typename Expr1::value_type
918 ,
typename Expr2::value_type
919 ,Result>::first_argument_type A1;
920 typedef typename details::generic_binary_traits<BinaryFunction>::template hint<
921 typename Expr1::value_type
922 ,
typename Expr2::value_type
923 ,Result>::second_argument_type A2;
936 template<
class BinaryFunction,
class Expr1,
class Expr2>
949 field_expr_v2_nonlinear_node_binary<F,Expr1,Expr2>::is_affine_homogeneous::value>::type>: std::true_type {};
997 #define _RHEOLEF_make_field_expr_v2_nonlinear_binary(FUNCTION,FUNCTOR) \
998 template<class Expr1, class Expr2> \
1002 details::is_field_expr_v2_nonlinear_arg<Expr1>::value \
1003 && details::is_field_expr_v2_nonlinear_arg<Expr2>::value \
1004 && ! details::is_field_expr_v2_constant <Expr1>::value \
1005 && ! details::is_field_expr_v2_constant <Expr2>::value \
1006 ,details::field_expr_v2_nonlinear_node_binary< \
1008 ,typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type \
1009 ,typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type \
1012 FUNCTION (const Expr1& expr1, const Expr2& expr2) \
1014 typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type wrap1_t; \
1015 typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type wrap2_t; \
1016 return details::field_expr_v2_nonlinear_node_binary <FUNCTOR,wrap1_t,wrap2_t> \
1017 (FUNCTOR(), wrap1_t(expr1), wrap2_t(expr2)); \
1019 template<class Expr1, class Expr2> \
1023 details::is_field_expr_v2_constant <Expr1>::value \
1024 && details::is_field_expr_v2_nonlinear_arg<Expr2>::value \
1025 && ! details::is_field_expr_v2_constant <Expr2>::value \
1026 ,details::field_expr_v2_nonlinear_node_unary< \
1027 details::binder_first< \
1029 ,typename details::field_promote_first_argument< \
1031 ,typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type::value_type \
1034 ,typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type \
1037 FUNCTION (const Expr1& expr1, const Expr2& expr2) \
1039 typedef typename details::field_promote_first_argument< \
1041 ,typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type::value_type \
1044 typedef details::binder_first<FUNCTOR,value_type> fun_t; \
1045 typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type wrap2_t; \
1046 return details::field_expr_v2_nonlinear_node_unary<fun_t,wrap2_t>(fun_t(FUNCTOR(), expr1), wrap2_t(expr2)); \
1048 template<class Expr1, class Expr2> \
1052 details::is_field_expr_v2_constant <Expr2>::value \
1053 && details::is_field_expr_v2_nonlinear_arg<Expr1>::value \
1054 && ! details::is_field_expr_v2_constant <Expr1>::value \
1055 ,details::field_expr_v2_nonlinear_node_unary< \
1056 details::binder_second< \
1058 ,typename details::field_promote_second_argument< \
1059 typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type::value_type \
1063 ,typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type \
1066 FUNCTION (const Expr1& expr1, const Expr2& expr2) \
1068 typedef typename details::field_promote_second_argument< \
1069 typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type::value_type \
1073 typedef details::binder_second<FUNCTOR,value_type> fun_t; \
1074 typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type wrap1_t; \
1075 return details::field_expr_v2_nonlinear_node_unary<fun_t,wrap1_t>(fun_t(FUNCTOR(), expr2), wrap1_t(expr1)); \
1087 #define _RHEOLEF_make_field_expr_v2_nonlinear_binary_function(FUNCTION) \
1088 _RHEOLEF_make_field_expr_v2_nonlinear_binary (FUNCTION, details::FUNCTION##_) \
1098 #undef _RHEOLEF_make_field_expr_v2_nonlinear_binary_function
1099 #undef _RHEOLEF_make_field_expr_v2_nonlinear_binary
1109 template<
class Function,
class Expr1,
class Expr2>
1123 compose (
const Function&
f,
const Expr1& expr1,
const Expr2& expr2)
1125 typedef typename details::function_traits<Function>::functor_type
fun_wrap_t;
1126 typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type
expr1_wrap_t;
1127 typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type
expr2_wrap_t;
1133 template <
class Function,
class Expr1,
class Expr2>
1141 details::binder_first<
1145 ,
typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type::value_type
1151 compose (
const Function&
f,
const Expr1& expr1,
const Expr2& expr2)
1155 ,
typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type::value_type
1158 typedef details::binder_first<wrap_fun_t,value_type> binded_fun_t;
1161 <binded_fun_t, wrap2_t>
1162 (binded_fun_t(wrap_fun_t(
f), expr1), wrap2_t(expr2));
1165 template <
class Function,
class Expr1,
class Expr2>
1169 details::is_field_expr_v2_nonlinear_arg<Expr1>::value
1170 && ! details::is_field_expr_v2_constant <Expr1>::value
1171 && details::is_field_expr_v2_constant <Expr2>::value
1172 ,details::field_expr_v2_nonlinear_node_unary<
1173 details::binder_second<
1174 typename details::function_traits<Function>::functor_type
1176 typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type::value_type
1180 ,
typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type
1183 compose (
const Function&
f,
const Expr1& expr1,
const Expr2& expr2)
1185 typedef typename promote<
1186 typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type::value_type
1189 typedef typename details::function_traits<Function>::functor_type wrap_fun_t;
1190 typedef details::binder_second<wrap_fun_t,value_type> binded_fun_t;
1191 typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type wrap1_t;
1192 return details::field_expr_v2_nonlinear_node_unary
1193 <binded_fun_t, wrap1_t>
1194 (binded_fun_t(wrap_fun_t(
f), expr2), wrap1_t(expr1));
1198 #endif // _RHEOLEF_FIELD_EXPR_RECURSIVE_H