BOSS 7.0.7
BESIII Offline Software System
Loading...
Searching...
No Matches
DCSimpleSelector.h
Go to the documentation of this file.
1#ifndef DCHAIN_DCSIMPLESELECTOR_H
2#define DCHAIN_DCSIMPLESELECTOR_H
3// -*- C++ -*-
4//
5// Package: DChain
6// Module: DCSimpleSelector
7//
8/**\class DCSimpleSelector DCSimpleSelector.h DChain/DCSimpleSelector.h
9
10 Description: Create a DCSelectionFunction from simple parts
11
12 Usage:
13 To make use of this ability, you must place your selection functions in
14 the DChain namespace (avoids having && and || override builtin version)
15
16 namespace DChain {
17 class Selector1 ...
18 class Selector2 ...
19 class Selector3 ...
20 }
21 using DChain::Selector1;
22 using DChain::Selector2;
23
24 Then in our code
25 Selector1 s1; Selector2 s2; Selector3 s3;
26 DCSimpleSelector<Decay> jointSelector = s1 && s2 || s3;
27 DCDecayList<Decay> myStuff( jointSelector);
28*/
29//
30// Author: Chris D Jones
31// Created: Tue Sep 30 15:41:54 EDT 2003
32// $Id: DCSimpleSelector.h,v 1.1.1.1 2009/03/03 06:06:56 maqm Exp $
33//
34// Revision history
35//
36// $Log: DCSimpleSelector.h,v $
37// Revision 1.1.1.1 2009/03/03 06:06:56 maqm
38// first import of DecayChain
39//
40// Revision 1.4 2006/01/11 20:28:13 cdj
41// massive class renaming, addition of [] for selection and unit tests
42//
43// Revision 1.3 2003/10/27 22:59:25 cdj
44// added operator= to DCSimpleSelector
45//
46// Revision 1.2 2003/10/12 23:16:44 cdj
47// simplified the use of the simple selector
48//
49// Revision 1.1 2003/10/02 23:55:00 cdj
50// changed compound selection to be simple selector (including expression templates)
51//
52// Revision 1.1 2003/10/01 23:45:17 cdj
53// added compound selection function
54//
55
56// system include files
57
58// user include files
60
61// forward declarations
62namespace DChain {
63// base class for operation used to combine Selectors
64 template<class Arg>
65 class MethodBase {
66 public:
67 typedef Arg arg_type;
68 virtual bool select(Arg&) = 0;
69 virtual MethodBase* clone() const = 0;
70 };
71
72 //combine Selectors using logical AND
73 template<class LHS, class RHS, class Arg>
74 class MethodAnd : public MethodBase<Arg> {
75 public:
76 typedef Arg arg_type;
77
78 MethodAnd( const LHS& iLHS, const RHS& iRHS) :
79 m_lhs(iLHS),
80 m_rhs(iRHS) {
81 }
82
84
85 bool select(Arg& iArg) {
86 return m_lhs.select(iArg) && m_rhs.select(iArg);
87 }
88
90 return new MethodAnd<LHS,RHS,Arg>( *this );
91 }
92 private:
93 LHS m_lhs;
94 RHS m_rhs;
95 };
96
97 //combine Selectors using logical OR
98 template<class LHS, class RHS, class Arg>
99 class MethodOr : public MethodBase<Arg> {
100 public:
101 typedef Arg arg_type;
102
103 MethodOr( const LHS& iLHS, const RHS& iRHS) :
104 m_lhs(iLHS),
105 m_rhs(iRHS) {
106 }
108
109 bool select(Arg& iArg) {
110 return m_lhs.select(iArg) || m_rhs.select(iArg);
111 }
112
114 return new MethodOr<LHS,RHS,Arg>( *this );
115 }
116 private:
117 LHS m_lhs;
118 RHS m_rhs;
119 };
120
121 //Adapter for a Selector so it can be used as a Method
122 template<class Arg>
123 class MethodHolder : public MethodBase<Arg> {
124 public:
125 typedef Arg arg_type;
126
128 m_selector(iSelector) {}
130 return new MethodHolder<Arg>(*this);
131 }
132 bool select(Arg& iArg ) {
133 return m_selector( iArg);
134 }
135 private:
136 DCSelectionFunction<Arg>& m_selector;
137 };
138
139 //Create a test to see if a class inherits from DCSelectionFunction
140 // this is needed to determine if we need to create a
141 // MethodHolder
142
143 //These classes are used only for the return value of our test
144 struct PassTest {
145 char m_size[12];
146 };
147 struct FailTest {
148 char m_size[1];
149 };
150
151 //This function will be used if our class does inherits
152 template <class Arg> PassTest testForHolder(const DCSelectionFunction<Arg>* );
153 //This function will be used if our class doesn't inherit
155
156 //This class actually determines if we should use a MethodHolder
157 // for the class T
158 template <class T, bool> class UseHolder {
159 public:
160 typedef T Method;
161 };
162 template <class T> class UseHolder<T,false> {
163 public:
164 typedef T Method;
165 };
166 template <class T> class UseHolder<T,true> {
167 public:
169 typedef typename Method::arg_type arg_type;
170 };
171 //End code needed for test
172
173
174 //Determine exactly what MethodType to use for class T
175 // mostly used to make using UseHolder easier
176 template <class T> class MethodType {
177 public:
178 //static const T& make();
179 typedef typename UseHolder<T, (sizeof(testForHolder((T*)0))==sizeof(PassTest) ) >::Method Method;
180 typedef typename Method::arg_type arg_type;
181 };
182
183
184 //If the two arguments are not identical, pick the one that is more specialized (I.e. if B inherits from A, pick B)
185
186 //Chooses which of the first two template based on the third argument
187 template<class T1, class T2, bool> struct ChooseArg {
188 typedef T1 arg_type;
189 };
190 template<class T1, class T2> struct ChooseArg<T1,T2,false> {
191 typedef T2 arg_type;
192 };
193
194 //This class needed to get around bug in g++
195 template<class T1, class T2> struct PickArgTester {
196 static PassTest inheritsFrom(const T2*);
198 };
199
200 template<class T1, class T2> class PickArg {
201 public:
202 static PassTest inheritsFrom(const T2*);
204
205 typedef typename ChooseArg<T1, T2, (
208 };
209
210 //overload && to allow nice syntax for constructing a DCSimpleSelector
211 //This type is only needed to work around a Solaris 2.8 CC bug
212 // If the arg_type of LHS and RHS do not agree, pick the most
213 // specialized one
214 template< class LHS, class RHS> struct AndOpReturn {
218 typename MethodType<RHS>::arg_type>::arg_type > Return;
219 };
220
221 template<class LHS, class RHS>
222 inline
224 operator&&(LHS& iLHS, RHS& iRHS) {
225 return
227 typename MethodType<LHS>::Method(iLHS),
228 typename MethodType<RHS>::Method(iRHS) );
229 }
230
231 template<class LHS, class RHS>
232 inline
234 operator&&(const LHS& iLHS, RHS& iRHS) {
235 return
237 typename MethodType<LHS>::Method(iLHS),
238 typename MethodType<RHS>::Method(iRHS) );
239 }
240
241 template<class LHS, class RHS>
242 inline
244 operator&&(const LHS& iLHS, const RHS& iRHS) {
245 return
247 typename MethodType<LHS>::Method(iLHS),
248 typename MethodType<RHS>::Method(iRHS) );
249 }
250
251 template< class LHS, class RHS> struct OrOpReturn {
255 typename MethodType<RHS>::arg_type>::arg_type > Return;
256 };
257
258 template<class LHS, class RHS>
259 inline
261 operator||(LHS& iLHS, RHS& iRHS) {
263 typename MethodType<LHS>::Method(iLHS),
264 typename MethodType<RHS>::Method(iRHS) );
265 }
266
267 template<class LHS, class RHS>
268 inline
270 operator||(const LHS& iLHS, RHS& iRHS) {
272 typename MethodType<LHS>::Method(iLHS),
273 typename MethodType<RHS>::Method(iRHS) );
274 }
275
276 template<class LHS, class RHS>
277 inline
279 operator||(const LHS& iLHS, const RHS& iRHS) {
281 typename MethodType<LHS>::Method(iLHS),
282 typename MethodType<RHS>::Method(iRHS) );
283 }
284
285 //Creates a Method that will allow you to call another MethodT that
286 // has a different but compatable Arg
287 template<class MethodT, class Arg> class MethodAdapter : public MethodBase<Arg> {
288 public:
289 MethodAdapter(const MethodT& iMethod ) :
290 m_method(iMethod) {}
291 bool select(Arg& iArg) {
292 return m_method.select(iArg);
293 }
294
296 return new MethodAdapter<MethodT,Arg>( *this );
297 }
298 private:
299 MethodT m_method;
300
301 };
302
303
304template<class Arg>
306{
307 // ---------- friend classes and functions ---------------
308
309 public:
310 // ---------- constants, enums and typedefs --------------
311
312 // ---------- Constructors and destructor ----------------
313 DCSimpleSelector() : m_method(0) {}
314 template<class T>
315 DCSimpleSelector(const T& iMethod ) :
316 m_method( new DChain::MethodAdapter<T,Arg>(iMethod) ) {}
317
319 m_method( iMethod.clone() ) {}
321 delete m_method;
322 }
323
324 // ---------- member functions ---------------------------
325 virtual bool operator()( Arg& iArg) {
326 if( 0 != m_method ) {
327 return m_method->select(iArg);
328 }
329 return true;
330 }
331
332 DCSimpleSelector( const DCSimpleSelector<Arg>& iCopy ) : m_method(0) {
333 if( 0 != iCopy.m_method) {
334 m_method = iCopy.m_method->clone();
335 }
336 }
337
339 DCSimpleSelector<Arg> temp(iRHS);
340 swap(temp);
341 return *this;
342 }
343private:
344 // ---------- Constructors and destructor ----------------
345
346 void swap( DCSimpleSelector<Arg>& iOther ) {
347 DChain::MethodBase<Arg>* temp = m_method;
348 m_method = iOther.m_method;
349 iOther.m_method = temp;
350 }
351 // ---------- assignment operator(s) ---------------------
352
353 // ---------- data members -------------------------------
354 DChain::MethodBase<Arg>* m_method;
355};
356
357}
359
360// inline function definitions
361
362// Uncomment the following lines, if your class is templated
363// and has an implementation file (in the Template directory)
364//#if defined(INCLUDE_TEMPLATE_DEFINITIONS)
365//# include "DChain/Template/DCSimpleSelector.cc"
366//#endif
367
368#endif /* DCHAIN_DCSIMPLESELECTOR_H */
const DCSimpleSelector< Arg > & operator=(const DCSimpleSelector< Arg > &iRHS)
virtual bool operator()(Arg &iArg)
DCSimpleSelector(const DChain::MethodBase< Arg > &iMethod)
DCSimpleSelector(const DCSimpleSelector< Arg > &iCopy)
DCSimpleSelector(const T &iMethod)
bool select(Arg &iArg)
MethodAdapter(const MethodT &iMethod)
MethodBase< Arg > * clone() const
bool select(Arg &iArg)
MethodAnd(const LHS &iLHS, const RHS &iRHS)
MethodBase< Arg > * clone() const
virtual bool select(Arg &)=0
virtual MethodBase * clone() const =0
bool select(Arg &iArg)
MethodHolder(DCSelectionFunction< Arg > &iSelector)
MethodBase< Arg > * clone() const
bool select(Arg &iArg)
MethodOr(const LHS &iLHS, const RHS &iRHS)
MethodBase< Arg > * clone() const
UseHolder< T,(sizeof(testForHolder((T *) 0))==sizeof(PassTest))>::Method Method
Method::arg_type arg_type
ChooseArg< T1, T2,(sizeof(PickArgTester< T1, T2 >::inheritsFrom((T1 *) 0))==sizeof(PassTest))>::arg_type arg_type
static PassTest inheritsFrom(const T2 *)
static FailTest inheritsFrom(...)
MethodHolder< typename T::arg_type > Method
OrOpReturn< LHS, RHS >::Return operator||(LHS &iLHS, RHS &iRHS)
PassTest testForHolder(const DCSelectionFunction< Arg > *)
AndOpReturn< LHS, RHS >::Return operator&&(LHS &iLHS, RHS &iRHS)
MethodAnd< typename MethodType< LHS >::Method, typename MethodType< RHS >::Method, typename PickArg< typename MethodType< LHS >::arg_type, typename MethodType< RHS >::arg_type >::arg_type > Return
MethodOr< typename MethodType< LHS >::Method, typename MethodType< RHS >::Method, typename PickArg< typename MethodType< LHS >::arg_type, typename MethodType< RHS >::arg_type >::arg_type > Return
static PassTest inheritsFrom(const T2 *)
static FailTest inheritsFrom(...)