CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10_patch1/src/PhysicsTools/SelectorUtils/interface/Expressions.h

Go to the documentation of this file.
00001 #ifndef SelectorUtils_Expressions_h
00002 #define SelectorUtils_Expressions_h
00003 
00004 // expression templates
00005 // Benedikt Hegner, DESY
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;  //@TODO: add exception handling in case of forgotten expression definition
00028 };
00029 
00030 
00031 //the implementation part
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 //hold expression literals
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 // operators //
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 // boolean operators //
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 // Comparison operators //
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 // conv traits for basic types //
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 // conversion traits for more advanced types //
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 // operators for expressions //
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 // Expression templates //
00328 
00329 // operator+ 
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 // operator* 
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 // operator/ 
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 // operator&& 
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 // operator|| 
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 // operator< 
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 // operator<= 
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 // operator> 
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 // operator>= 
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 //------------------------- operator== --------------------------------------------------
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 }// namespace
00614 
00615 #endif