00001 #ifndef Notification_SimActivityRegistryEnroller_h
00002 #define Notification_SimActivityRegistryEnroller_h
00003
00004
00005
00006
00007
00016
00017
00018
00019
00020
00021
00022
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
00033 #include "SimG4Core/Notification/interface/Observer.h"
00034 #include "SimG4Core/Notification/interface/SimActivityRegistry.h"
00035
00036
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
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
00058
00059 Enrollment< typename boost::mpl::deref< typename boost::mpl::prior< typename boost::mpl::end< TVector >::type >::type >::type >::enroll(iReg, iT );
00060
00061
00062
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
00079 typedef boost::mpl::vector<BeginOfJob,DDDWorld,BeginOfRun,BeginOfEvent,BeginOfTrack,BeginOfStep,G4Step,EndOfTrack,EndOfEvent,EndOfRun> Signals;
00080
00081
00082
00083
00084 template<class T>
00085 static void enroll(SimActivityRegistry& iReg, T* iObj){
00086 enroller_helper::EnrollerHelper<T,Signals>::enroll(iReg,iObj);
00087 }
00088
00089
00090 private:
00091 SimActivityRegistryEnroller(const SimActivityRegistryEnroller&);
00092
00093 const SimActivityRegistryEnroller& operator=(const SimActivityRegistryEnroller&);
00094
00095
00096
00097 };
00098
00099
00100 #endif