/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Event/DecayChain/DecayChain-00-00-03-slc6tag/DecayChain/Function/DCSimpleSelector.h

Go to the documentation of this file.
00001 #ifndef DCHAIN_DCSIMPLESELECTOR_H
00002 #define DCHAIN_DCSIMPLESELECTOR_H
00003 // -*- C++ -*-
00004 //
00005 // Package:     DChain
00006 // Module:      DCSimpleSelector
00007 // 
00029 //
00030 // Author:      Chris D Jones
00031 // Created:     Tue Sep 30 15:41:54 EDT 2003
00032 // $Id: DCSimpleSelector.h,v 1.1.1.1 2009/03/03 06:06:56 maqm Exp $
00033 //
00034 // Revision history
00035 //
00036 // $Log: DCSimpleSelector.h,v $
00037 // Revision 1.1.1.1  2009/03/03 06:06:56  maqm
00038 // first import of DecayChain
00039 //
00040 // Revision 1.4  2006/01/11 20:28:13  cdj
00041 // massive class renaming, addition of [] for selection and unit tests
00042 //
00043 // Revision 1.3  2003/10/27 22:59:25  cdj
00044 // added operator= to DCSimpleSelector
00045 //
00046 // Revision 1.2  2003/10/12 23:16:44  cdj
00047 // simplified the use of the simple selector
00048 //
00049 // Revision 1.1  2003/10/02 23:55:00  cdj
00050 // changed compound selection to be simple selector (including expression templates)
00051 //
00052 // Revision 1.1  2003/10/01 23:45:17  cdj
00053 // added compound selection function
00054 //
00055 
00056 // system include files
00057 
00058 // user include files
00059 #include "DecayChain/Function/DCSelectionFunction.h"
00060 
00061 // forward declarations
00062 namespace DChain {
00063 // base class for operation used to combine Selectors
00064    template<class Arg>
00065    class MethodBase {
00066       public:
00067          typedef Arg arg_type;
00068          virtual bool select(Arg&) = 0;
00069          virtual MethodBase* clone() const = 0;
00070    };
00071 
00072    //combine Selectors using logical AND
00073    template<class LHS, class RHS, class Arg>
00074    class MethodAnd : public MethodBase<Arg> {
00075       public:
00076          typedef Arg arg_type;
00077 
00078          MethodAnd( const LHS& iLHS, const RHS& iRHS) :
00079          m_lhs(iLHS),
00080          m_rhs(iRHS) {
00081          }
00082 
00083          MethodAnd();
00084 
00085          bool select(Arg& iArg) {
00086             return m_lhs.select(iArg) && m_rhs.select(iArg);
00087          }
00088 
00089          MethodBase<Arg>* clone() const {
00090             return new MethodAnd<LHS,RHS,Arg>( *this );
00091          }
00092       private:
00093          LHS m_lhs;
00094          RHS m_rhs;
00095    };
00096 
00097    //combine Selectors using logical OR
00098    template<class LHS, class RHS, class Arg>
00099    class MethodOr : public MethodBase<Arg> {
00100       public:
00101          typedef Arg arg_type;
00102 
00103          MethodOr( const LHS& iLHS, const RHS& iRHS) :
00104          m_lhs(iLHS),
00105          m_rhs(iRHS) {
00106          }
00107          MethodOr();
00108 
00109          bool select(Arg& iArg) {
00110             return m_lhs.select(iArg) || m_rhs.select(iArg);
00111          }
00112 
00113          MethodBase<Arg>* clone() const {
00114             return new MethodOr<LHS,RHS,Arg>( *this );
00115          }
00116       private:
00117          LHS m_lhs;
00118          RHS m_rhs;
00119    };
00120 
00121    //Adapter for a Selector so it can be used as a Method
00122    template<class Arg>
00123    class MethodHolder : public MethodBase<Arg> {
00124       public:
00125          typedef Arg arg_type;
00126 
00127          MethodHolder(DCSelectionFunction<Arg>& iSelector) :
00128             m_selector(iSelector) {}
00129          MethodBase<Arg>* clone() const {
00130             return new MethodHolder<Arg>(*this);
00131          }
00132          bool select(Arg& iArg ) {
00133             return m_selector( iArg);
00134          }
00135       private:
00136          DCSelectionFunction<Arg>& m_selector;
00137    };
00138 
00139    //Create a test to see if a class inherits from DCSelectionFunction
00140    // this is needed to determine if we need to create a
00141    // MethodHolder
00142 
00143    //These classes are used only for the return value of our test
00144    struct PassTest {
00145          char m_size[12];
00146    };
00147    struct FailTest {
00148          char m_size[1];
00149    };
00150 
00151    //This function will be used if our class does inherits
00152    template <class Arg> PassTest testForHolder(const DCSelectionFunction<Arg>* );
00153    //This function will be used if our class doesn't inherit
00154    FailTest testForHolder(...);
00155 
00156    //This class actually determines if we should use a MethodHolder
00157    // for the class T
00158    template <class T, bool> class UseHolder {
00159       public:
00160          typedef T Method;
00161    };
00162    template <class T> class UseHolder<T,false> {
00163       public: 
00164          typedef T Method;
00165    }; 
00166    template <class T> class UseHolder<T,true> {
00167       public:
00168          typedef MethodHolder<typename T::arg_type> Method;
00169          typedef typename Method::arg_type arg_type;
00170    };
00171    //End code needed for test
00172 
00173 
00174    //Determine exactly what MethodType to use for class T
00175    //  mostly used to make using UseHolder easier
00176    template <class T> class MethodType {
00177       public:
00178          //static const T& make();
00179          typedef typename UseHolder<T, (sizeof(testForHolder((T*)0))==sizeof(PassTest) ) >::Method Method;
00180          typedef typename Method::arg_type arg_type;
00181    };
00182 
00183 
00184    //If the two arguments are not identical, pick the one that is more specialized (I.e. if B inherits from A, pick B)
00185 
00186    //Chooses which of the first two template based on the third argument
00187    template<class T1, class T2, bool> struct ChooseArg {
00188          typedef T1 arg_type;
00189    };
00190    template<class T1, class T2> struct ChooseArg<T1,T2,false> {
00191          typedef T2 arg_type;
00192    };
00193 
00194    //This class needed to get around bug in g++
00195    template<class T1, class T2> struct PickArgTester {
00196          static PassTest inheritsFrom(const T2*);
00197          static FailTest inheritsFrom(...);
00198    };
00199 
00200    template<class T1, class T2> class PickArg {
00201       public:
00202          static PassTest inheritsFrom(const T2*);
00203          static FailTest inheritsFrom(...);
00204 
00205          typedef typename ChooseArg<T1, T2, (
00206             sizeof(PickArgTester<T1,T2>::inheritsFrom((T1*)0))
00207             ==sizeof(PassTest) )  >::arg_type arg_type;
00208    };
00209    
00210    //overload && to allow nice syntax for constructing a DCSimpleSelector
00211    //This type is only needed to work around a Solaris 2.8 CC bug
00212    //  If the arg_type of LHS and RHS do not agree, pick the most 
00213    //  specialized one
00214    template< class LHS, class RHS> struct AndOpReturn {
00215          typedef MethodAnd<typename MethodType<LHS>::Method,
00216              typename MethodType<RHS>::Method,
00217              typename PickArg< typename MethodType<LHS>::arg_type,
00218                                typename MethodType<RHS>::arg_type>::arg_type > Return;
00219    };
00220 
00221    template<class LHS, class RHS>
00222       inline
00223       typename AndOpReturn<LHS,RHS>::Return
00224       operator&&(LHS& iLHS, RHS& iRHS) {
00225       return
00226          AndOpReturn<LHS,RHS>::Return(
00227          typename MethodType<LHS>::Method(iLHS),
00228          typename MethodType<RHS>::Method(iRHS) );
00229    }
00230 
00231    template<class LHS, class RHS>
00232       inline
00233       typename AndOpReturn<LHS,RHS>::Return
00234       operator&&(const LHS& iLHS, RHS& iRHS) {
00235       return 
00236          AndOpReturn<LHS,RHS>::Return( 
00237             typename MethodType<LHS>::Method(iLHS),
00238             typename MethodType<RHS>::Method(iRHS) );
00239    }
00240 
00241    template<class LHS, class RHS>
00242       inline
00243       typename AndOpReturn<LHS,RHS>::Return
00244       operator&&(const LHS& iLHS, const RHS& iRHS) {
00245       return 
00246          AndOpReturn<LHS,RHS>::Return( 
00247             typename MethodType<LHS>::Method(iLHS),
00248             typename MethodType<RHS>::Method(iRHS) );
00249    }
00250 
00251    template< class LHS, class RHS> struct OrOpReturn {
00252          typedef MethodOr<typename MethodType<LHS>::Method,
00253                           typename MethodType<RHS>::Method,
00254              typename PickArg< typename MethodType<LHS>::arg_type,
00255             typename MethodType<RHS>::arg_type>::arg_type > Return;
00256    };
00257 
00258    template<class LHS, class RHS>
00259       inline
00260       typename OrOpReturn<LHS,RHS>::Return
00261    operator||(LHS& iLHS, RHS& iRHS) {
00262       return OrOpReturn<LHS,RHS>::Return ( 
00263             typename MethodType<LHS>::Method(iLHS),
00264             typename MethodType<RHS>::Method(iRHS) );
00265    }
00266 
00267    template<class LHS, class RHS>
00268       inline
00269       typename OrOpReturn<LHS,RHS>::Return
00270    operator||(const LHS& iLHS, RHS& iRHS) {
00271       return OrOpReturn<LHS,RHS>::Return ( 
00272             typename MethodType<LHS>::Method(iLHS),
00273             typename MethodType<RHS>::Method(iRHS) );
00274    }
00275 
00276    template<class LHS, class RHS>
00277       inline
00278       typename OrOpReturn<LHS,RHS>::Return
00279    operator||(const LHS& iLHS, const RHS& iRHS) {
00280       return OrOpReturn<LHS,RHS>::Return ( 
00281             typename MethodType<LHS>::Method(iLHS),
00282             typename MethodType<RHS>::Method(iRHS) );
00283    }
00284 
00285    //Creates a Method that will allow you to call another MethodT that
00286    // has a different but compatable Arg
00287    template<class MethodT, class Arg> class MethodAdapter : public MethodBase<Arg> {
00288       public:
00289          MethodAdapter(const MethodT& iMethod ) :
00290             m_method(iMethod) {}
00291          bool select(Arg& iArg) {
00292             return m_method.select(iArg);
00293          }
00294 
00295          MethodBase<Arg>* clone() const {
00296             return new MethodAdapter<MethodT,Arg>( *this );
00297          }
00298       private:
00299          MethodT m_method;
00300 
00301    };
00302 
00303 
00304 template<class Arg>
00305 class DCSimpleSelector : public DCSelectionFunction<Arg>
00306 {
00307       // ---------- friend classes and functions ---------------
00308 
00309    public:
00310       // ---------- constants, enums and typedefs --------------
00311 
00312       // ---------- Constructors and destructor ----------------
00313       DCSimpleSelector() : m_method(0) {}
00314       template<class T>
00315       DCSimpleSelector(const T& iMethod ) :
00316          m_method( new DChain::MethodAdapter<T,Arg>(iMethod) ) {}
00317            
00318       DCSimpleSelector(const DChain::MethodBase<Arg>& iMethod ) :
00319          m_method( iMethod.clone() ) {}
00320       virtual ~DCSimpleSelector() {
00321          delete m_method;
00322       }
00323 
00324       // ---------- member functions ---------------------------
00325       virtual bool operator()( Arg& iArg) {
00326          if( 0 != m_method ) {
00327             return m_method->select(iArg);
00328          }
00329          return true;
00330       }
00331 
00332       DCSimpleSelector( const DCSimpleSelector<Arg>& iCopy ) : m_method(0) {
00333          if( 0 != iCopy.m_method) {
00334             m_method = iCopy.m_method->clone();
00335          }
00336       }
00337             
00338       const DCSimpleSelector<Arg>& operator=( const DCSimpleSelector<Arg>& iRHS) {
00339          DCSimpleSelector<Arg> temp(iRHS);
00340          swap(temp);
00341          return *this;
00342       }
00343 private:
00344       // ---------- Constructors and destructor ----------------
00345 
00346       void swap( DCSimpleSelector<Arg>& iOther ) {
00347          DChain::MethodBase<Arg>* temp = m_method;
00348          m_method = iOther.m_method;
00349          iOther.m_method = temp;
00350       }
00351       // ---------- assignment operator(s) ---------------------
00352 
00353       // ---------- data members -------------------------------
00354       DChain::MethodBase<Arg>* m_method;
00355 };
00356 
00357 }
00358 using DChain::DCSimpleSelector;
00359 
00360 // inline function definitions
00361 
00362 // Uncomment the following lines, if your class is templated 
00363 // and has an implementation file (in the Template directory)
00364 //#if defined(INCLUDE_TEMPLATE_DEFINITIONS)
00365 //# include "DChain/Template/DCSimpleSelector.cc"
00366 //#endif
00367 
00368 #endif /* DCHAIN_DCSIMPLESELECTOR_H */

Generated on Tue Nov 29 22:58:22 2016 for BOSS_7.0.2 by  doxygen 1.4.7