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  // void swap_or_assign(T& a, T& b) will swap if T::swap(T&) is defined and assign otherwise
24  // Definitions for the following struct and function templates are not needed; we only require the declarations.
25  template<typename T, void (T::*)(T&)> struct swap_function;
26  template<typename T> static yes_tag has_swap(swap_function<T, &T::swap>* dummy);
27  template<typename T> static no_tag has_swap(...);
28 
29  template<typename T>
31  static constexpr bool value = std::is_same<decltype(has_swap<T>(nullptr)), yes_tag>::value;
32  };
33 
35  template<typename T> struct doSwapOrAssign<T, true> {
36  void operator()(T& thisProduct, T& otherProduct) {
37  thisProduct.swap(otherProduct);
38  }
39  };
40  template<typename T> struct doSwapOrAssign<T, false> {
41  void operator()(T& thisProduct, T& otherProduct) {
42  thisProduct = otherProduct;
43  }
44  };
45 
46  // valueTypeInfo_() will return typeid(T::value_type) if T::value_type is declared and typeid(void) otherwise.
47  // Definitions for the following struct and function templates are not needed; we only require the declarations.
48  template<typename T> static yes_tag has_value_type(typename T::value_type*);
49  template<typename T> static no_tag has_value_type(...);
50 
51  template<typename T> struct has_typedef_value_type {
52  static constexpr bool value = std::is_same<decltype(has_value_type<T>(nullptr)), yes_tag>::value;
53  };
55  template<typename T> struct getValueType<T, true> {
56  std::type_info const& operator()() {
57  return typeid(typename T::value_type);
58  }
59  };
60  template<typename T> struct getValueType<T, false> {
61  std::type_info const& operator()() {
62  return typeid(void);
63  }
64  };
65 
66  // memberTypeInfo_() will return typeid(T::member_type) if T::member_type is declared and typeid(void) otherwise.
67  // Definitions for the following struct and function templates are not needed; we only require the declarations.
68  template<typename T> static yes_tag has_member_type(typename T::member_type*);
69  template<typename T> static no_tag has_member_type(...);
70 
71  template<typename T> struct has_typedef_member_type {
72  static constexpr bool value = std::is_same<decltype(has_member_type<T>(nullptr)), yes_tag>::value;
73  };
75  template<typename T> struct getMemberType<T, true> {
76  std::type_info const& operator()() {
77  return typeid(typename T::member_type);
78  }
79  };
80  template<typename T> struct getMemberType<T, false> {
81  std::type_info const& operator()() {
82  return typeid(void);
83  }
84  };
85 
86  template< typename T> struct has_typedef_member_type<std::vector<edm::Ptr<T> > > {
87  static constexpr bool value = true;
88  };
89 
90  template <typename T> struct getMemberType<std::vector<edm::Ptr<T> >, true> {
91  std::type_info const& operator()() {
92  return typeid(T);
93  }
94  };
95 
96  // bool isMergeable_() will return true if T::mergeProduct(T const&) is declared and false otherwise
97  // bool mergeProduct_(WrapperBase const*) will merge products if T::mergeProduct(T const&) is defined
98  // Definitions for the following struct and function templates are not needed; we only require the declarations.
99  template<typename T, bool (T::*)(T const&)> struct mergeProduct_function;
101  template<typename T> static no_tag has_mergeProduct(...);
102 
103  template<typename T>
105  static constexpr bool value =
106  std::is_same<decltype(has_mergeProduct<T>(nullptr)), yes_tag>::value;
107  };
108 
110  template<typename T> struct getHasMergeFunction<T, true> {
111  bool operator()() {
112  return true;
113  }
114  };
115  template<typename T> struct getHasMergeFunction<T, false> {
116  bool operator()() {
117  return false;
118  }
119  };
121  template<typename T> struct doMergeProduct<T, true> {
122  bool operator()(T& thisProduct, T const& newProduct) {
123  return thisProduct.mergeProduct(newProduct);
124  }
125  };
126  template<typename T> struct doMergeProduct<T, false> {
127  bool operator()(T& thisProduct, T const& newProduct) {
128  return true; // Should never be called
129  }
130  };
131 
132  // bool hasIsProductEqual_() will return true if T::isProductEqual(T const&) const is declared and false otherwise
133  // bool isProductEqual _(WrapperBase const*) will call T::isProductEqual(T const&) if it is defined
134  // Definitions for the following struct and function templates are not needed; we only require the declarations.
135  template<typename T, bool (T::*)(T const&) const> struct isProductEqual_function;
137  template<typename T> static no_tag has_isProductEqual(...);
138 
139  template<typename T>
141  static constexpr bool value =
142  std::is_same<decltype(has_isProductEqual<T>(nullptr)),yes_tag>::value;
143  };
144 
146  template<typename T> struct getHasIsProductEqual<T, true> {
147  bool operator()() {
148  return true;
149  }
150  };
151  template<typename T> struct getHasIsProductEqual<T, false> {
152  bool operator()() {
153  return false;
154  }
155  };
157  template<typename T> struct doIsProductEqual<T, true> {
158  bool operator()(T const& thisProduct, T const& newProduct) {
159  return thisProduct.isProductEqual(newProduct);
160  }
161  };
162  template<typename T> struct doIsProductEqual<T, false> {
163  bool operator()(T const& thisProduct, T const& newProduct) {
164  return true; // Should never be called
165  }
166  };
167  }
168 }
169 #endif
std::type_info const & operator()()
Definition: WrapperDetail.h:81
std::false_type no_tag
Definition: WrapperDetail.h:20
#define constexpr
std::type_info const & operator()()
Definition: WrapperDetail.h:61
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)
std::type_info const & operator()()
Definition: WrapperDetail.h:76
Definition: value.py:1
static yes_tag has_member_type(typename T::member_type *)
static constexpr bool value
Definition: WrapperDetail.h:31
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:56
void operator()(T &thisProduct, T &otherProduct)
Definition: WrapperDetail.h:41
static yes_tag has_value_type(typename T::value_type *)
long double T
void operator()(T &thisProduct, T &otherProduct)
Definition: WrapperDetail.h:36
bool operator()(T &thisProduct, T const &newProduct)
static yes_tag has_swap(swap_function< T,&T::swap > *dummy)