Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:52:54

0001 #ifndef Candidate_component_h
0002 #define Candidate_component_h
0003 /** \class reco::component

0004  *

0005  * Generic accessor to components of a Candidate 

0006  *

0007  * \author Luca Lista, INFN

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   }  // namespace componenthelper

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 }  // namespace reco

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