00001 #ifndef SelectorUtils_Expressions_h
00002 #define SelectorUtils_Expressions_h
00003
00004
00005
00006
00007 namespace reco{
00008
00009 template<class T>
00010 class ExprBase {
00011 public:
00012 ExprBase() {};
00013 virtual bool operator()(const T& x) const { return 1;}
00014 virtual ExprBase * clone() { return new ExprBase(*this);}
00015 };
00016
00017
00018
00019 template<class Type>
00020 class Selector {
00021 public:
00022 Selector() {}
00023 template<class Expr>
00024 void operator=(Expr e){tmp = e.clone();}
00025 void operator()(Type * aClass) {return tmp->operator()(*aClass);}
00026 private:
00027 ExprBase<Type>* tmp;
00028 };
00029
00030
00031
00032
00033 template<class AnExpr>
00034 class Expr : public ExprBase<typename AnExpr::RetType> {
00035 public:
00036 typedef typename AnExpr::ArgType ArgType;
00037 typedef typename AnExpr::RetType RetType;
00038
00039 Expr( const AnExpr& expr = AnExpr() ):mExpr(expr) {};
00040 RetType operator()( const ArgType& x ) const
00041 { return mExpr(x); }
00042
00043 private:
00044 AnExpr mExpr;
00045 };
00046
00047
00048
00049 template< class Value, class ActON >
00050 class ExprLiteral
00051 {
00052 public:
00053 typedef Value RetType;
00054 typedef ActON ArgType;
00055
00056 ExprLiteral( const RetType& val)
00057 { mVal = val; }
00058
00059 RetType operator()( const ArgType& ) const
00060 { return mVal; }
00061
00062 private:
00063 RetType mVal;
00064 };
00065
00066
00068 template < class RETType >
00069 class ExprIdentity
00070 {
00071 public:
00072 typedef RETType RetType;
00073 typedef RETType ArgType;
00074
00075 RetType operator()( const ArgType& x ) const
00076 { return x; }
00077
00078 };
00079
00080
00081 template< class Value, class ActON >
00082 class ExprUserFun
00083 {
00084 public:
00085 typedef Value RetType;
00086 typedef ActON ArgType;
00087
00088 ExprUserFun( Value (ActON::* aFun)() const )
00089 {mFun = aFun;};
00090
00091 RetType operator()( const ArgType& x ) const
00092 {return (x.*mFun)();}
00093
00094 private:
00095 RetType (ActON::* mFun)() const;
00096 };
00097
00098
00100
00102 template< class T >
00103 struct Add {
00104 typedef T RetType;
00105 static inline RetType apply( const RetType& a, const RetType& b )
00106 {return ( a + b );}
00107 };
00108
00109 template< class T >
00110 struct Sub {
00111 typedef T RetType;
00112 static inline RetType apply( const RetType& a, const RetType& b )
00113 {return ( a - b );}
00114 };
00115
00116 template< class T >
00117 struct Mul {
00118 typedef T RetType;
00119 static inline RetType apply( const RetType& a, const RetType& b )
00120 {return ( a * b );}
00121 };
00122
00123 template< class T >
00124 struct Div {
00125 typedef T RetType;
00126 static inline RetType apply( const RetType& a, const RetType& b )
00127 {return ( a / b );}
00128 };
00129
00130
00132
00134 template< class T >
00135 struct And;
00136
00137 template<>
00138 struct And<bool> {
00139 typedef bool RetType;
00140 static inline RetType apply( bool a, bool b )
00141 {return ( a && b );}
00142 };
00143
00144 template< class T >
00145 struct Or;
00146
00147 template<>
00148 struct Or<bool> {
00149 typedef bool RetType;
00150 static inline RetType apply( bool a, bool b )
00151 {return ( a || b );}
00152 };
00153
00154
00156
00158 template< class T >
00159 struct Less {
00160 typedef bool RetType;
00161 static inline RetType apply( const T& a, const T& b )
00162 {return ( a < b );}
00163 };
00164
00165 template< class T >
00166 struct LessEqual {
00167 typedef bool RetType;
00168 static inline RetType apply( const T& a, const T& b )
00169 {return ( a <= b );}
00170 };
00171
00172 template< class T >
00173 struct More {
00174 typedef bool RetType;
00175 static inline RetType apply( const T& a, const T& b )
00176 {return ( a > b );}
00177 };
00178
00179 template< class T >
00180 struct MoreEqual {
00181 typedef bool RetType;
00182 static inline RetType apply( const T& a, const T& b )
00183 {return ( a >= b );}
00184 };
00185
00186 template< class T >
00187 struct Equal {
00188 typedef bool RetType;
00189 static inline RetType apply( const T& a, const T& b )
00190 {return ( a == b );}
00191 };
00192
00193
00194
00195 template< class A, class Operation, class B >
00196 class BinOp {
00197 public:
00198 typedef typename Operation::RetType RetType;
00199 typedef typename A::ArgType ArgType;
00200
00201 BinOp( const A& A, const B& B ):mA(A), mB(B)
00202 { };
00203
00204 RetType operator() (const ArgType& x) const
00205 {return Operation::apply( mA(x), mB(x) );}
00206
00207 private:
00208 A mA;
00209 B mB;
00210 };
00211
00213
00215 template< class A, class B >
00216 struct BasicConvTrait;
00217
00218 template<>
00219 struct BasicConvTrait< double, double >
00220 {typedef double ResultType;};
00221
00222 template<>
00223 struct BasicConvTrait< double, int >
00224 {typedef double ResultType;};
00225
00226 template<>
00227 struct BasicConvTrait< int, double >
00228 {typedef double ResultType;};
00229
00230 template<>
00231 struct BasicConvTrait< double, float >
00232 {typedef double ResultType;};
00233
00234 template<>
00235 struct BasicConvTrait< float, double >
00236 {typedef double ResultType;};
00237
00238 template<>
00239 struct BasicConvTrait< float, int >
00240 {typedef float ResultType;};
00241
00242 template<>
00243 struct BasicConvTrait< int, float >
00244 {typedef float ResultType;};
00245
00246 template<>
00247 struct BasicConvTrait< int, int >
00248 {typedef int ResultType;};
00249
00250 template<class A >
00251 struct BasicConvTrait< A, A >
00252 {typedef A ResultType;};
00253
00254
00256
00258 template< class A, class B >
00259 struct ConvTrait;
00260
00261 template< class A, class B >
00262 class ConvTrait<Expr<A>, Expr<B> > {
00263 private:
00264 typedef typename Expr<A>::RetType LReturn;
00265 typedef typename Expr<B>::RetType RReturn;
00266 public:
00267 typedef typename BasicConvTrait<LReturn,RReturn>::ResultType ResultType;
00268 };
00269
00270 template< class A , class ArgType>
00271 struct ToExprTraits;
00272
00273 template<class ArgType>
00274 struct ToExprTraits<double, ArgType> {
00275 typedef Expr< ExprLiteral<double, ArgType> > ToExprType;
00276 };
00277
00278 template<class ArgType>
00279 struct ToExprTraits<int, ArgType>{
00280 typedef Expr< ExprLiteral<int, ArgType> > ToExprType;
00281 };
00282
00283
00285
00287 template< template<class T> class Op, class A, class B >
00288 struct operator_trait;
00289
00290 template< template<class T> class Op, class A, class B>
00291 class operator_trait< Expr<A>, Op, Expr<B> > {
00292 private:
00293 typedef typename ConvTraits< Expr<A>, Expr<B> >::ResultType ResultType;
00294 public:
00295 typedef BinOp< Expr<A>, Op< ResultType >, Expr<B> > ReturnBaseType;
00296 typedef Expr< ReturnBaseType > ReturnType;
00297 };
00298
00299 template< template<class T> class Op, class A, class B >
00300 class operator_trait< Op, A, Expr<B> > {
00301 private:
00302 typedef typename Expr<B>::ArgType ArgType;
00303 typedef typename ToExprTrait<A, ArgType>::ToExprType ToExprType;
00304 typedef typename ConvTraits ToExprType, Expr<B> >::ResultType ResultType;
00305 public:
00306 typedef ToExprType LToExpr;
00307 typedef BinOp< ToExprType, Op<ResultType>, Expr<B> > ReturnBaseType;
00308 typedef Expr< ReturnBaseType > ReturnType;
00309 };
00310
00311 template< template<class T> class Op, class A, class B >
00312 class operator_trait< Op, Expr<A>, B > {
00313 private:
00314 typedef typename Expr<A>::ArgType ArgType;
00315 typedef typename ToExprTrait<B, ArgType>::ToExprType ToExprType;
00316 typedef typename ConvTraits< Expr<A>, ToExprType >::ResultType ResultType;
00317 public:
00318 typedef ToExprType RToExpr;
00319 typedef BinOp< Expr<A>, Op<ResultType>, ToExprType > ReturnBaseType;
00320 typedef Expr< ReturnBaseType > ReturnType;
00321 };
00322
00323
00324
00326
00328
00329
00330 template< class A, class B >
00331 typename operator_trait< Expr<A>, Add, Expr<B> >::ReturnType
00332 operator+( const TExpr<A>& A, const TExpr<B>& B ) {
00333 typedef typename operator_trait< Expr<A>, Add, TExpr<B> >::ReturnBaseType ReturnBaseType;
00334 typedef typename operator_trait< Expr<A>, Add, TExpr<B> >::ReturnType ReturnType;
00335 return ReturnType( ReturnBaseType(A, B) );
00336 }
00337
00338 template< class A, class B >
00339 typename operator_trait< A, Add , Expr<B> >::ReturnType
00340 operator+( const A& A, const Expr<B>& B ) {
00341 typedef typename operator_trait< A, Add, Expr<B> >::LToExpr LToExpr;
00342 typedef typename operator_trait< A, Add, Expr<B> >::ReturnBaseType ReturnBaseType;
00343 typedef typename operator_trait< A, Add, Expr<B> >::ReturnType ReturnType;
00344 return ReturnType( ReturnBaseType(LToExpr(A), B) );
00345 }
00346
00347 template< class A, class B >
00348 typename operator_trait< Expr<A>, Add, B >::ReturnType
00349 operator+( const Expr<A>& A, const B& B ) {
00350 typedef typename operator_trait< Expr<A>, Add, B >::RToExpr RToExpr;
00351 typedef typename operator_trait< Expr<A>, Add, B >::ReturnBaseType ReturnBaseType;
00352 typedef typename operator_trait< Expr<A>, Add, B >::ReturnType ReturnType;
00353 return ReturnType( ReturnBaseType(A, RToExpr(B)) );
00354 }
00355
00356
00357
00358 template< class A, class B >
00359 typename operator_trait< Expr<A>, Mul, Expr<B> >::ReturnType
00360 operator*( const Expr<A>& A, const Expr<B>& B ) {
00361 typedef typename operator_trait< Expr<A>, Mul, Expr<B> >::ReturnBaseType ReturnBaseType;
00362 typedef typename operator_trait< Expr<A>, Mul, Expr<B> >::ReturnType ReturnType;
00363 return ReturnType( ReturnBaseType(A, B) );
00364 }
00365
00366 template< class A, class B >
00367 typename operator_trait< A, Mul, Expr<B> >::ReturnType
00368 operator*( const A& A, const Expr<B>& B ) {
00369 typedef typename operator_trait< A, Mul, Expr<B> >::LToExpr LToExpr;
00370 typedef typename operator_trait< A, Mul, Expr<B> >::ReturnBaseType ReturnBaseType;
00371 typedef typename operator_trait< A, Mul, Expr<B> >::ReturnType ReturnType;
00372 return ReturnType( ReturnBaseType(LToExpr(A), B) );
00373 }
00374
00375 template< class A, class B >
00376 typename operator_trait< Expr<A>, Mul, B >::ReturnType
00377 operator*( const Expr<A>& A, const B& B ){
00378 typedef typename operator_trait< Expr<A>, Mul, B >::RToExpr RToExpr;
00379 typedef typename operator_trait< Expr<A>, Mul, B >::ReturnBaseType ReturnBaseType;
00380 typedef typename operator_trait< Expr<A>, Mul, B >::ReturnType ReturnType;
00381 return ReturnType( ReturnBaseType(A, RToExpr(B)) );
00382 }
00383
00384
00385
00386 template< class A, class B >
00387 typename operator_trait< Expr<A>, Div, Expr<B> >::ReturnType
00388 operator/( const Expr<A>& A, const Expr<B>& B ) {
00389 typedef typename operator_trait< Expr<A>, Div, Expr<B> >::ReturnBaseType ReturnBaseType;
00390 typedef typename operator_trait< Expr<A>, Div, Expr<B> >::ReturnType ReturnType;
00391 return ReturnType( ReturnBaseType(A, B) );
00392 }
00393
00394 template< class A, class B >
00395 typename operator_trait< A , Div, Expr<B> >::ReturnType
00396 operator/( const A& A, const Expr<B>& B ) {
00397 typedef typename operator_trait< A, Div, Expr<B> >::LToExpr LToExpr;
00398 typedef typename operator_trait< A, Div, Expr<B> >::ReturnBaseType ReturnBaseType;
00399 typedef typename operator_trait< A, Div, Expr<B> >::ReturnType ReturnType;
00400 return ReturnType( ReturnBaseType(LToExpr(A), B) );
00401 }
00402
00403 template< class A, class B >
00404 typename operator_trait< Expr<A>, Div, B >::ReturnType
00405 operator/( const Expr<A>& A, const B& B ) {
00406 typedef typename operator_trait< Expr<A>, Div, B >::RToExpr RToExpr;
00407 typedef typename operator_trait< Expr<A>, Div, B >::ReturnBaseType ReturnBaseType;
00408 typedef typename operator_trait< Expr<A>, Div, B >::ReturnType ReturnType;
00409 return ReturnType( ReturnBaseType(A, RToExpr(B)) );
00410 }
00411
00412
00413
00414 template< class A, class B >
00415 typename operator_trait< Expr<A>, And, Expr<B> >::ReturnType
00416 operator&&( const Expr<A>& A, const Expr<B>& B )
00417 {
00418 typedef typename operator_trait< Expr<A>, And, Expr<B> >::ReturnBaseType ReturnBaseType;
00419 typedef typename operator_trait< Expr<A>, And, Expr<B> >::ReturnType ReturnType;
00420 return ReturnType( ReturnBaseType(A, B) );
00421 }
00422
00423
00424 template< class A, class B >
00425 typename operator_trait< A, And, Expr<B> >::ReturnType
00426 operator&&( const A& A, const Expr<B>& B ) {
00427 typedef typename operator_trait< A, And, Expr<B> >::LToExpr LToExpr;
00428 typedef typename operator_trait< A, And, Expr<B> >::ReturnBaseType ReturnBaseType;
00429 typedef typename operator_trait< A, And, Expr<B> >::ReturnType ReturnType;
00430 return ReturnType( ReturnBaseType(LToExpr(A), B) );
00431 }
00432
00433 template< class A, class B >
00434 typename operator_trait< Expr<A>, And, B >::ReturnType
00435 operator&&( const Expr<A>& A, const B& B ) {
00436 typedef typename operator_trait< Expr<A>, And, B >::RToExpr RToExpr;
00437 typedef typename operator_trait< Expr<A>, And, B >::ReturnBaseType ReturnBaseType;
00438 typedef typename operator_trait< Expr<A>, And, B >::ReturnType ReturnType;
00439 return ReturnType( ReturnBaseType(A, RToExpr(B)) );
00440 }
00441
00442
00443
00444 template< class A, class B >
00445 typename operator_trait< Expr<A>, Or, Expr<B> >::ReturnType
00446 operator||( const Expr<A>& A, const Expr<B>& B ) {
00447 typedef typename operator_trait< Expr<A>, Or, Expr<B> >::ReturnBaseType ReturnBaseType;
00448 typedef typename operator_trait< Expr<A>, Or, Expr<B> >::ReturnType ReturnType;
00449 return ReturnType( ReturnBaseType(A, B) );
00450 }
00451
00452 template< class A, class B >
00453 typename operator_trait< A, Or, Expr<B> >::ReturnType
00454 operator||( const A& A, const Expr<B>& B ) {
00455 typedef typename operator_trait< A, Or, Expr<B> >::LToExpr LToExpr;
00456 typedef typename operator_trait< A, Or, Expr<B> >::ReturnBaseType ReturnBaseType;
00457 typedef typename operator_trait< A, Or, Expr<B> >::ReturnType ReturnType;
00458 return ReturnType( ReturnBaseType(LToExpr(A), B) );
00459 }
00460
00461 template< class A, class B >
00462 typename operator_trait< Expr<A>, Or, B >::ReturnType
00463 operator||( const Expr<A>& A, const B& B ) {
00464 typedef typename operator_trait< Expr<A>, Or, B >::RToExpr RToExpr;
00465 typedef typename operator_trait< Expr<A>, Or, B >::ReturnBaseType ReturnBaseType;
00466 typedef typename operator_trait< Expr<A>, Or, B >::ReturnType ReturnType;
00467 return ReturnType( ReturnBaseType(A, RToExpr(B)) );
00468 }
00469
00470
00471
00472 template< class A, class B >
00473 typename operator_trait< Expr<A>, Less, Expr<B> >::ReturnType
00474 operator<( const Expr<A>& A, const Expr<B>& B ){
00475 typedef typename operator_trait< Expr<A>, Less, Expr<B> >::ReturnBaseType ReturnBaseType;
00476 typedef typename operator_trait< Expr<A>, Less, Expr<B> >::ReturnType ReturnType;
00477 return ReturnType( ReturnBaseType(A, B) );
00478 }
00479
00480 template< class A, class B >
00481 typename operator_trait< A , Less, TExpr<B> >::ReturnType
00482 operator<( const A& A, const Expr<B>& B ){
00483 typedef typename operator_trait< A, Less, TExpr<B> >::LToExpr LToExpr;
00484 typedef typename operator_trait< A, Less, TExpr<B> >::ReturnBaseType ReturnBaseType;
00485 typedef typename operator_trait< A, Less, TExpr<B> >::ReturnType ReturnType;
00486 return ReturnType( ReturnBaseType(LToExpr(A), B) );
00487 }
00488
00489 template< class A, class B >
00490 typename operator_trait< Expr<A>, Less, B >::ReturnType
00491 operator<( const Expr<A>& A, const B& B ){
00492 typedef typename operator_trait< TLt, TExpr<A>, B >::RToExpr RToExpr;
00493 typedef typename operator_trait< TLt, TExpr<A>, B >::ReturnBaseType ReturnBaseType;
00494 typedef typename operator_trait< TLt, TExpr<A>, B >::ReturnType ReturnType;
00495 return ReturnType( ReturnBaseType(A, RToExpr(B)) );
00496 }
00497
00498
00499
00500 template< class A, class B >
00501 typename operator_trait< Expr<A>, LessEqual, Expr<B> >::ReturnType
00502 operator<=( const Expr<A>& A, const Expr<B>& B ) {
00503 typedef typename operator_trait< Expr<A>, LessEqual, Expr<B> >::ReturnBaseType ReturnBaseType;
00504 typedef typename operator_trait< Expr<A>, LessEqual, Expr<B> >::ReturnType ReturnType;
00505 return ReturnType( ReturnBaseType(A, B) );
00506 }
00507
00508 template< class A, class B >
00509 typename operator_trait< A, LessEqual, Expr<B> >::ReturnType
00510 operator<=( const A& A, const Expr<B>& B ) {
00512 typedef typename operator_trait< A, LessEqual, Expr<B> >::LToExpr LToExpr;
00513 typedef typename operator_trait< A, LessEqual, Expr<B> >::ReturnBaseType ReturnBaseType;
00514 typedef typename operator_trait< A, LessEqual,Expr<B> >::ReturnType ReturnType;
00515 return ReturnType( ReturnBaseType(LToExpr(A), B) );
00516 }
00517
00518 template< class A, class B >
00519 typename operator_trait< Expr<A>, LessEqual, B >::ReturnType
00520 operator<=( const Expr<A>& A, const B& B ) {
00521 typedef typename operator_trait< Expr<A>, LessEqual, B >::RToExpr RToExpr;
00522 typedef typename operator_trait< Expr<A>, LessEqual, B >::ReturnBaseType ReturnBaseType;
00523 typedef typename operator_trait< Expr<A>, LessEqual, B >::ReturnType ReturnType;
00524 return ReturnType( ReturnBaseType(A, RToExpr(B)) );
00525 }
00526
00527
00528
00529 template< class A, class B >
00530 typename operator_trait< Expr<A>, More, Expr<B> >::ReturnType
00531 operator>( const Expr<A>& A, const Expr<B>& B ) {
00532 typedef typename operator_trait< Expr<A>, More, Expr<B> >::ReturnBaseType ReturnBaseType;
00533 typedef typename operator_trait< Expr<A>, More, Expr<B> >::ReturnType ReturnType;
00534 return ReturnType( ReturnBaseType(A, B) );
00535 }
00536
00537 template< class A, class B >
00538 typename operator_trait< A, More, Expr<B> >::ReturnType
00539 operator>( const A& A, const Expr<B>& B ) {
00540 typedef typename operator_trait< A, More, Expr<B> >::LToExpr LToExpr;
00541 typedef typename operator_trait< A, More, Expr<B> >::ReturnBaseType ReturnBaseType;
00542 typedef typename operator_trait< A, More, Expr<B> >::ReturnType ReturnType;
00543 return ReturnType( ReturnBaseType(LToExpr(A), B) );
00544 }
00545
00546 template< class A, class B >
00547 typename operator_trait< Expr<A>, More, B >::ReturnType
00548 operator>( const Expr<A>& A, const B& B ) {
00549 typedef typename operator_trait< Expr<A>, More, B >::RToExpr RToExpr;
00550 typedef typename operator_trait< Expr<A>, More, B >::ReturnBaseType ReturnBaseType;
00551 typedef typename operator_trait< Expr<A>, More, B >::ReturnType ReturnType;
00552 return ReturnType( ReturnBaseType(A, RToExpr(B)) );
00553 }
00554
00555
00556
00557 template< class A, class B >
00558 typename operator_trait< Expr<A>, MoreEqual, TExpr<B> >::ReturnType
00559 operator>=( const Expr<A>& A, const Expr<B>& B ) {
00560 typedef typename operator_trait< Expr<A>, MoreEqual, Expr<B> >::ReturnBaseType ReturnBaseType;
00561 typedef typename operator_trait< Expr<A>, MoreEqual, Expr<B> >::ReturnType ReturnType;
00562 return ReturnType( ReturnBaseType(A, B) );
00563 }
00564
00565 template< class A, class B >
00566 typename operator_trait< A , MoreEqual, TExpr<B> >::ReturnType
00567 operator>=( const A& A, const Expr<B>& B ) {
00568 typedef typename operator_trait< A, MoreEqual, Expr<B> >::LToExpr LToExpr;
00569 typedef typename operator_trait< A, MoreEqual, Expr<B> >::ReturnBaseType ReturnBaseType;
00570 typedef typename operator_trait< A, MoreEqual, Expr<B> >::ReturnType ReturnType;
00571 return ReturnType( ReturnBaseType(LToExpr(A), B) );
00572 }
00573
00574 template< class A, class B >
00575 typename operator_trait< Expr<A>, MoreEqual, B >::ReturnType
00576 operator>=( const Expr<A>& A, const B& B ) {
00577 typedef typename operator_trait< Expr<A>, MoreEqual, B >::RToExpr RToExpr;
00578 typedef typename operator_trait< Expr<A>, MoreEqual, B >::ReturnBaseType ReturnBaseType;
00579 typedef typename operator_trait< Expr<A>, MoreEqual, B >::ReturnType ReturnType;
00580 return ReturnType( ReturnBaseType(A, RToExpr(B)) );
00581 }
00582
00583
00584
00585
00586 template< class A, class B >
00587 typename operator_trait< Expr<A>, Equal, Expr<B> >::ReturnType
00588 operator==( const Expr<A>& A, const Expr<B>& B ) {
00589 typedef typename operator_trait< Expr<A>, Equal, Expr<B> >::ReturnBaseType ReturnBaseType;
00590 typedef typename operator_trait< Expr<A>, Equal, Expr<B> >::ReturnType ReturnType;
00591 return ReturnType( ReturnBaseType(A, B) );
00592 }
00593
00594 template< class A, class B >
00595 typename operator_trait< A , Equal, Expr<B> >::ReturnType
00596 operator==( const A& A, const Expr<B>& B ) {
00597 typedef typename operator_trait< A, Equal, Expr<B> >::LToExpr LToExpr;
00598 typedef typename operator_trait< A, Equal, Expr<B> >::ReturnBaseType ReturnBaseType;
00599 typedef typename operator_trait< A, Equal, Expr<B> >::ReturnType ReturnType;
00600 return ReturnType( ReturnBaseType(LToExpr(A), B) );
00601 }
00602
00603 template< class A, class B >
00604 typename operator_trait< Expr<A>, Equal, B >::ReturnType
00605 operator==( const Expr<A>& A, const B& B ) {
00606 typedef typename operator_trait< Expr<A>, Equal, B >::RToExpr RToExpr;
00607 typedef typename operator_trait< Expr<A>, Equal, B >::ReturnBaseType ReturnBaseType;
00608 typedef typename operator_trait< Expr<A>, Equal, B >::ReturnType ReturnType;
00609 return ReturnType( ReturnBaseType(A, RToExpr(B)) );
00610 }
00611
00612
00613 }
00614
00615 #endif