00001 #ifndef DCHAIN_DCSIMPLESELECTOR_H
00002 #define DCHAIN_DCSIMPLESELECTOR_H
00003
00004
00005
00006
00007
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include "DecayChain/Function/DCSelectionFunction.h"
00060
00061
00062 namespace DChain {
00063
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
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
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
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
00140
00141
00142
00143
00144 struct PassTest {
00145 char m_size[12];
00146 };
00147 struct FailTest {
00148 char m_size[1];
00149 };
00150
00151
00152 template <class Arg> PassTest testForHolder(const DCSelectionFunction<Arg>* );
00153
00154 FailTest testForHolder(...);
00155
00156
00157
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
00172
00173
00174
00175
00176 template <class T> class MethodType {
00177 public:
00178
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
00185
00186
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
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
00211
00212
00213
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
00286
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
00308
00309 public:
00310
00311
00312
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
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
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
00352
00353
00354 DChain::MethodBase<Arg>* m_method;
00355 };
00356
00357 }
00358 using DChain::DCSimpleSelector;
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 #endif