BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
Event/DecayChain/include/DecayChain/Function/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
59#include "DecayChain/Function/DCSelectionFunction.h"
60
61// forward declarations
62namespace DChain {
63 // base class for operation used to combine Selectors
64 template <class Arg> class MethodBase {
65 public:
66 typedef Arg arg_type;
67 virtual bool select( Arg& ) = 0;
68 virtual MethodBase* clone() const = 0;
69 };
70
71 // combine Selectors using logical AND
72 template <class LHS, class RHS, class Arg> class MethodAnd : public MethodBase<Arg> {
73 public:
74 typedef Arg arg_type;
75
76 MethodAnd( const LHS& iLHS, const RHS& iRHS ) : m_lhs( iLHS ), m_rhs( iRHS ) {}
77
79
80 bool select( Arg& iArg ) { return m_lhs.select( iArg ) && m_rhs.select( iArg ); }
81
82 MethodBase<Arg>* clone() const { return new MethodAnd<LHS, RHS, Arg>( *this ); }
83
84 private:
85 LHS m_lhs;
86 RHS m_rhs;
87 };
88
89 // combine Selectors using logical OR
90 template <class LHS, class RHS, class Arg> class MethodOr : public MethodBase<Arg> {
91 public:
92 typedef Arg arg_type;
93
94 MethodOr( const LHS& iLHS, const RHS& iRHS ) : m_lhs( iLHS ), m_rhs( iRHS ) {}
96
97 bool select( Arg& iArg ) { return m_lhs.select( iArg ) || m_rhs.select( iArg ); }
98
99 MethodBase<Arg>* clone() const { return new MethodOr<LHS, RHS, Arg>( *this ); }
100
101 private:
102 LHS m_lhs;
103 RHS m_rhs;
104 };
105
106 // Adapter for a Selector so it can be used as a Method
107 template <class Arg> class MethodHolder : public MethodBase<Arg> {
108 public:
109 typedef Arg arg_type;
110
111 MethodHolder( DCSelectionFunction<Arg>& iSelector ) : m_selector( iSelector ) {}
112 MethodBase<Arg>* clone() const { return new MethodHolder<Arg>( *this ); }
113 bool select( Arg& iArg ) { return m_selector( iArg ); }
114
115 private:
116 DCSelectionFunction<Arg>& m_selector;
117 };
118
119 // Create a test to see if a class inherits from DCSelectionFunction
120 // this is needed to determine if we need to create a
121 // MethodHolder
122
123 // These classes are used only for the return value of our test
124 struct PassTest {
125 char m_size[12];
126 };
127 struct FailTest {
128 char m_size[1];
129 };
130
131 // This function will be used if our class does inherits
132 template <class Arg> PassTest testForHolder( const DCSelectionFunction<Arg>* );
133 // This function will be used if our class doesn't inherit
135
136 // This class actually determines if we should use a MethodHolder
137 // for the class T
138 template <class T, bool> class UseHolder {
139 public:
140 typedef T Method;
141 };
142 template <class T> class UseHolder<T, false> {
143 public:
144 typedef T Method;
145 };
146 template <class T> class UseHolder<T, true> {
147 public:
149 typedef typename Method::arg_type arg_type;
150 };
151 // End code needed for test
152
153 // Determine exactly what MethodType to use for class T
154 // mostly used to make using UseHolder easier
155 template <class T> class MethodType {
156 public:
157 // static const T& make();
158 typedef typename UseHolder<T, ( sizeof( testForHolder( (T*)0 ) ) ==
160 typedef typename Method::arg_type arg_type;
161 };
162
163 // If the two arguments are not identical, pick the one that is more specialized (I.e. if B
164 // inherits from A, pick B)
165
166 // Chooses which of the first two template based on the third argument
167 template <class T1, class T2, bool> struct ChooseArg {
168 typedef T1 arg_type;
169 };
170 template <class T1, class T2> struct ChooseArg<T1, T2, false> {
171 typedef T2 arg_type;
172 };
173
174 // This class needed to get around bug in g++
175 template <class T1, class T2> struct PickArgTester {
176 static PassTest inheritsFrom( const T2* );
177 static FailTest inheritsFrom( ... );
178 };
179
180 template <class T1, class T2> class PickArg {
181 public:
182 static PassTest inheritsFrom( const T2* );
183 static FailTest inheritsFrom( ... );
184
185 typedef typename ChooseArg<T1, T2,
186 ( sizeof( PickArgTester<T1, T2>::inheritsFrom( (T1*)0 ) ) ==
188 };
189
190 // overload && to allow nice syntax for constructing a DCSimpleSelector
191 // This type is only needed to work around a Solaris 2.8 CC bug
192 // If the arg_type of LHS and RHS do not agree, pick the most
193 // specialized one
200
201 template <class LHS, class RHS>
202 inline typename AndOpReturn<LHS, RHS>::Return operator&&( LHS& iLHS, RHS& iRHS ) {
204 typename MethodType<RHS>::Method( iRHS ) );
205 }
206
207 template <class LHS, class RHS>
208 inline typename AndOpReturn<LHS, RHS>::Return operator&&( const LHS& iLHS, RHS& iRHS ) {
210 typename MethodType<RHS>::Method( iRHS ) );
211 }
212
213 template <class LHS, class RHS>
214 inline typename AndOpReturn<LHS, RHS>::Return operator&&( const LHS& iLHS,
215 const RHS& iRHS ) {
217 typename MethodType<RHS>::Method( iRHS ) );
218 }
219
226
227 template <class LHS, class RHS>
228 inline typename OrOpReturn<LHS, RHS>::Return operator||( LHS& iLHS, RHS& iRHS ) {
230 typename MethodType<RHS>::Method( iRHS ) );
231 }
232
233 template <class LHS, class RHS>
234 inline typename OrOpReturn<LHS, RHS>::Return operator||( const LHS& iLHS, RHS& iRHS ) {
236 typename MethodType<RHS>::Method( iRHS ) );
237 }
238
239 template <class LHS, class RHS>
240 inline typename OrOpReturn<LHS, RHS>::Return operator||( const LHS& iLHS, const RHS& iRHS ) {
242 typename MethodType<RHS>::Method( iRHS ) );
243 }
244
245 // Creates a Method that will allow you to call another MethodT that
246 // has a different but compatable Arg
247 template <class MethodT, class Arg> class MethodAdapter : public MethodBase<Arg> {
248 public:
249 MethodAdapter( const MethodT& iMethod ) : m_method( iMethod ) {}
250 bool select( Arg& iArg ) { return m_method.select( iArg ); }
251
252 MethodBase<Arg>* clone() const { return new MethodAdapter<MethodT, Arg>( *this ); }
253
254 private:
255 MethodT m_method;
256 };
257
258 template <class Arg> class DCSimpleSelector : public DCSelectionFunction<Arg> {
259 // ---------- friend classes and functions ---------------
260
261 public:
262 // ---------- constants, enums and typedefs --------------
263
264 // ---------- Constructors and destructor ----------------
265 DCSimpleSelector() : m_method( 0 ) {}
266 template <class T>
267 DCSimpleSelector( const T& iMethod )
268 : m_method( new DChain::MethodAdapter<T, Arg>( iMethod ) ) {}
269
270 DCSimpleSelector( const DChain::MethodBase<Arg>& iMethod ) : m_method( iMethod.clone() ) {}
271 virtual ~DCSimpleSelector() { delete m_method; }
272
273 // ---------- member functions ---------------------------
274 virtual bool operator()( Arg& iArg ) {
275 if ( 0 != m_method ) { return m_method->select( iArg ); }
276 return true;
277 }
278
279 DCSimpleSelector( const DCSimpleSelector<Arg>& iCopy ) : m_method( 0 ) {
280 if ( 0 != iCopy.m_method ) { m_method = iCopy.m_method->clone(); }
281 }
282
284 DCSimpleSelector<Arg> temp( iRHS );
285 swap( temp );
286 return *this;
287 }
288
289 private:
290 // ---------- Constructors and destructor ----------------
291
292 void swap( DCSimpleSelector<Arg>& iOther ) {
293 DChain::MethodBase<Arg>* temp = m_method;
294 m_method = iOther.m_method;
295 iOther.m_method = temp;
296 }
297 // ---------- assignment operator(s) ---------------------
298
299 // ---------- data members -------------------------------
300 DChain::MethodBase<Arg>* m_method;
301 };
302
303} // namespace DChain
305
306// inline function definitions
307
308// Uncomment the following lines, if your class is templated
309// and has an implementation file (in the Template directory)
310// #if defined(INCLUDE_TEMPLATE_DEFINITIONS)
311// # include "DChain/Template/DCSimpleSelector.cc"
312// #endif
313
314#endif /* DCHAIN_DCSIMPLESELECTOR_H */
void swap(DataList< T > lhs, DataList< T > rhs)
const DCSimpleSelector< Arg > & operator=(const DCSimpleSelector< Arg > &iRHS)
virtual bool select(Arg &)=0
virtual MethodBase * clone() const =0
UseHolder< T,(sizeof(testForHolder((T *) 0))==sizeof(PassTest))>::Method Method
ChooseArg< T1, T2,(sizeof(PickArgTester< T1, T2 >::inheritsFrom((T1 *) 0))==sizeof(PassTest))>::arg_type arg_type
static PassTest inheritsFrom(const T2 *)
static FailTest inheritsFrom(...)
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(...)