30 #if !defined( PP_OPERATORS_HPP )
31 #define PP_OPERATORS_HPP 1
33 #include <feel/feelconfig.h>
34 #if defined( FEELPP_HAS_QD_H )
39 # include <boost/preprocessor/comparison/less.hpp>
40 # include <boost/preprocessor/comparison/equal.hpp>
41 # include <boost/preprocessor/logical/and.hpp>
42 # include <boost/preprocessor/control/if.hpp>
43 # include <boost/preprocessor/list/at.hpp>
44 # include <boost/preprocessor/list/cat.hpp>
45 # include <boost/preprocessor/list/for_each_product.hpp>
46 # include <boost/preprocessor/logical/or.hpp>
47 # include <boost/preprocessor/tuple/to_list.hpp>
48 # include <boost/preprocessor/tuple/eat.hpp>
49 # include <boost/preprocessor/facilities/empty.hpp>
50 # include <boost/preprocessor/punctuation/comma.hpp>
51 # include <boost/preprocessor/facilities/identity.hpp>
57 # define VF_OP_SYMBOL(O) BOOST_PP_TUPLE_ELEM(9, 0, O)
58 # define VF_OP_NAME(O) BOOST_PP_TUPLE_ELEM(9, 1, O)
59 # define VF_OP_IS_FLOATING(O) BOOST_PP_TUPLE_ELEM(9, 2, O)
60 # define VF_OP_IS_LOGICAL(O) BOOST_PP_TUPLE_ELEM(9, 3, O)
61 # define VF_OP_IS_SHIFT(O) BOOST_PP_TUPLE_ELEM(9, 4, O)
62 # define VF_OP_IS_ADD(O) BOOST_PP_TUPLE_ELEM(9, 5, O)
63 # define VF_OP_IS_SYMETRIC(O) BOOST_PP_TUPLE_ELEM(9, 6, O)
64 # define VF_OP_SHAPE(O) BOOST_PP_TUPLE_ELEM(9, 7, O)
65 # define VF_OP_IMORDER(O) BOOST_PP_TUPLE_ELEM(9, 8, O)
68 # define VF_APPLICATIVE_UNARY_OPS \
69 BOOST_PP_TUPLE_TO_LIST( \
72 ( ! , vf_logical_not, 1, 1, 0,0,0), \
73 ( ~ , vf_bitwise_not, 0, 0, 0,0,0), \
74 ( - , vf_neg, 1, 0, 0,0,0) \
81 # define VF_APPLICATIVE_BINARY_OPS \
82 BOOST_PP_TUPLE_TO_LIST( \
85 ( * , vf_mul ,1 ,0 ,0 ,0 ,1), \
86 ( / , vf_div ,1 ,0 ,0 ,0 ,0), \
87 ( % , vf_mod ,0 ,0 ,0 ,0 ,0), \
88 ( + , vf_add ,1 ,0 ,0 ,1 ,1), \
89 ( - , vf_sub ,1 ,0 ,0 ,1 ,0), \
90 ( << , vf_shift_left ,0 ,0 ,1 ,0 ,0), \
91 ( >> , vf_shift_right ,0 ,0 ,1 ,0 ,0), \
92 ( < , vf_less ,1 ,1 ,0 ,0 ,0), \
93 ( <= , vf_less_equal ,1 ,1 ,0 ,0 ,0), \
94 ( >= , vf_greater_equal ,1 ,1 ,0 ,0 ,0), \
95 ( > , vf_greater ,1 ,1 ,0 ,0 ,0), \
96 ( == , vf_equal ,1 ,1 ,0 ,0 ,0), \
97 ( != , vf_not_equal ,1 ,1 ,0 ,0 ,0), \
98 ( & , vf_bitwise_and ,0 ,0 ,0 ,0 ,0), \
99 ( | , vf_bitwise_or ,0 ,0 ,0 ,0 ,0), \
100 ( ^ , vf_bitwise_xor ,0 ,0 ,0 ,0 ,0), \
101 ( && , vf_logical_and ,1 ,1 ,0 ,0 ,0), \
102 ( || , vf_logical_or ,1 ,1 ,0 ,0, 0) \
107 # // get rid of operator^ which is used for power computation
109 # define VF_APPLICATIVE_BINARY_OPS \
110 BOOST_PP_TUPLE_TO_LIST( \
113 ( * , vf_mul ,1 ,0 ,0 ,0 ,1, shape_op_mul ,2 ), \
114 ( / , vf_div ,1 ,0 ,0 ,0 ,0, shape_op_div ,1 ), \
115 ( + , vf_add ,1 ,0 ,0 ,1 ,1, shape_op_samerank ,1 ), \
116 ( - , vf_sub ,1 ,0 ,0 ,1 ,0, shape_op_samerank ,1 ), \
117 ( < , vf_less ,1 ,1 ,0 ,0 ,0, shape_op_id ,0 ), \
118 ( <= , vf_less_equal ,1 ,1 ,0 ,0 ,0, shape_op_id ,0 ), \
119 ( >= , vf_greater_equal ,1 ,1 ,0 ,0 ,0, shape_op_id ,0 ), \
120 ( > , vf_greater ,1 ,1 ,0 ,0 ,0, shape_op_id ,0 ), \
121 ( == , vf_equal ,1 ,1 ,0 ,0 ,0, shape_op_id ,0 ), \
122 ( != , vf_not_equal ,1 ,1 ,0 ,0 ,0, shape_op_id ,0 ), \
123 ( && , vf_logical_and ,1 ,1 ,0 ,0 ,0, shape_op_id ,0 ), \
124 ( || , vf_logical_or ,1 ,1 ,0 ,0, 0, shape_op_id ,0 ) \
131 # define VF_TYPE_NAME(T) BOOST_PP_TUPLE_ELEM(5, 0, T)
132 # define VF_TYPE_ABBREVIATION(T) BOOST_PP_TUPLE_ELEM(5, 1, T)
133 # define VF_TYPE_IS_FLOATING(T) BOOST_PP_TUPLE_ELEM(5, 2, T)
134 # define VF_TYPE_RANK(T) BOOST_PP_TUPLE_ELEM(5, 3, T)
135 # define VF_TYPE_IS_EXPR(T) BOOST_PP_TUPLE_ELEM(5, 4, T)
138 # define VF_BUILTIN_TYPES \
139 BOOST_PP_TUPLE_TO_LIST( \
142 ( signed char ,sc, 0, 1,0), \
143 ( char ,ch, 0, 1,0), \
144 ( unsigned char ,uc, 0, 1,0), \
145 ( short ,ss, 0, 2,0), \
146 ( unsigned short ,us, 0, 2,0), \
148 ( unsigned ,ui, 0, 4,0), \
149 ( long ,sl, 0, 5,0), \
150 ( unsigned long ,ul, 0, 6,0), \
151 ( float ,fl, 1, 7,0), \
152 ( double ,db, 1, 8,0), \
153 ( long double ,ld, 1, 9,0) \
158 # if defined( DISABLE_FEELPP_HAS_QD_H ) && defined( DISABLE_FEELPP_HAS_MPFR )
159 # define VF_BUILTIN_TYPES \
160 BOOST_PP_TUPLE_TO_LIST( \
164 ( unsigned ,ui, 0, 4,0), \
165 ( long ,sl, 0, 5,0), \
166 ( unsigned long ,ul, 0, 6,0), \
167 ( float ,fl, 1, 7,0), \
168 ( double ,db, 1, 8,0), \
169 ( long double ,ld, 1, 9,0), \
170 ( std::complex<float> ,cfl, 1, 10,0), \
171 ( std::complex<double> ,cld, 1, 11,0), \
172 ( mp_type ,mp, 1,12,0), \
173 ( dd_real ,dd, 1,13,0), \
174 ( qd_real ,dd, 1,14,0) \
178 # elif defined (DISABLE_FEELPP_HAS_QD_H )
179 # define VF_BUILTIN_TYPES \
180 BOOST_PP_TUPLE_TO_LIST( \
184 ( unsigned ,ui, 0, 4,0), \
185 ( long ,sl, 0, 5,0), \
186 ( unsigned long ,ul, 0, 6,0), \
187 ( float ,fl, 1, 7,0), \
188 ( double ,db, 1, 8,0), \
189 ( long double ,ld, 1, 9,0), \
190 ( std::complex<float> ,cfl, 1, 10,0), \
191 ( std::complex<double> ,cld, 1, 11,0), \
192 ( dd_real ,dd, 1,12,0), \
193 ( qd_real ,dd, 1,13,0) \
197 # elif defined (DISABLE_FEELPP_HAS_MPFR )
198 # define VF_BUILTIN_TYPES \
199 BOOST_PP_TUPLE_TO_LIST( \
203 ( unsigned ,ui, 0, 4,0), \
204 ( long ,sl, 0, 5,0), \
205 ( unsigned long ,ul, 0, 6,0), \
206 ( float ,fl, 1, 7,0), \
207 ( double ,db, 1, 8,0), \
208 ( long double ,ld, 1, 9,0), \
209 ( std::complex<float> ,cfl, 1, 10,0), \
210 ( std::complex<double> ,cld, 1, 11,0), \
211 ( mp_type ,mp, 1,12,0) \
216 # define VF_BUILTIN_TYPES \
217 BOOST_PP_TUPLE_TO_LIST( \
221 ( unsigned ,ui, 0, 4,0), \
222 ( long ,sl, 0, 5,0), \
223 ( unsigned long ,ul, 0, 6,0), \
224 ( float ,fl, 1, 7,0), \
225 ( double ,db, 1, 8,0), \
226 ( long double ,ld, 1, 9,0), \
227 ( std::complex<float> ,cfl, 1, 10,0), \
228 ( std::complex<double> ,cld, 1, 11,0) \
236 # define VF_TYPE_INT (int, si, 0, 3, 0)
238 # define VF_VALUE_TYPE(L) \
239 BOOST_PP_LIST_CAT(BOOST_PP_TUPLE_TO_LIST(2,(value_type_,VF_TYPE_ABBREVIATION(L)))) \
242 # define VF_TYPE_CV(L) \
243 BOOST_PP_IF(VF_TYPE_IS_EXPR(L), \
244 BOOST_PP_IDENTITY(const&), \
248 # define VF_TYPE_VALUE_TYPE(L) \
249 BOOST_PP_IF(VF_TYPE_IS_EXPR(L), \
250 typename VF_TYPE_NAME(L)::value_type, \
251 VF_TYPE_NAME( L ) ) \
254 # define VF_TYPE_TYPE(L) \
255 BOOST_PP_IF(VF_TYPE_IS_EXPR(L), \
257 Cst<VF_TYPE_NAME( L )> ) \
260 # define VF_TYPE_TYPE_EXPR(L) \
261 BOOST_PP_IF(VF_TYPE_IS_EXPR(L), \
262 Expr<VF_TYPE_NAME(L)>, \
263 VF_TYPE_NAME( L ) ) \
266 # define VF_TYPE_TYPE_EXPR_CST(L) \
267 BOOST_PP_IF(VF_TYPE_IS_EXPR(L), \
268 Expr<VF_TYPE_NAME(L)>, \
269 Cst<VF_TYPE_NAME( L )> ) \
272 # define VF_TYPE_TYPE_CST(L) \
273 BOOST_PP_IF(BOOST_PP_NOT(VF_TYPE_IS_EXPR(L)), \
274 BOOST_PP_IDENTITY(Cst<VF_TYPE_NAME( L )>), \
278 # define VF_TEMPLATE_TYPE(L) \
279 BOOST_PP_IF(VF_TYPE_IS_EXPR(L), \
280 class VF_TYPE_NAME( L ), \
284 #define VF_TEXT(z, n, text) text
286 # define VF_SPECIALIZATION_IF_BUILTIN(L,R) \
287 BOOST_PP_IF(BOOST_PP_OR( BOOST_PP_NOT( VF_TYPE_IS_EXPR(L) ), \
288 BOOST_PP_NOT( VF_TYPE_IS_EXPR(R) ) ), \
289 BOOST_PP_IDENTITY(<VF_TYPE_TYPE(L)), \
291 BOOST_PP_IF(BOOST_PP_OR( BOOST_PP_NOT( VF_TYPE_IS_EXPR(L) ), \
292 BOOST_PP_NOT( VF_TYPE_IS_EXPR(R) ) ), \
295 BOOST_PP_IF(BOOST_PP_OR( BOOST_PP_NOT( VF_TYPE_IS_EXPR(L) ), \
296 BOOST_PP_NOT( VF_TYPE_IS_EXPR(R) ) ), \
297 BOOST_PP_IDENTITY(VF_TYPE_TYPE(R)>), \
301 # define VF_IM_ORDER(O,L,R) \
302 BOOST_PP_IF( BOOST_PP_EQUAL( VF_OP_IMORDER(O) , 0) , \
304 BOOST_PP_IF( BOOST_PP_EQUAL( VF_OP_IMORDER(O) , 1) , \
305 (VF_TYPE_TYPE(L)::imorder < VF_TYPE_TYPE(R)::imorder)*VF_TYPE_TYPE(R)::imorder \
306 + (VF_TYPE_TYPE(L)::imorder >= VF_TYPE_TYPE(R)::imorder)*VF_TYPE_TYPE(L)::imorder , \
307 VF_TYPE_TYPE(L)::imorder + VF_TYPE_TYPE(R)::imorder ) \
313 # define VF_EXPRL_TYPES \
314 BOOST_PP_TUPLE_TO_LIST( \
317 ( ExprL ,L, 1, 10, 1) \
322 # define VF_EXPRR_TYPES \
323 BOOST_PP_TUPLE_TO_LIST( \
326 ( ExprR ,R, 1, 10, 1) \
331 # define VF_BOOST_PP_EMPTY() \
335 # define VF_BINARY_ARRAY_OP(_, OLR) \
336 VF_BINARY_ARRAY_OP_CODE OLR \
339 #define VF_BINARY_ARRAY_OP_CODE(O,L,R) \
340 template <BOOST_PP_IF( VF_TYPE_IS_EXPR( L ), \
341 BOOST_PP_IDENTITY(class VF_TYPE_NAME(L)), \
344 BOOST_PP_IF( BOOST_PP_AND( VF_TYPE_IS_EXPR(L), \
345 VF_TYPE_IS_EXPR(R) ), \
348 BOOST_PP_IF( VF_TYPE_IS_EXPR( R ), \
349 BOOST_PP_IDENTITY(class VF_TYPE_NAME(R)), \
352 class VF_OP_NAME( O ) VF_SPECIALIZATION_IF_BUILTIN( L, R ) \
355 typedef VF_OP_NAME( O )<VF_TYPE_TYPE_EXPR_CST( L ), VF_TYPE_TYPE_EXPR_CST( R )> expression_type; \
356 typedef VF_OP_NAME( O )<VF_TYPE_TYPE_EXPR_CST( L ), VF_TYPE_TYPE_EXPR_CST( R )> this_type; \
357 typedef VF_TYPE_VALUE_TYPE( L ) VF_VALUE_TYPE(L); \
358 typedef VF_TYPE_VALUE_TYPE( R ) VF_VALUE_TYPE(R); \
359 typedef VF_TYPE_TYPE( L ) L_type; \
360 typedef VF_TYPE_TYPE( R ) R_type; \
362 static const size_type context = L_type::context | R_type::context; \
364 static const uint16_type imorder = VF_IM_ORDER(O,L,R) ; \
365 static const bool imIsPoly = L_type::imIsPoly && R_type::imIsPoly; \
366 static const bool is_terminal = false; \
368 template<typename Func> \
369 struct HasTestFunction \
371 static const bool result = L_type::template HasTestFunction<Func>::result|R_type::template HasTestFunction<Func>::result; \
374 template<typename Func> \
375 struct HasTrialFunction \
377 static const bool result = L_type::template HasTrialFunction<Func>::result|R_type::template HasTrialFunction<Func>::result; \
380 typedef typename mpl::if_<mpl::greater<mpl::sizeof_<VF_VALUE_TYPE(L)>, \
381 mpl::sizeof_<VF_VALUE_TYPE(R)> >, \
382 mpl::identity<VF_VALUE_TYPE(L)>, \
383 mpl::identity<VF_VALUE_TYPE(R)> >::type::type value_type; \
385 VF_OP_NAME( O )( L_type const& left, R_type const& right ) \
390 VF_OP_NAME( O )( VF_OP_NAME(O) const& __m ) \
392 M_left( __m.M_left ), \
393 M_right( __m.M_right ) \
397 template<typename TheExpr> \
400 typedef VF_OP_NAME( O )<typename L_type::template Lambda<TheExpr>::type,typename R_type::template Lambda<TheExpr>::type> type; \
403 template<typename TheExpr> \
404 typename Lambda<TheExpr>::type \
405 operator()( TheExpr const& e ) { return typename Lambda<TheExpr>::type( M_left(e), M_right(e) ); } \
407 L_type VF_TYPE_CV(L) left() const { return M_left; } \
408 R_type VF_TYPE_CV(R) right() const { return M_right; } \
410 template<typename Geo_t, typename Basis_i_t, typename Basis_j_t = Basis_i_t> \
413 typedef this_type expression_type; \
414 typedef typename L_type::template tensor<Geo_t, Basis_i_t, Basis_j_t> l_type; \
415 typedef typename R_type::template tensor<Geo_t, Basis_i_t, Basis_j_t> r_type; \
416 typedef typename strongest_numeric_type<typename l_type::value_type, \
417 typename r_type::value_type>::type value_type; \
418 typedef typename VF_OP_SHAPE( O )<typename l_type::shape, typename r_type::shape>::type shape; \
419 static const int shape_op = VF_OP_SHAPE( O )<typename l_type::shape, typename r_type::shape>::op; \
422 static const bool value = VF_OP_SHAPE( O )<typename l_type::shape, typename r_type::shape>::template is_zero<l_type::is_zero::value, r_type::is_zero::value>::value; \
423 static const bool update_and_eval_left = VF_OP_SHAPE( O )<typename l_type::shape, typename r_type::shape>::template is_zero<l_type::is_zero::value, r_type::is_zero::value>::update_and_eval_left; \
424 static const bool update_and_eval_right = VF_OP_SHAPE( O )<typename l_type::shape, typename r_type::shape>::template is_zero<l_type::is_zero::value, r_type::is_zero::value>::update_and_eval_right; \
427 template<typename ExprT> \
428 tensor( ExprT const& expr, Geo_t const& geom, Basis_i_t const& fev, Basis_j_t const& feu ) \
430 M_left( expr.left(), geom, fev, feu ), \
431 M_right( expr.right(), geom, fev, feu ) \
433 DVLOG(2) << "Operation " BOOST_PP_STRINGIZE( VF_OP_SYMBOL( O ) ) " is_zero " << is_zero::value << " " \
434 << "update_and_eval_left " << is_zero::update_and_eval_left << " " \
435 << " update_and_eval_right " << is_zero::update_and_eval_right << " " \
436 << " left_is_zero " << l_type::is_zero::value << " " \
437 << " right_is_zero " << r_type::is_zero::value << "\n"; \
439 template<typename ExprT> \
440 tensor( ExprT const& expr,Geo_t const& geom, Basis_i_t const& fev ) \
442 M_left( expr.left(), geom, fev ), \
443 M_right( expr.right(), geom, fev ) \
445 template<typename ExprT> \
446 tensor( ExprT const& expr, Geo_t const& geom ) \
448 M_left( expr.left(), geom ), \
449 M_right( expr.right(), geom ) \
452 template<typename IM> \
453 void init( IM const& im ) \
456 M_right.init( im ); \
458 void update( Geo_t const& geom, Basis_i_t const& fev, Basis_j_t const& feu ) \
460 if ( is_zero::update_and_eval_left ) \
461 M_left.update( geom, fev, feu ); \
462 if ( is_zero::update_and_eval_right ) \
463 M_right.update( geom, fev, feu ); \
465 void update( Geo_t const& geom, Basis_i_t const& fev ) \
467 if ( is_zero::update_and_eval_left ) \
468 M_left.update( geom, fev ); \
469 if ( is_zero::update_and_eval_right ) \
470 M_right.update( geom, fev ); \
472 void update( Geo_t const& geom ) \
474 if ( is_zero::update_and_eval_left ) \
475 M_left.update( geom ); \
476 if ( is_zero::update_and_eval_right ) \
477 M_right.update( geom ); \
479 void update( Geo_t const& geom, uint16_type face ) \
481 if ( is_zero::update_and_eval_left ) \
482 M_left.update( geom, face ); \
483 if ( is_zero::update_and_eval_right ) \
484 M_right.update( geom, face ); \
488 evalij( uint16_type i, uint16_type j ) const \
490 return M_left.evalij(i,j) VF_OP_SYMBOL( O ) M_right.evalij(i,j); \
494 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q ) const \
496 return evalijq(i,j,c1,c2,q,mpl::int_<shape_op>() ); \
498 template<int PatternContext> \
500 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::int_<PatternContext> ) const \
502 return evalijq(i,j,c1,c2,q,mpl::int_<PatternContext>(),mpl::int_<shape_op>() ); \
506 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::int_<0> ) const \
508 return evalijq( i, j, c1, c2, q, mpl::bool_<is_zero::update_and_eval_left>(), mpl::bool_<is_zero::update_and_eval_right>() ); \
512 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::bool_<false>, mpl::bool_<false> ) const \
514 return value_type( 0 ); \
518 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::bool_<true>, mpl::bool_<false> ) const \
520 return M_left.evalijq(i, j, c1, c2, q); \
524 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::bool_<false>, mpl::bool_<true> ) const \
526 return M_right.evalijq(i, j, c1, c2, q); \
530 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::bool_<true>, mpl::bool_<true> ) const \
532 return M_left.evalijq(i, j, c1, c2, q) VF_OP_SYMBOL( O ) M_right.evalijq(i,j, c1, c2, q); \
536 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::int_<1> ) const \
538 return evalijq( i, j, c1, c2, q, mpl::bool_<is_zero::value>() ); \
542 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::bool_<true> ) const \
544 return value_type( 0 ); \
548 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::bool_<false> ) const \
550 value_type res( value_type( 0 ) ); \
551 for(uint16_type ii = 0; ii < l_type::shape::N; ++ii ) \
552 res += M_left.evalijq(i, j, c1, ii, q ) VF_OP_SYMBOL( O ) M_right.evalijq(i, j, ii, c2, q ); \
555 template<int PatternContext> \
557 evalijq__( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::int_<PatternContext>, mpl::int_<0> ) const \
559 if ( is_zero::value ) \
560 return value_type( 0 ); \
561 else if ( !is_zero::update_and_eval_left && is_zero::update_and_eval_right ) \
562 return M_right.evalijq(i,j, c1, c2, q,mpl::int_<PatternContext>()); \
563 else if ( is_zero::update_and_eval_left && !is_zero::update_and_eval_right ) \
564 return M_left.evalijq(i, j, c1, c2, q,mpl::int_<PatternContext>()); \
566 return M_left.evalijq(i, j, c1, c2, q,mpl::int_<PatternContext>()) VF_OP_SYMBOL( O ) M_right.evalijq(i,j, c1, c2, q,mpl::int_<PatternContext>()); \
568 template<int PatternContext> \
570 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::int_<PatternContext>, mpl::int_<0> ) const \
572 return M_left.evalijq(i, j, c1, c2, q,mpl::int_<PatternContext>()) VF_OP_SYMBOL( O ) M_right.evalijq(i,j, c1, c2, q,mpl::int_<PatternContext>()); \
574 template<int PatternContext> \
576 evalijq( uint16_type i, uint16_type j, uint16_type c1, uint16_type c2, uint16_type q, mpl::int_<PatternContext>, mpl::int_<1> ) const \
578 value_type res( value_type( 0 ) ); \
579 for(uint16_type ii = 0; ii < l_type::shape::N; ++ii ) \
580 res += M_left.evalijq(i, j, c1, ii, q,mpl::int_<PatternContext>() ) VF_OP_SYMBOL( O ) M_right.evalijq(i, j, ii, c2, q,mpl::int_<PatternContext>() ); \
585 evaliq( uint16_type i, uint16_type c1, uint16_type c2, uint16_type q ) const \
587 return evaliq(i, c1, c2, q, mpl::int_<shape_op>() ); \
591 evaliq( uint16_type i, uint16_type c1, uint16_type c2, uint16_type q, mpl::int_<0> ) const \
593 if ( is_zero::value ) \
594 return value_type( 0 ); \
595 else if ( !is_zero::update_and_eval_left && is_zero::update_and_eval_right ) \
596 return M_right.evaliq(i, c1, c2, q); \
597 else if ( is_zero::update_and_eval_left && !is_zero::update_and_eval_right ) \
598 return M_left.evaliq(i, c1, c2, q); \
600 return M_left.evaliq(i, c1, c2, q) VF_OP_SYMBOL( O ) M_right.evaliq(i, c1, c2, q); \
604 evaliq( uint16_type i, uint16_type c1, uint16_type c2, uint16_type q, mpl::int_<1> ) const \
606 if ( is_zero::value ) \
607 return value_type( 0 ); \
610 value_type res( value_type( 0 ) ); \
611 for(uint16_type ii = 0; ii < l_type::shape::N; ++ii ) \
612 res += M_left.evaliq(i, c1, ii, q ) VF_OP_SYMBOL( O ) M_right.evaliq(i, ii, c2, q ); \
617 evalq( uint16_type c1, uint16_type c2, uint16_type q ) const \
619 return evalq( c1, c2, q, mpl::int_<shape_op>() ); \
623 evalq( uint16_type c1, uint16_type c2, uint16_type q, mpl::int_<0> ) const \
625 return M_left.evalq( c1, c2, q ) VF_OP_SYMBOL( O ) M_right.evalq( c1, c2, q ); \
628 evalq( uint16_type c1, uint16_type c2, uint16_type q, mpl::int_<1> ) const \
630 value_type res( value_type( 0 ) ); \
631 for(uint16_type ii = 0; ii < l_type::shape::N; ++ii ) \
632 res += M_left.evalq( c1, ii, q ) VF_OP_SYMBOL( O ) M_right.evalq( ii, c2, q ); \
641 return M_left.evaluate() VF_OP_SYMBOL( O ) M_right.evaluate(); \
644 evaluate(bool p) const \
646 return M_left.evaluate(p) VF_OP_SYMBOL( O ) M_right.evaluate(p); \
649 std::string expressionStr() const \
651 return std::string(); \
656 BOOST_PP_IF(BOOST_PP_AND(VF_OP_IS_ADD(O), \
657 BOOST_PP_AND(VF_TYPE_IS_EXPR(L),VF_TYPE_IS_EXPR(R))), \
662 VF_OP_NAME( O )() {} \
667 template <BOOST_PP_IF( VF_TYPE_IS_EXPR( L ), \
668 BOOST_PP_IDENTITY(class VF_TYPE_NAME(L)), \
671 BOOST_PP_IF( BOOST_PP_AND( VF_TYPE_IS_EXPR(L), \
672 VF_TYPE_IS_EXPR(R) ), \
675 BOOST_PP_IF( VF_TYPE_IS_EXPR( R ), \
676 BOOST_PP_IDENTITY(class VF_TYPE_NAME(R)), \
680 Expr< VF_OP_NAME( O )< VF_TYPE_TYPE_EXPR_CST(L), VF_TYPE_TYPE_EXPR_CST(R) > > \
681 operator VF_OP_SYMBOL( O )( VF_TYPE_TYPE_EXPR(L) VF_TYPE_CV(L) v, VF_TYPE_TYPE_EXPR(R) VF_TYPE_CV(R) w ) \
683 typedef VF_OP_NAME( O )<VF_TYPE_TYPE_EXPR_CST( L ), VF_TYPE_TYPE_EXPR_CST( R )> expr_t; \
684 return Expr<expr_t> (expr_t ( VF_TYPE_TYPE_CST(L)(v) , VF_TYPE_TYPE_CST(R)(w) )); \
688 # define VF_ASSEMBLE() \
689 template<typename Elem1, typename Elem2, typename FormType> \
690 void assemble( boost::shared_ptr<Elem1> const& __u, boost::shared_ptr<Elem2> const& __v, FormType& __f ) const \
692 M_left.assemble( __u, __v, __f ); \
693 M_right.assemble( __u, __v, __f ); \
696 template<typename Elem1, typename FormType> \
697 void assemble( boost::shared_ptr<Elem1> const& __v, FormType& __f ) const \
699 M_left.assemble( __v, __f ); \
700 M_right.assemble( __v, __f ); \
704 # define VF_SYMETRIC() \
705 bool isSymetric() const \
716 BOOST_PP_LIST_FOR_EACH_PRODUCT( VF_BINARY_ARRAY_OP, 3, ( VF_APPLICATIVE_BINARY_OPS, VF_EXPRL_TYPES, VF_EXPRR_TYPES ) )
717 BOOST_PP_LIST_FOR_EACH_PRODUCT( VF_BINARY_ARRAY_OP, 3, ( VF_APPLICATIVE_BINARY_OPS, VF_EXPRL_TYPES, VF_BUILTIN_TYPES ) )
718 BOOST_PP_LIST_FOR_EACH_PRODUCT( VF_BINARY_ARRAY_OP, 3, ( VF_APPLICATIVE_BINARY_OPS, VF_BUILTIN_TYPES, VF_EXPRR_TYPES ) )