1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#ifndef Candidate_component_h
#define Candidate_component_h
/** \class reco::component
*
* Generic accessor to components of a Candidate
*
* \author Luca Lista, INFN
*
*
*/
#include "FWCore/Utilities/interface/Exception.h"
namespace reco {
class Candidate;
struct DefaultComponentTag {};
namespace componenthelper {
struct SingleComponentTag {};
struct MultipleComponentsTag {};
template <typename C, typename T, T (C::*F)() const>
struct SingleComponent {
static T get(const Candidate &c) {
const C *dc = dynamic_cast<const C *>(&c);
if (dc == nullptr)
return T();
return (dc->*F)();
}
};
template <typename C, typename T, T (C::*F)(size_t) const, size_t (C::*S)() const>
struct MultipleComponents {
static size_t numberOf(const Candidate &c) {
const C *dc = dynamic_cast<const C *>(&c);
if (dc == nullptr)
return 0;
return (dc->*S)();
}
static T get(const Candidate &c, size_t i) {
const C *dc = dynamic_cast<const C *>(&c);
if (dc == nullptr)
return T();
if (i < (dc->*S)())
return (dc->*F)(i);
else
throw cms::Exception("Error") << "index " << i << " out ot range";
}
};
} // namespace componenthelper
template <typename T, typename M, typename Tag = DefaultComponentTag>
struct component {};
template <typename T>
inline T get(const Candidate &c) {
return component<T, componenthelper::SingleComponentTag>::type::get(c);
}
template <typename T, typename Tag>
inline T get(const Candidate &c) {
return component<T, componenthelper::SingleComponentTag, Tag>::type::get(c);
}
template <typename T>
inline T get(const Candidate &c, size_t i) {
return component<T, componenthelper::MultipleComponentsTag>::type::get(c, i);
}
template <typename T, typename Tag>
inline T get(const Candidate &c, size_t i) {
return component<T, componenthelper::MultipleComponentsTag, Tag>::type::get(c, i);
}
template <typename T>
inline size_t numberOf(const Candidate &c) {
return component<T, componenthelper::MultipleComponentsTag>::type::numberOf(c);
}
template <typename T, typename Tag>
inline size_t numberOf(const Candidate &c) {
return component<T, componenthelper::MultipleComponentsTag, Tag>::type::numberOf(c);
}
} // namespace reco
#define GET_CANDIDATE_COMPONENT(CAND, TYPE, FUN, TAG) \
template <> \
struct component<TYPE, componenthelper::SingleComponentTag, TAG> { \
typedef componenthelper::SingleComponent<CAND, TYPE, &CAND::FUN> type; \
}
#define GET_DEFAULT_CANDIDATE_COMPONENT(CAND, TYPE, FUN) \
template <> \
struct component<TYPE, componenthelper::SingleComponentTag, DefaultComponentTag> { \
typedef componenthelper::SingleComponent<CAND, TYPE, &CAND::FUN> type; \
}
#define GET_CANDIDATE_MULTIPLECOMPONENTS(CAND, TYPE, FUN, SIZE, TAG) \
template <> \
struct component<TYPE, componenthelper::MultipleComponentsTag, TAG> { \
typedef componenthelper::MultipleComponents<CAND, TYPE, &CAND::FUN, &CAND::SIZE> type; \
}
#define GET_DEFAULT_CANDIDATE_MULTIPLECOMPONENTS(CAND, TYPE, FUN, SIZE) \
template <> \
struct component<TYPE, componenthelper::MultipleComponentsTag, DefaultComponentTag> { \
typedef componenthelper::MultipleComponents<CAND, TYPE, &CAND::FUN, &CAND::SIZE> type; \
}
#endif
|