CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/SimG4Core/Notification/interface/SimActivityRegistryEnroller.h

Go to the documentation of this file.
00001 #ifndef Notification_SimActivityRegistryEnroller_h
00002 #define Notification_SimActivityRegistryEnroller_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     Notification
00006 // Class  :     SimActivityRegistryEnroller
00007 // 
00016 //
00017 // Original Author:  Chris Jones
00018 //         Created:  Sun Nov 13 15:08:12 EST 2005
00019 // $Id: SimActivityRegistryEnroller.h,v 1.4 2005/11/24 19:59:52 chrjones Exp $
00020 //
00021 
00022 // system include files
00023 #include "boost/mpl/pop_back.hpp"
00024 #include "boost/mpl/begin_end.hpp"
00025 #include "boost/mpl/copy_if.hpp"
00026 #include "boost/mpl/deref.hpp"
00027 #include "boost/mpl/prior.hpp"
00028 #include "boost/mpl/vector.hpp"
00029 #include "boost/mpl/eval_if.hpp"
00030 #include "boost/mpl/empty.hpp"
00031 
00032 // user include files
00033 #include "SimG4Core/Notification/interface/Observer.h"
00034 #include "SimG4Core/Notification/interface/SimActivityRegistry.h"
00035 
00036 // forward declarations
00037 namespace enroller_helper {
00038   template <class T>
00039     struct Enrollment {
00040       static void enroll(SimActivityRegistry& iReg, Observer<const T*>* iObs){
00041         iReg.connect(iObs);
00042       }
00043       static void enroll(SimActivityRegistry&, void*) {}
00044     };
00045    
00046   //this class is used to terminate our recursion
00047   template <class T>
00048     struct LastEnrollerHelper {
00049       static void enroll(SimActivityRegistry&, T*) {
00050       }
00051     };
00052 
00053   template< class T, class TVector>
00054     struct EnrollerHelper  {
00055       typedef typename boost::mpl::pop_back<TVector>::type RemainingVector;
00056       static void enroll(SimActivityRegistry& iReg, T* iT) {
00057         //Try to enroll the object if it inherits from the class at the 
00058         // end of TVector
00059         Enrollment< typename boost::mpl::deref< typename boost::mpl::prior< typename boost::mpl::end< TVector >::type >::type >::type >::enroll(iReg, iT );
00060         
00061         //If TVector is not at its end, call EnrollerHelper with a vector
00062         // that had our last type 'popped off' the end
00063         typedef typename boost::mpl::eval_if<boost::mpl::empty<TVector>,
00064           boost::mpl::identity<LastEnrollerHelper<T> >,
00065           boost::mpl::identity<EnrollerHelper<T, typename boost::mpl::pop_back< TVector >::type > >
00066           >::type NextEnroller;
00067         NextEnroller::enroll(iReg,iT);
00068       }
00069     };
00070   
00071 }
00072 
00073 class SimActivityRegistryEnroller
00074 {
00075   
00076  public:
00077   SimActivityRegistryEnroller() {}
00078       //virtual ~SimActivityRegistryEnroller();
00079       typedef boost::mpl::vector<BeginOfJob,DDDWorld,BeginOfRun,BeginOfEvent,BeginOfTrack,BeginOfStep,G4Step,EndOfTrack,EndOfEvent,EndOfRun> Signals;
00080    
00081       // ---------- const member functions ---------------------
00082 
00083       // ---------- static member functions --------------------
00084       template<class T>
00085       static void enroll(SimActivityRegistry& iReg, T* iObj){
00086          enroller_helper::EnrollerHelper<T,Signals>::enroll(iReg,iObj);
00087       }
00088       // ---------- member functions ---------------------------
00089 
00090    private:
00091       SimActivityRegistryEnroller(const SimActivityRegistryEnroller&); // stop default
00092 
00093       const SimActivityRegistryEnroller& operator=(const SimActivityRegistryEnroller&); // stop default
00094 
00095       // ---------- member data --------------------------------
00096 
00097 };
00098 
00099 
00100 #endif