CMS 3D CMS Logo

eventsetup_dependsOn.h
Go to the documentation of this file.
1 
2 #ifndef Framework_eventsetup_dependsOn_h
3 #define Framework_eventsetup_dependsOn_h
4 // -*- C++ -*-
5 //
6 // Package: Framework
7 // Class : eventsetup_dependsOn
8 //
26 /*
27  Implementation details:
28 
29  The dependsOn function does not have enough information to convert the list of member function pointers directly into the
30  appropriate Decorator class since it is missing the Record type of the Decorator (all it knows are the Record types the
31  Decorator depends on). Therefore we must defer the creation of the Decorator until that Record type is known (which
32  happens within the body of the ESProducer::setWhatProduced method). To allow the deferred construction,
33  the dependsOn method returns a compile time linked list created via the TwoHolder class (if there is only one
34  node you get a OneHolder). The dependsOn method always makes sure that the second type of the TwoHolder is the member
35  function pointer which is needed for the later construction stage.
36 
37  Within the body of ESProducer::setWhatProduced, the proper Decorator is created by calling 'createDecoratorFrom' which is given
38  a pointer to the Producer, a dummy pointer to the proper Record and the linked list of member function pointers. The
39  'createDecoratorFrom' uses the makeCaller and createDependsOnCaller functions to recursively create the proper DependsOnCaller
40  functor which is then used by the ESPreFunctorDecorator to do the work. We use HolderToCaller template class merely to define
41  the return type of the 'createDecoratorFrom' and 'makeCaller' functions.
42 
43  */
44 
45 //
46 // Original Author: Chris Jones
47 // Created: Thu Jun 23 14:06:56 EDT 2005
48 //
49 
50 // system include files
51 
52 // user include files
54 
55 // forward declarations
56 
57 namespace edm {
58  namespace eventsetup {
59 
60  //Simple functor that checks to see if a Record has changed since the last time it was called
61  // and if so, calls the appropriate member method. Multiple callers can be chained together using the
62  // TCallerChain template argument.
63  template <class T, class TRecord, class TDependsOnRecord, class TCallerChain>
64  struct DependsOnCaller {
65  DependsOnCaller(T* iCallee, void (T::*iMethod)(const TDependsOnRecord&), const TCallerChain& iChain)
66  : callee_(iCallee), method_(iMethod), chain_(iChain), cacheID_(0) {}
67 
68  void operator()(const TRecord& iRecord) {
69  const TDependsOnRecord& record = iRecord.template getRecord<TDependsOnRecord>();
70  if (record.cacheIdentifier() != cacheID_) {
71  (callee_->*method_)(record);
72  cacheID_ = record.cacheIdentifier();
73  }
74  //call next 'functor' in our chain
75  chain_(iRecord);
76  }
77 
78  private:
80  void (T::*method_)(const TDependsOnRecord&);
81  TCallerChain chain_;
82  unsigned long long cacheID_;
83  };
84 
85  //helper function to help create a DependsOnCaller
86  template <class T, class TRecord, class TDependsOnRecord, class TCallerChain>
88  T* iCallee, const TRecord*, void (T::*iMethod)(const TDependsOnRecord&), const TCallerChain& iChain) {
89  return DependsOnCaller<T, TRecord, TDependsOnRecord, TCallerChain>(iCallee, iMethod, iChain);
90  }
91 
92  //A 'do nothing' functor that is used to terminate our chain of functors
93  template <class TRecord>
95  void operator()(const TRecord&) {}
96  };
97 
98  //put implementation details used to get the dependsOn method to work into their own namespace
99  namespace depends_on {
100  //class to hold onto one member method pointer
101  template <class T, class TDependsOnRecord>
102  struct OneHolder {
103  typedef T Prod_t;
104  typedef TDependsOnRecord DependsOnRecord_t;
105 
106  OneHolder(void (T::*iHoldee)(const TDependsOnRecord&)) : holdee_(iHoldee) {}
107  void (T::*holdee_)(const TDependsOnRecord&);
108  };
109 
110  //class to create a linked list of member method pointers
111  template <class T, class U>
112  struct TwoHolder {
113  typedef T T1_t;
114  typedef U T2_t;
115  TwoHolder(const T& i1, const U& i2) : h1_(i1), h2_(i2) {}
118  };
119 
120  //allows one to create the linked list by applying operator & to member method pointers
121  template <class T, class U>
122  TwoHolder<T, U> operator&(const T& iT, const U& iU) {
123  return TwoHolder<T, U>(iT, iU);
124  }
125 
126  //HolderToCaller is used to state how a OneHolder or TwoHolder is converted into the appropriate
127  // DependsOnCaller. This class is needed to define the return value of the makeCaller function
128  template <class TRecord, class THolder>
129  struct HolderToCaller {};
130  template <class TRecord, class T, class TDependsOnRecord>
131  struct HolderToCaller<TRecord, OneHolder<T, TDependsOnRecord> > {
133  };
134  template <class TRecord, class T, class T1, class T2>
135  struct HolderToCaller<TRecord, TwoHolder<T1, void (T::*)(const T2&)> > {
137  };
138 
139  //helper function to convert a OneHolder or TwoHolder into a DependsOnCaller.
140  template <class T, class TDependsOnRecord, class TRecord>
142  T* iT, const TRecord* iRec, const OneHolder<T, TDependsOnRecord>& iHolder) {
144  }
145 
146  template <class T, class T1, class T2, class TRecord>
148  T* iT, const TRecord* iRec, const TwoHolder<T1, void (T::*)(const T2&)>& iHolder) {
149  return createDependsOnCaller(iT, iRec, iHolder.h2_, makeCaller(iT, iRec, iHolder.h1_));
150  }
151  } // namespace depends_on
152 
153  //DecoratorFromArg is used to declare the return type of 'createDecoratorFrom' based on the arguments to the function.
154  template <typename T, typename TRecord, typename TArg>
156  typedef TArg Decorator_t;
157  };
158 
159  template <typename T, typename TRecord, typename TDependsOnRecord>
160  struct DecoratorFromArg<T, TRecord, depends_on::OneHolder<T, TDependsOnRecord> > {
161  typedef ESPreFunctorDecorator<TRecord,
164  };
165 
166  template <typename T, typename TRecord, typename TDependsOnRecord>
167  inline ESPreFunctorDecorator<TRecord,
169  createDecoratorFrom(T* iT, const TRecord* iRec, const depends_on::OneHolder<T, TDependsOnRecord>& iHolder) {
172  temp(createDependsOnCaller(iT, iRec, iHolder.holdee_, tCaller));
173  return temp;
174  }
175 
176  template <typename T, typename TRecord, typename T1, typename T2>
177  struct DecoratorFromArg<T, TRecord, depends_on::TwoHolder<T1, T2> > {
178  typedef ESPreFunctorDecorator<
179  TRecord,
182  };
183  template <typename T, typename TRecord, typename T1, typename T2>
184  inline ESPreFunctorDecorator<TRecord,
186  createDecoratorFrom(T* iT, const TRecord* iRec, const depends_on::TwoHolder<T1, T2>& iHolder) {
187  return ESPreFunctorDecorator<
188  TRecord,
190  createDependsOnCaller(iT, iRec, iHolder.h2_, makeCaller(iT, iRec, iHolder.h1_)));
191  }
192 
193  //The actual dependsOn functions which users call
194  template <typename T, typename TDependsOnRecord>
195  depends_on::OneHolder<T, TDependsOnRecord> dependsOn(void (T::*iT)(const TDependsOnRecord&)) {
196  return iT;
197  }
198 
199  template <typename T, typename T1, typename T2>
200  depends_on::TwoHolder<depends_on::OneHolder<T, T1>, T2> dependsOn(void (T::*iT1)(const T1&), T2 iT2) {
201  return depends_on::OneHolder<T, T1>(iT1) & iT2;
202  }
203 
204  template <typename T, typename T1, typename T2, typename T3>
206  void (T::*iT1)(const T1&), T2 iT2, T3 iT3) {
207  return depends_on::OneHolder<T, T1>(iT1) & iT2 & iT3;
208  }
209 
210  } // namespace eventsetup
211 } // namespace edm
212 
213 #endif
edm::eventsetup::DependsOnCaller::DependsOnCaller
DependsOnCaller(T *iCallee, void(T::*iMethod)(const TDependsOnRecord &), const TCallerChain &iChain)
Definition: eventsetup_dependsOn.h:65
testProducerWithPsetDescEmpty_cfi.i2
i2
Definition: testProducerWithPsetDescEmpty_cfi.py:46
edm::eventsetup::DecoratorFromArg< T, TRecord, depends_on::TwoHolder< T1, T2 > >::Decorator_t
ESPreFunctorDecorator< TRecord, typename depends_on::HolderToCaller< TRecord, depends_on::TwoHolder< T1, T2 > >::Caller_t > Decorator_t
Definition: eventsetup_dependsOn.h:181
edm::eventsetup::depends_on::OneHolder::DependsOnRecord_t
TDependsOnRecord DependsOnRecord_t
Definition: eventsetup_dependsOn.h:104
edm::eventsetup::DependsOnCaller::chain_
TCallerChain chain_
Definition: eventsetup_dependsOn.h:81
edm::eventsetup::DependsOnCaller::method_
void(T::* method_)(const TDependsOnRecord &)
Definition: eventsetup_dependsOn.h:80
edm::eventsetup::dependsOn
depends_on::OneHolder< T, TDependsOnRecord > dependsOn(void(T::*iT)(const TDependsOnRecord &))
Definition: eventsetup_dependsOn.h:195
edm::eventsetup::depends_on::TwoHolder::h2_
U h2_
Definition: eventsetup_dependsOn.h:117
edm
HLT enums.
Definition: AlignableModifier.h:19
edm::eventsetup::DependsOnCaller::callee_
T * callee_
Definition: eventsetup_dependsOn.h:79
testProducerWithPsetDescEmpty_cfi.i1
i1
Definition: testProducerWithPsetDescEmpty_cfi.py:45
edm::eventsetup::DependsOnDoNothingCaller
Definition: eventsetup_dependsOn.h:94
GlobalPosition_Frontier_DevDB_cff.record
record
Definition: GlobalPosition_Frontier_DevDB_cff.py:10
edm::eventsetup::depends_on::TwoHolder::T1_t
T T1_t
Definition: eventsetup_dependsOn.h:113
edm::eventsetup::depends_on::HolderToCaller< TRecord, TwoHolder< T1, void(T::*)(const T2 &)> >::Caller_t
DependsOnCaller< T, TRecord, T2, typename HolderToCaller< TRecord, T1 >::Caller_t > Caller_t
Definition: eventsetup_dependsOn.h:136
edm::eventsetup::depends_on::makeCaller
DependsOnCaller< T, TRecord, T2, typename HolderToCaller< TRecord, T1 >::Caller_t > makeCaller(T *iT, const TRecord *iRec, const TwoHolder< T1, void(T::*)(const T2 &)> &iHolder)
Definition: eventsetup_dependsOn.h:147
edm::eventsetup::depends_on::TwoHolder
Definition: eventsetup_dependsOn.h:112
groupFilesInBlocks.temp
list temp
Definition: groupFilesInBlocks.py:142
edm::eventsetup::depends_on::TwoHolder::h1_
T h1_
Definition: eventsetup_dependsOn.h:116
edm::eventsetup::depends_on::OneHolder::Prod_t
T Prod_t
Definition: eventsetup_dependsOn.h:103
edm::eventsetup::DependsOnCaller::operator()
void operator()(const TRecord &iRecord)
Definition: eventsetup_dependsOn.h:68
edm::eventsetup::depends_on::operator&
TwoHolder< T, U > operator&(const T &iT, const U &iU)
Definition: eventsetup_dependsOn.h:122
edm::eventsetup::createDependsOnCaller
DependsOnCaller< T, TRecord, TDependsOnRecord, TCallerChain > createDependsOnCaller(T *iCallee, const TRecord *, void(T::*iMethod)(const TDependsOnRecord &), const TCallerChain &iChain)
Definition: eventsetup_dependsOn.h:87
edm::eventsetup::DecoratorFromArg< T, TRecord, depends_on::OneHolder< T, TDependsOnRecord > >::Decorator_t
ESPreFunctorDecorator< TRecord, DependsOnCaller< T, TRecord, TDependsOnRecord, DependsOnDoNothingCaller< TRecord > > > Decorator_t
Definition: eventsetup_dependsOn.h:163
edm::eventsetup::DependsOnCaller
Definition: eventsetup_dependsOn.h:64
edm::eventsetup::depends_on::TwoHolder::TwoHolder
TwoHolder(const T &i1, const U &i2)
Definition: eventsetup_dependsOn.h:115
edm::eventsetup::createDecoratorFrom
const TDecorator & createDecoratorFrom(T *, const TRecord *, const TDecorator &iDec)
Definition: ESProducer.h:96
mitigatedMETSequence_cff.U
U
Definition: mitigatedMETSequence_cff.py:36
edm::eventsetup::DependsOnDoNothingCaller::operator()
void operator()(const TRecord &)
Definition: eventsetup_dependsOn.h:95
edm::eventsetup::ESPreFunctorDecorator
Definition: ESPreFunctorDecorator.h:33
edm::eventsetup::depends_on::OneHolder::OneHolder
OneHolder(void(T::*iHoldee)(const TDependsOnRecord &))
Definition: eventsetup_dependsOn.h:106
edm::eventsetup::DecoratorFromArg::Decorator_t
TArg Decorator_t
Definition: eventsetup_dependsOn.h:156
edm::eventsetup::DecoratorFromArg
Definition: eventsetup_dependsOn.h:155
edm::eventsetup::depends_on::TwoHolder::T2_t
U T2_t
Definition: eventsetup_dependsOn.h:114
edm::eventsetup::depends_on::OneHolder
Definition: eventsetup_dependsOn.h:102
T
long double T
Definition: Basic3DVectorLD.h:48
edm::eventsetup::depends_on::makeCaller
DependsOnCaller< T, TRecord, TDependsOnRecord, DependsOnDoNothingCaller< TRecord > > makeCaller(T *iT, const TRecord *iRec, const OneHolder< T, TDependsOnRecord > &iHolder)
Definition: eventsetup_dependsOn.h:141
edm::eventsetup::depends_on::HolderToCaller< TRecord, OneHolder< T, TDependsOnRecord > >::Caller_t
DependsOnCaller< T, TRecord, TDependsOnRecord, DependsOnDoNothingCaller< TRecord > > Caller_t
Definition: eventsetup_dependsOn.h:132
funct::void
TEMPL(T2) struct Divides void
Definition: Factorize.h:29
edm::eventsetup::depends_on::OneHolder::holdee_
void(T::* holdee_)(const TDependsOnRecord &)
Definition: eventsetup_dependsOn.h:107
edm::eventsetup::depends_on::HolderToCaller
Definition: eventsetup_dependsOn.h:129
ESPreFunctorDecorator.h
edm::eventsetup::DependsOnCaller::cacheID_
unsigned long long cacheID_
Definition: eventsetup_dependsOn.h:82