File indexing completed on 2023-03-17 10:49:17
0001 #ifndef Candidate_component_h
0002 #define Candidate_component_h
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "FWCore/Utilities/interface/Exception.h"
0012
0013 namespace reco {
0014
0015 class Candidate;
0016
0017 struct DefaultComponentTag {};
0018
0019 namespace componenthelper {
0020
0021 struct SingleComponentTag {};
0022
0023 struct MultipleComponentsTag {};
0024
0025 template <typename C, typename T, T (C::*F)() const>
0026 struct SingleComponent {
0027 static T get(const Candidate &c) {
0028 const C *dc = dynamic_cast<const C *>(&c);
0029 if (dc == nullptr)
0030 return T();
0031 return (dc->*F)();
0032 }
0033 };
0034
0035 template <typename C, typename T, T (C::*F)(size_t) const, size_t (C::*S)() const>
0036 struct MultipleComponents {
0037 static size_t numberOf(const Candidate &c) {
0038 const C *dc = dynamic_cast<const C *>(&c);
0039 if (dc == nullptr)
0040 return 0;
0041 return (dc->*S)();
0042 }
0043 static T get(const Candidate &c, size_t i) {
0044 const C *dc = dynamic_cast<const C *>(&c);
0045 if (dc == nullptr)
0046 return T();
0047 if (i < (dc->*S)())
0048 return (dc->*F)(i);
0049 else
0050 throw cms::Exception("Error") << "index " << i << " out ot range";
0051 }
0052 };
0053
0054 }
0055
0056 template <typename T, typename M, typename Tag = DefaultComponentTag>
0057 struct component {};
0058
0059 template <typename T>
0060 inline T get(const Candidate &c) {
0061 return component<T, componenthelper::SingleComponentTag>::type::get(c);
0062 }
0063
0064 template <typename T, typename Tag>
0065 inline T get(const Candidate &c) {
0066 return component<T, componenthelper::SingleComponentTag, Tag>::type::get(c);
0067 }
0068
0069 template <typename T>
0070 inline T get(const Candidate &c, size_t i) {
0071 return component<T, componenthelper::MultipleComponentsTag>::type::get(c, i);
0072 }
0073
0074 template <typename T, typename Tag>
0075 inline T get(const Candidate &c, size_t i) {
0076 return component<T, componenthelper::MultipleComponentsTag, Tag>::type::get(c, i);
0077 }
0078
0079 template <typename T>
0080 inline size_t numberOf(const Candidate &c) {
0081 return component<T, componenthelper::MultipleComponentsTag>::type::numberOf(c);
0082 }
0083
0084 template <typename T, typename Tag>
0085 inline size_t numberOf(const Candidate &c) {
0086 return component<T, componenthelper::MultipleComponentsTag, Tag>::type::numberOf(c);
0087 }
0088
0089 }
0090
0091 #define GET_CANDIDATE_COMPONENT(CAND, TYPE, FUN, TAG) \
0092 template <> \
0093 struct component<TYPE, componenthelper::SingleComponentTag, TAG> { \
0094 typedef componenthelper::SingleComponent<CAND, TYPE, &CAND::FUN> type; \
0095 }
0096
0097 #define GET_DEFAULT_CANDIDATE_COMPONENT(CAND, TYPE, FUN) \
0098 template <> \
0099 struct component<TYPE, componenthelper::SingleComponentTag, DefaultComponentTag> { \
0100 typedef componenthelper::SingleComponent<CAND, TYPE, &CAND::FUN> type; \
0101 }
0102
0103 #define GET_CANDIDATE_MULTIPLECOMPONENTS(CAND, TYPE, FUN, SIZE, TAG) \
0104 template <> \
0105 struct component<TYPE, componenthelper::MultipleComponentsTag, TAG> { \
0106 typedef componenthelper::MultipleComponents<CAND, TYPE, &CAND::FUN, &CAND::SIZE> type; \
0107 }
0108
0109 #define GET_DEFAULT_CANDIDATE_MULTIPLECOMPONENTS(CAND, TYPE, FUN, SIZE) \
0110 template <> \
0111 struct component<TYPE, componenthelper::MultipleComponentsTag, DefaultComponentTag> { \
0112 typedef componenthelper::MultipleComponents<CAND, TYPE, &CAND::FUN, &CAND::SIZE> type; \
0113 }
0114
0115 #endif