CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/FWCore/Framework/interface/Callback.h

Go to the documentation of this file.
00001 #ifndef Framework_Callback_h
00002 #define Framework_Callback_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     Framework
00006 // Class  :     Callback
00007 // 
00016 //
00017 // Author:      Chris Jones
00018 // Created:     Sun Apr 17 14:30:24 EDT 2005
00019 // $Id: Callback.h,v 1.9 2006/10/21 02:48:59 wmtan Exp $
00020 //
00021 
00022 // system include files
00023 #include <vector>
00024 // user include files
00025 #include "FWCore/Framework/interface/produce_helpers.h"
00026 
00027 // forward declarations
00028 namespace edm {
00029    namespace eventsetup {
00030       
00031       //need a virtual distructor since owner of callback only knows
00032       // about the base class.  Other users of callback know the specific
00033       // type
00034       struct CallbackBase { virtual ~CallbackBase() {} };
00035       
00036       // The default decorator that does nothing
00037       template< typename TRecord>
00038       struct CallbackSimpleDecorator {
00039          void pre(const TRecord&) {}
00040          void post(const TRecord&) {}
00041       };
00042       
00043       template<typename T,         //producer's type
00044                typename TReturn,   //return type of the producer's method
00045                typename TRecord,   //the record passed in as an argument
00046                typename TDecorator //allows customization using pre/post calls 
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          // ---------- const member functions ---------------------
00063          
00064          // ---------- static member functions --------------------
00065          
00066          // ---------- member functions ---------------------------
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             //std::cout <<" storeReturnedValues "<< iReturn <<" " <<iReturn->value_ <<std::endl;
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                //std::cout <<" setData["<< produce::find_index<TReturn,DataT>::value<<"] "<< temp <<std::endl;
00101                if(0 != temp) { copyFromTo(iProducts, *temp); } 
00102             }
00103          void newRecordComing() {
00104             wasCalledForThisRecord_ = false;
00105          }
00106          
00107      private:
00108          Callback(const Callback&); // stop default
00109          
00110          const Callback& operator=(const Callback&); // stop default
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