CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/DataFormats/Candidate/interface/component.h

Go to the documentation of this file.
00001 #ifndef Candidate_component_h
00002 #define Candidate_component_h
00003 
00012 #include "FWCore/Utilities/interface/Exception.h"
00013 
00014 namespace reco {
00015 
00016   class Candidate;
00017 
00018   struct DefaultComponentTag { };
00019   
00020   namespace componenthelper {
00021 
00022     struct SingleComponentTag { };
00023 
00024     struct MultipleComponentsTag { };
00025 
00026     template<typename C, typename T, T (C::*F)() const>
00027     struct SingleComponent {
00028       static T get( const Candidate & c ) {
00029         const C * dc = dynamic_cast<const C *>( & c );
00030         if ( dc == 0 ) return T();
00031         return (dc->*F)();
00032       }
00033     };
00034 
00035     template<typename C, typename T, T (C::*F)( size_t ) const , size_t (C::*S)() const>
00036     struct MultipleComponents {
00037       static size_t numberOf( const Candidate & c ) { 
00038         const C * dc = dynamic_cast<const C *>( & c );
00039         if ( dc == 0 ) return 0;
00040         return (dc->*S)(); 
00041       }
00042       static T get( const Candidate & c, size_t i ) {
00043         const C * dc = dynamic_cast<const C *>( & c );
00044         if ( dc == 0 ) return T();
00045         if ( i < (dc->*S)() ) return (dc->*F)( i );
00046         else throw cms::Exception( "Error" ) << "index " << i << " out ot range";
00047       }
00048     };
00049 
00050   }
00051 
00052   template<typename T, typename M, typename Tag = DefaultComponentTag>
00053   struct component { };
00054 
00055   template<typename T>
00056   inline T get( const Candidate & c ) {
00057     return component<T, componenthelper::SingleComponentTag>::type::get( c );
00058   }
00059 
00060   template<typename T, typename Tag>
00061   inline T get( const Candidate & c ) {
00062     return component<T, componenthelper::SingleComponentTag, Tag>::type::get( c );
00063   }
00064 
00065   template<typename T>
00066   inline T get( const Candidate & c, size_t i ) {
00067     return component<T, componenthelper::MultipleComponentsTag>::type::get( c, i );
00068   }
00069 
00070   template<typename T, typename Tag>
00071   inline T get( const Candidate & c, size_t i ) {
00072     return component<T, componenthelper::MultipleComponentsTag, Tag>::type::get( c, i );
00073   }
00074 
00075   template<typename T>
00076   inline size_t numberOf( const Candidate & c ) {
00077     return component<T, componenthelper::MultipleComponentsTag>::type::numberOf( c );
00078   }
00079 
00080   template<typename T, typename Tag>
00081   inline size_t numberOf( const Candidate & c ) {
00082     return component<T, componenthelper::MultipleComponentsTag, Tag>::type::numberOf( c );
00083   }
00084 
00085 }
00086 
00087 #define GET_CANDIDATE_COMPONENT( CAND, TYPE, FUN, TAG ) \
00088   template<> \
00089   struct  component<TYPE, componenthelper::SingleComponentTag, TAG> { \
00090     typedef componenthelper::SingleComponent<CAND, TYPE, & CAND::FUN> type; \
00091   }
00092 
00093 #define GET_DEFAULT_CANDIDATE_COMPONENT( CAND, TYPE, FUN ) \
00094   template<> \
00095   struct  component<TYPE, componenthelper::SingleComponentTag, DefaultComponentTag> { \
00096     typedef componenthelper::SingleComponent<CAND, TYPE, & CAND::FUN> type; \
00097   }
00098 
00099 #define GET_CANDIDATE_MULTIPLECOMPONENTS( CAND, TYPE, FUN, SIZE, TAG ) \
00100   template<> \
00101   struct  component<TYPE, componenthelper::MultipleComponentsTag, TAG> { \
00102     typedef componenthelper::MultipleComponents<CAND, TYPE, & CAND::FUN, & CAND::SIZE> type; \
00103   }
00104 
00105 #define GET_DEFAULT_CANDIDATE_MULTIPLECOMPONENTS( CAND, TYPE, FUN, SIZE ) \
00106   template<> \
00107   struct  component<TYPE, componenthelper::MultipleComponentsTag, DefaultComponentTag> { \
00108     typedef componenthelper::MultipleComponents<CAND, TYPE, & CAND::FUN, & CAND::SIZE> type; \
00109   }
00110 
00111 #endif