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