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