Go to the documentation of this file.00001 #ifndef Framework_Callback_h
00002 #define Framework_Callback_h
00003
00004
00005
00006
00007
00016
00017
00018
00019
00020
00021
00022
00023 #include <vector>
00024
00025 #include "FWCore/Framework/interface/produce_helpers.h"
00026
00027
00028 namespace edm {
00029 namespace eventsetup {
00030
00031
00032
00033
00034 struct CallbackBase { virtual ~CallbackBase() {} };
00035
00036
00037 template< typename TRecord>
00038 struct CallbackSimpleDecorator {
00039 void pre(const TRecord&) {}
00040 void post(const TRecord&) {}
00041 };
00042
00043 template<typename T,
00044 typename TReturn,
00045 typename TRecord,
00046 typename TDecorator
00047 =CallbackSimpleDecorator<TRecord> >
00048 class Callback : public CallbackBase {
00049 public:
00050 typedef TReturn (T ::* method_type)(const TRecord&);
00051
00052 Callback(T* iProd,
00053 method_type iMethod,
00054 const TDecorator& iDec = TDecorator()) :
00055 proxyData_(produce::size< TReturn >::value, static_cast<void*>(0)),
00056 producer_(iProd),
00057 method_(iMethod),
00058 wasCalledForThisRecord_(false),
00059 decorator_(iDec) {}
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 void operator()(const TRecord& iRecord) {
00070 if(!wasCalledForThisRecord_) {
00071 decorator_.pre(iRecord);
00072 storeReturnedValues((producer_->*method_)(iRecord));
00073 wasCalledForThisRecord_ = true;
00074 decorator_.post(iRecord);
00075 }
00076 }
00077
00078 template<class DataT>
00079 void holdOntoPointer(DataT* iData) {
00080 proxyData_[produce::find_index<TReturn,DataT>::value] = iData;
00081 }
00082
00083 void storeReturnedValues(TReturn iReturn) {
00084
00085 typedef typename produce::product_traits<TReturn>::type type;
00086 setData(iReturn, static_cast<typename type::head_type*>(0), static_cast<const typename type::tail_type *>(0));
00087 }
00088
00089 template<class RemainingContainerT, class DataT, class ProductsT>
00090 void setData(ProductsT& iProducts, const RemainingContainerT*, const DataT*) {
00091 DataT* temp = reinterpret_cast< DataT*>(proxyData_[produce::find_index<TReturn,DataT>::value]) ;
00092 if(0 != temp) { copyFromTo(iProducts, *temp); }
00093 setData(iProducts, static_cast< const typename RemainingContainerT::head_type *>(0),
00094 static_cast< const typename RemainingContainerT::tail_type *>(0));
00095 }
00096 template<class DataT, class ProductsT>
00097 void setData(ProductsT& iProducts, const produce::Null*, const DataT*) {
00098
00099 DataT* temp = reinterpret_cast< DataT*>(proxyData_[produce::find_index<TReturn,DataT>::value]) ;
00100
00101 if(0 != temp) { copyFromTo(iProducts, *temp); }
00102 }
00103 void newRecordComing() {
00104 wasCalledForThisRecord_ = false;
00105 }
00106
00107 private:
00108 Callback(const Callback&);
00109
00110 const Callback& operator=(const Callback&);
00111
00112 std::vector<void*> proxyData_;
00113 T* producer_;
00114 method_type method_;
00115 bool wasCalledForThisRecord_;
00116 TDecorator decorator_;
00117 };
00118 }
00119 }
00120
00121 #endif