CMS 3D CMS Logo

WrapperDetail.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_WrapperDetail_h
2 #define DataFormats_Common_WrapperDetail_h
3 
4 /*----------------------------------------------------------------------
5 
6 WrapperDetail: Metafunction support for compile-time selection of code.
7 
8 ----------------------------------------------------------------------*/
9 
10 #include <typeinfo>
11 #include <type_traits>
12 #include <vector>
13 
14 namespace edm {
15 
16  //Need to specialize the case of std::vector<edm::Ptr<T>>
17  template<typename T> class Ptr;
18 
19  namespace detail {
20  using no_tag = std::false_type; // type indicating FALSE
21  using yes_tag = std::true_type; // type indicating TRUE
22 
23  // valueTypeInfo_() will return typeid(T::value_type) if T::value_type is declared and typeid(void) otherwise.
24  // Definitions for the following struct and function templates are not needed; we only require the declarations.
25  template<typename T> static yes_tag has_value_type(typename T::value_type*);
26  template<typename T> static no_tag has_value_type(...);
27 
28  template<typename T> struct has_typedef_value_type {
29  static constexpr bool value = std::is_same<decltype(has_value_type<T>(nullptr)), yes_tag>::value;
30  };
32  template<typename T> struct getValueType<T, true> {
33  std::type_info const& operator()() {
34  return typeid(typename T::value_type);
35  }
36  };
37  template<typename T> struct getValueType<T, false> {
38  std::type_info const& operator()() {
39  return typeid(void);
40  }
41  };
42 
43  // memberTypeInfo_() will return typeid(T::member_type) if T::member_type is declared and typeid(void) otherwise.
44  // Definitions for the following struct and function templates are not needed; we only require the declarations.
45  template<typename T> static yes_tag has_member_type(typename T::member_type*);
46  template<typename T> static no_tag has_member_type(...);
47 
48  template<typename T> struct has_typedef_member_type {
49  static constexpr bool value = std::is_same<decltype(has_member_type<T>(nullptr)), yes_tag>::value;
50  };
52  template<typename T> struct getMemberType<T, true> {
53  std::type_info const& operator()() {
54  return typeid(typename T::member_type);
55  }
56  };
57  template<typename T> struct getMemberType<T, false> {
58  std::type_info const& operator()() {
59  return typeid(void);
60  }
61  };
62 
63  template< typename T> struct has_typedef_member_type<std::vector<edm::Ptr<T> > > {
64  static constexpr bool value = true;
65  };
66 
67  template <typename T> struct getMemberType<std::vector<edm::Ptr<T> >, true> {
68  std::type_info const& operator()() {
69  return typeid(T);
70  }
71  };
72 
73  // bool isMergeable_() will return true if T::mergeProduct(T const&) is declared and false otherwise
74  // bool mergeProduct_(WrapperBase const*) will merge products if T::mergeProduct(T const&) is defined
75  // Definitions for the following struct and function templates are not needed; we only require the declarations.
76  template<typename T, bool (T::*)(T const&)> struct mergeProduct_function;
78  template<typename T> static no_tag has_mergeProduct(...);
79 
80  template<typename T>
82  static constexpr bool value =
83  std::is_same<decltype(has_mergeProduct<T>(nullptr)), yes_tag>::value;
84  };
85 
87  template<typename T> struct getHasMergeFunction<T, true> {
88  bool operator()() {
89  return true;
90  }
91  };
92  template<typename T> struct getHasMergeFunction<T, false> {
93  bool operator()() {
94  return false;
95  }
96  };
98  template<typename T> struct doMergeProduct<T, true> {
99  bool operator()(T& thisProduct, T const& newProduct) {
100  return thisProduct.mergeProduct(newProduct);
101  }
102  };
103  template<typename T> struct doMergeProduct<T, false> {
104  bool operator()(T& thisProduct, T const& newProduct) {
105  return true; // Should never be called
106  }
107  };
108 
109  // bool hasIsProductEqual_() will return true if T::isProductEqual(T const&) const is declared and false otherwise
110  // bool isProductEqual _(WrapperBase const*) will call T::isProductEqual(T const&) if it is defined
111  // Definitions for the following struct and function templates are not needed; we only require the declarations.
112  template<typename T, bool (T::*)(T const&) const> struct isProductEqual_function;
114  template<typename T> static no_tag has_isProductEqual(...);
115 
116  template<typename T>
118  static constexpr bool value =
119  std::is_same<decltype(has_isProductEqual<T>(nullptr)),yes_tag>::value;
120  };
121 
123  template<typename T> struct getHasIsProductEqual<T, true> {
124  bool operator()() {
125  return true;
126  }
127  };
128  template<typename T> struct getHasIsProductEqual<T, false> {
129  bool operator()() {
130  return false;
131  }
132  };
134  template<typename T> struct doIsProductEqual<T, true> {
135  bool operator()(T const& thisProduct, T const& newProduct) {
136  return thisProduct.isProductEqual(newProduct);
137  }
138  };
139  template<typename T> struct doIsProductEqual<T, false> {
140  bool operator()(T const& thisProduct, T const& newProduct) {
141  return true; // Should never be called
142  }
143  };
144  }
145 }
146 #endif
std::type_info const & operator()()
Definition: WrapperDetail.h:58
std::false_type no_tag
Definition: WrapperDetail.h:20
#define constexpr
std::type_info const & operator()()
Definition: WrapperDetail.h:38
static yes_tag has_isProductEqual(isProductEqual_function< T,&T::isProductEqual > *dummy)
static yes_tag has_mergeProduct(mergeProduct_function< T,&T::mergeProduct > *dummy)
bool operator()(T const &thisProduct, T const &newProduct)
bool operator()(T &thisProduct, T const &newProduct)
Definition: WrapperDetail.h:99
std::type_info const & operator()()
Definition: WrapperDetail.h:53
Definition: value.py:1
static yes_tag has_member_type(typename T::member_type *)
std::true_type yes_tag
Definition: WrapperDetail.h:21
bool operator()(T const &thisProduct, T const &newProduct)
HLT enums.
std::type_info const & operator()()
Definition: WrapperDetail.h:33
static yes_tag has_value_type(typename T::value_type *)
long double T
bool operator()(T &thisProduct, T const &newProduct)