File indexing completed on 2024-04-06 12:12:02
0001
0002 #ifndef Framework_eventsetup_dependsOn_h
0003 #define Framework_eventsetup_dependsOn_h
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 #include "FWCore/Framework/interface/ESPreFunctorDecorator.h"
0054
0055
0056
0057 namespace edm {
0058 namespace eventsetup {
0059
0060
0061
0062
0063 template <class T, class TRecord, class TDependsOnRecord, class TCallerChain>
0064 struct DependsOnCaller {
0065 DependsOnCaller(T* iCallee, void (T::*iMethod)(const TDependsOnRecord&), const TCallerChain& iChain)
0066 : callee_(iCallee), method_(iMethod), chain_(iChain), cacheID_(0) {}
0067
0068 void operator()(const TRecord& iRecord) {
0069 const TDependsOnRecord& record = iRecord.template getRecord<TDependsOnRecord>();
0070 if (record.cacheIdentifier() != cacheID_) {
0071 (callee_->*method_)(record);
0072 cacheID_ = record.cacheIdentifier();
0073 }
0074
0075 chain_(iRecord);
0076 }
0077
0078 private:
0079 T* callee_;
0080 void (T::*method_)(const TDependsOnRecord&);
0081 TCallerChain chain_;
0082 unsigned long long cacheID_;
0083 };
0084
0085
0086 template <class T, class TRecord, class TDependsOnRecord, class TCallerChain>
0087 DependsOnCaller<T, TRecord, TDependsOnRecord, TCallerChain> createDependsOnCaller(
0088 T* iCallee, const TRecord*, void (T::*iMethod)(const TDependsOnRecord&), const TCallerChain& iChain) {
0089 return DependsOnCaller<T, TRecord, TDependsOnRecord, TCallerChain>(iCallee, iMethod, iChain);
0090 }
0091
0092
0093 template <class TRecord>
0094 struct DependsOnDoNothingCaller {
0095 void operator()(const TRecord&) {}
0096 };
0097
0098
0099 namespace depends_on {
0100
0101 template <class T, class TDependsOnRecord>
0102 struct OneHolder {
0103 typedef T Prod_t;
0104 typedef TDependsOnRecord DependsOnRecord_t;
0105
0106 OneHolder(void (T::*iHoldee)(const TDependsOnRecord&)) : holdee_(iHoldee) {}
0107 void (T::*holdee_)(const TDependsOnRecord&);
0108 };
0109
0110
0111 template <class T, class U>
0112 struct TwoHolder {
0113 typedef T T1_t;
0114 typedef U T2_t;
0115 TwoHolder(const T& i1, const U& i2) : h1_(i1), h2_(i2) {}
0116 T h1_;
0117 U h2_;
0118 };
0119
0120
0121 template <class T, class U>
0122 TwoHolder<T, U> operator&(const T& iT, const U& iU) {
0123 return TwoHolder<T, U>(iT, iU);
0124 }
0125
0126
0127
0128 template <class TRecord, class THolder>
0129 struct HolderToCaller {};
0130 template <class TRecord, class T, class TDependsOnRecord>
0131 struct HolderToCaller<TRecord, OneHolder<T, TDependsOnRecord> > {
0132 typedef DependsOnCaller<T, TRecord, TDependsOnRecord, DependsOnDoNothingCaller<TRecord> > Caller_t;
0133 };
0134 template <class TRecord, class T, class T1, class T2>
0135 struct HolderToCaller<TRecord, TwoHolder<T1, void (T::*)(const T2&)> > {
0136 typedef DependsOnCaller<T, TRecord, T2, typename HolderToCaller<TRecord, T1>::Caller_t> Caller_t;
0137 };
0138
0139
0140 template <class T, class TDependsOnRecord, class TRecord>
0141 DependsOnCaller<T, TRecord, TDependsOnRecord, DependsOnDoNothingCaller<TRecord> > makeCaller(
0142 T* iT, const TRecord* iRec, const OneHolder<T, TDependsOnRecord>& iHolder) {
0143 return createDependsOnCaller(iT, iRec, iHolder.holdee_, DependsOnDoNothingCaller<TRecord>());
0144 }
0145
0146 template <class T, class T1, class T2, class TRecord>
0147 DependsOnCaller<T, TRecord, T2, typename HolderToCaller<TRecord, T1>::Caller_t> makeCaller(
0148 T* iT, const TRecord* iRec, const TwoHolder<T1, void (T::*)(const T2&)>& iHolder) {
0149 return createDependsOnCaller(iT, iRec, iHolder.h2_, makeCaller(iT, iRec, iHolder.h1_));
0150 }
0151 }
0152
0153
0154 template <typename T, typename TRecord, typename TArg>
0155 struct DecoratorFromArg {
0156 typedef TArg Decorator_t;
0157 };
0158
0159 template <typename T, typename TRecord, typename TDependsOnRecord>
0160 struct DecoratorFromArg<T, TRecord, depends_on::OneHolder<T, TDependsOnRecord> > {
0161 typedef ESPreFunctorDecorator<TRecord,
0162 DependsOnCaller<T, TRecord, TDependsOnRecord, DependsOnDoNothingCaller<TRecord> > >
0163 Decorator_t;
0164 };
0165
0166 template <typename T, typename TRecord, typename TDependsOnRecord>
0167 inline ESPreFunctorDecorator<TRecord,
0168 DependsOnCaller<T, TRecord, TDependsOnRecord, DependsOnDoNothingCaller<TRecord> > >
0169 createDecoratorFrom(T* iT, const TRecord* iRec, const depends_on::OneHolder<T, TDependsOnRecord>& iHolder) {
0170 DependsOnDoNothingCaller<TRecord> tCaller;
0171 ESPreFunctorDecorator<TRecord, DependsOnCaller<T, TRecord, TDependsOnRecord, DependsOnDoNothingCaller<TRecord> > >
0172 temp(createDependsOnCaller(iT, iRec, iHolder.holdee_, tCaller));
0173 return temp;
0174 }
0175
0176 template <typename T, typename TRecord, typename T1, typename T2>
0177 struct DecoratorFromArg<T, TRecord, depends_on::TwoHolder<T1, T2> > {
0178 typedef ESPreFunctorDecorator<
0179 TRecord,
0180 typename depends_on::HolderToCaller<TRecord, depends_on::TwoHolder<T1, T2> >::Caller_t>
0181 Decorator_t;
0182 };
0183 template <typename T, typename TRecord, typename T1, typename T2>
0184 inline ESPreFunctorDecorator<TRecord,
0185 typename depends_on::HolderToCaller<TRecord, depends_on::TwoHolder<T1, T2> >::Caller_t>
0186 createDecoratorFrom(T* iT, const TRecord* iRec, const depends_on::TwoHolder<T1, T2>& iHolder) {
0187 return ESPreFunctorDecorator<
0188 TRecord,
0189 typename depends_on::HolderToCaller<TRecord, depends_on::TwoHolder<T1, T2> >::Caller_t>(
0190 createDependsOnCaller(iT, iRec, iHolder.h2_, makeCaller(iT, iRec, iHolder.h1_)));
0191 }
0192
0193
0194 template <typename T, typename TDependsOnRecord>
0195 depends_on::OneHolder<T, TDependsOnRecord> dependsOn(void (T::*iT)(const TDependsOnRecord&)) {
0196 return iT;
0197 }
0198
0199 template <typename T, typename T1, typename T2>
0200 depends_on::TwoHolder<depends_on::OneHolder<T, T1>, T2> dependsOn(void (T::*iT1)(const T1&), T2 iT2) {
0201 return depends_on::OneHolder<T, T1>(iT1) & iT2;
0202 }
0203
0204 template <typename T, typename T1, typename T2, typename T3>
0205 depends_on::TwoHolder<depends_on::TwoHolder<depends_on::OneHolder<T, T1>, T2>, T3> dependsOn(
0206 void (T::*iT1)(const T1&), T2 iT2, T3 iT3) {
0207 return depends_on::OneHolder<T, T1>(iT1) & iT2 & iT3;
0208 }
0209
0210 }
0211 }
0212
0213 #endif