00001
00002 #ifndef Framework_eventsetup_dependsOn_h
00003 #define Framework_eventsetup_dependsOn_h
00004
00005
00006
00007
00008
00026
00027
00028
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 #include "FWCore/Framework/interface/ESPreFunctorDecorator.h"
00055 #include "FWCore/Framework/interface/IOVSyncValue.h"
00056 #include "FWCore/Framework/interface/EventSetupRecord.h"
00057
00058
00059
00060
00061 namespace edm {
00062 namespace eventsetup {
00063
00064
00065
00066
00067 template<class T, class TRecord, class TDependsOnRecord, class TCallerChain >
00068 struct DependsOnCaller
00069 {
00070 DependsOnCaller(T* iCallee, void(T::* iMethod)(const TDependsOnRecord&) , const TCallerChain& iChain) :
00071 callee_(iCallee), method_(iMethod), chain_(iChain),cacheID_(0){}
00072
00073 void operator()(const TRecord& iRecord) {
00074 const TDependsOnRecord& record = iRecord.template getRecord<TDependsOnRecord>();
00075 if(record.cacheIdentifier() != cacheID_) {
00076 (callee_->*method_)(record);
00077 cacheID_=record.cacheIdentifier();
00078 }
00079
00080 chain_(iRecord);
00081 }
00082 private:
00083 T* callee_;
00084 void (T::*method_)(const TDependsOnRecord&);
00085 TCallerChain chain_;
00086 unsigned long long cacheID_;
00087 };
00088
00089
00090 template<class T, class TRecord, class TDependsOnRecord, class TCallerChain >
00091 DependsOnCaller<T,TRecord, TDependsOnRecord, TCallerChain>
00092 createDependsOnCaller(T* iCallee, const TRecord*, void(T::*iMethod)(const TDependsOnRecord&), const TCallerChain& iChain)
00093 {
00094 return DependsOnCaller<T,TRecord, TDependsOnRecord, TCallerChain>(iCallee, iMethod, iChain);
00095 }
00096
00097
00098 template<class TRecord>
00099 struct DependsOnDoNothingCaller { void operator()(const TRecord&) {} };
00100
00101
00102 namespace depends_on {
00103
00104 template <class T, class TDependsOnRecord>
00105 struct OneHolder {
00106 typedef T Prod_t;
00107 typedef TDependsOnRecord DependsOnRecord_t;
00108
00109 OneHolder(void (T::*iHoldee)(const TDependsOnRecord&)) : holdee_(iHoldee) {}
00110 void (T::*holdee_)(const TDependsOnRecord&);
00111
00112 };
00113
00114
00115 template <class T, class U>
00116 struct TwoHolder {
00117 typedef T T1_t;
00118 typedef U T2_t;
00119 TwoHolder(T i1, U i2) : h1_(i1), h2_(i2) {}
00120 T h1_;
00121 U h2_;
00122 };
00123
00124
00125 template< class T, class U>
00126 TwoHolder<T,U> operator&(const T& iT, const U& iU) {
00127 return TwoHolder<T,U>(iT, iU);
00128 }
00129
00130
00131
00132 template< class TRecord, class THolder>
00133 struct HolderToCaller {
00134 };
00135 template< class TRecord, class T, class TDependsOnRecord >
00136 struct HolderToCaller<TRecord, OneHolder<T, TDependsOnRecord> > {
00137 typedef DependsOnCaller<T,TRecord, TDependsOnRecord, DependsOnDoNothingCaller<TRecord> > Caller_t;
00138 };
00139 template< class TRecord, class T, class T1, class T2>
00140 struct HolderToCaller< TRecord, TwoHolder<T1, void (T::*)(const T2&) > > {
00141 typedef DependsOnCaller<T, TRecord, T2 , typename HolderToCaller<TRecord,T1>::Caller_t > Caller_t;
00142 };
00143
00144
00145 template<class T, class TDependsOnRecord, class TRecord>
00146 DependsOnCaller<T,TRecord, TDependsOnRecord, DependsOnDoNothingCaller<TRecord> >
00147 makeCaller(T*iT, const TRecord* iRec, const OneHolder<T, TDependsOnRecord>& iHolder) {
00148 return createDependsOnCaller(iT, iRec, iHolder.holdee_, DependsOnDoNothingCaller<TRecord>());
00149 }
00150
00151 template<class T, class T1, class T2, class TRecord>
00152 DependsOnCaller<T,TRecord, T2, typename HolderToCaller<TRecord, T1>::Caller_t >
00153 makeCaller(T*iT, const TRecord* iRec, const TwoHolder<T1, void (T::*)(const T2&)>& iHolder) {
00154 return createDependsOnCaller(iT, iRec, iHolder.h2_, makeCaller(iT, iRec, iHolder.h1_));
00155 }
00156 }
00157
00158
00159 template< typename T, typename TRecord, typename TArg>
00160 struct DecoratorFromArg { typedef TArg Decorator_t; };
00161
00162 template< typename T, typename TRecord, typename TDependsOnRecord>
00163 struct DecoratorFromArg<T,TRecord, depends_on::OneHolder<T,TDependsOnRecord> > {
00164 typedef ESPreFunctorDecorator<TRecord,DependsOnCaller<T,TRecord, TDependsOnRecord, DependsOnDoNothingCaller<TRecord> > > Decorator_t;
00165 };
00166
00167
00168 template< typename T, typename TRecord, typename TDependsOnRecord >
00169 inline ESPreFunctorDecorator<TRecord,DependsOnCaller<T,TRecord, TDependsOnRecord, DependsOnDoNothingCaller<TRecord> > >
00170 createDecoratorFrom(T* iT, const TRecord*iRec, const depends_on::OneHolder<T,TDependsOnRecord>& iHolder) {
00171 DependsOnDoNothingCaller<TRecord> tCaller;
00172 ESPreFunctorDecorator<TRecord,DependsOnCaller<T,TRecord, TDependsOnRecord, DependsOnDoNothingCaller<TRecord> > >
00173 temp(createDependsOnCaller(iT, iRec, iHolder.holdee_, tCaller));
00174 return temp;
00175 }
00176
00177 template< typename T, typename TRecord, typename T1, typename T2>
00178 struct DecoratorFromArg<T,TRecord, depends_on::TwoHolder<T1,T2> > {
00179 typedef ESPreFunctorDecorator<TRecord,typename depends_on::HolderToCaller<TRecord, depends_on::TwoHolder<T1, T2> >::Caller_t >
00180 Decorator_t;
00181 };
00182 template< typename T, typename TRecord, typename T1, typename T2>
00183 inline ESPreFunctorDecorator<TRecord,typename depends_on::HolderToCaller<TRecord, depends_on::TwoHolder<T1, T2> >::Caller_t >
00184 createDecoratorFrom(T* iT, const TRecord*iRec, const depends_on::TwoHolder<T1,T2>& iHolder) {
00185 return ESPreFunctorDecorator<TRecord, typename depends_on::HolderToCaller<TRecord,depends_on::TwoHolder< T1, T2> >::Caller_t >
00186 (createDependsOnCaller(iT, iRec, iHolder.h2_, makeCaller(iT, iRec, iHolder.h1_)));
00187 }
00188
00189
00190
00191 template <typename T, typename TDependsOnRecord>
00192 depends_on::OneHolder<T,TDependsOnRecord>
00193 dependsOn(void(T::*iT)(const TDependsOnRecord&)) { return iT ; }
00194
00195 template< typename T, typename T1, typename T2>
00196 depends_on::TwoHolder<depends_on::OneHolder<T,T1>, T2>
00197 dependsOn(void (T::* iT1)(const T1&), T2 iT2) { return depends_on::OneHolder<T, T1>(iT1) & iT2; }
00198
00199 template< typename T, typename T1, typename T2, typename T3>
00200 depends_on::TwoHolder< depends_on::TwoHolder<depends_on::OneHolder<T,T1>, T2>, T3>
00201 dependsOn(void(T::* iT1)(const T1&), T2 iT2, T3 iT3) { return depends_on::OneHolder<T,T1>(iT1) & iT2 & iT3; }
00202
00203
00204 }
00205 }
00206
00207 #endif