CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 <memory>
11 #include <typeinfo>
12 #include <type_traits>
13 #include <vector>
14 
15 namespace edm {
16 
17  //Need to specialize the case of std::vector<edm::Ptr<T>>
18  template <typename T>
19  class Ptr;
20 
21  namespace detail {
22  using no_tag = std::false_type; // type indicating FALSE
23  using yes_tag = std::true_type; // type indicating TRUE
24 
25  // valueTypeInfo_() will return typeid(T::value_type) if T::value_type is declared and typeid(void) otherwise.
26  // Definitions for the following struct and function templates are not needed; we only require the declarations.
27  template <typename T>
28  static yes_tag has_value_type(typename T::value_type*);
29  template <typename T>
30  static no_tag has_value_type(...);
31 
32  template <typename T>
34  static constexpr bool value = std::is_same<decltype(has_value_type<T>(nullptr)), yes_tag>::value;
35  };
37  struct getValueType;
38  template <typename T>
39  struct getValueType<T, true> {
40  std::type_info const& operator()() { return typeid(typename T::value_type); }
41  };
42  template <typename T>
43  struct getValueType<T, false> {
44  std::type_info const& operator()() { return typeid(void); }
45  };
46 
47  // memberTypeInfo_() will return typeid(T::member_type) if T::member_type is declared and typeid(void) otherwise.
48  // Definitions for the following struct and function templates are not needed; we only require the declarations.
49  template <typename T>
50  static yes_tag has_member_type(typename T::member_type*);
51  template <typename T>
52  static no_tag has_member_type(...);
53 
54  template <typename T>
56  static constexpr bool value = std::is_same<decltype(has_member_type<T>(nullptr)), yes_tag>::value;
57  };
59  struct getMemberType;
60  template <typename T>
61  struct getMemberType<T, true> {
62  std::type_info const& operator()() { return typeid(typename T::member_type); }
63  };
64  template <typename T>
65  struct getMemberType<T, false> {
66  std::type_info const& operator()() { return typeid(void); }
67  };
68 
69  template <typename T>
70  struct has_typedef_member_type<std::vector<edm::Ptr<T> > > {
71  static constexpr bool value = true;
72  };
73 
74  template <typename T>
75  struct getMemberType<std::vector<edm::Ptr<T> >, true> {
76  std::type_info const& operator()() { return typeid(T); }
77  };
78 
79  template <typename T, typename Deleter>
80  struct has_typedef_member_type<std::vector<std::unique_ptr<T, Deleter> > > {
81  static constexpr bool value = true;
82  };
83 
84  template <typename T, typename Deleter>
85  struct getMemberType<std::vector<std::unique_ptr<T, Deleter> >, true> {
86  std::type_info const& operator()() { return typeid(T); }
87  };
88 
89  // bool isMergeable_() will return true if T::mergeProduct(T const&) is declared and false otherwise
90  // bool mergeProduct_(WrapperBase const*) will merge products if T::mergeProduct(T const&) is defined
91  // Definitions for the following struct and function templates are not needed; we only require the declarations.
92  template <typename T, bool (T::*)(T const&)>
94  template <typename T>
96  template <typename T>
97  static no_tag has_mergeProduct(...);
98 
99  template <typename T>
101  static constexpr bool value = std::is_same<decltype(has_mergeProduct<T>(nullptr)), yes_tag>::value;
102  };
103 
106  template <typename T>
108  bool operator()() { return true; }
109  };
110  template <typename T>
112  bool operator()() { return false; }
113  };
116  template <typename T>
117  struct doMergeProduct<T, true> {
118  bool operator()(T& thisProduct, T const& newProduct) { return thisProduct.mergeProduct(newProduct); }
119  };
120  template <typename T>
121  struct doMergeProduct<T, false> {
122  bool operator()(T& thisProduct, T const& newProduct) {
123  return true; // Should never be called
124  }
125  };
126 
127  // bool hasIsProductEqual_() will return true if T::isProductEqual(T const&) const is declared and false otherwise
128  // bool isProductEqual _(WrapperBase const*) will call T::isProductEqual(T const&) if it is defined
129  // Definitions for the following struct and function templates are not needed; we only require the declarations.
130  template <typename T, bool (T::*)(T const&) const>
132  template <typename T>
134  template <typename T>
135  static no_tag has_isProductEqual(...);
136 
137  template <typename T>
139  static constexpr bool value = std::is_same<decltype(has_isProductEqual<T>(nullptr)), yes_tag>::value;
140  };
141 
144  template <typename T>
146  bool operator()() { return true; }
147  };
148  template <typename T>
150  bool operator()() { return false; }
151  };
154  template <typename T>
156  bool operator()(T const& thisProduct, T const& newProduct) { return thisProduct.isProductEqual(newProduct); }
157  };
158  template <typename T>
160  bool operator()(T const& thisProduct, T const& newProduct) {
161  return true; // Should never be called
162  }
163  };
164 
165  // bool hasSwap_() will return true if T::swap(T&) is declared and false otherwise
166  // void swapProduct_() will call T::swap(T&) if it is defined otherwise it does nothing
167  // Definitions for the following struct and function templates are not needed; we only require the declarations.
168  template <typename T, void (T::*)(T&)>
170  template <typename T>
172  template <typename T>
173  static no_tag has_swap(...);
174 
175  template <typename T>
177  static constexpr bool value = std::is_same<decltype(has_swap<T>(nullptr)), yes_tag>::value;
178  };
179 
182  template <typename T>
184  bool operator()() { return true; }
185  };
186  template <typename T>
188  bool operator()() { return false; }
189  };
192  template <typename T>
193  struct doSwapProduct<T, true> {
194  void operator()(T& thisProduct, T& newProduct) { thisProduct.swap(newProduct); }
195  };
196  template <typename T>
197  struct doSwapProduct<T, false> {
198  void operator()(T&, T&) {
199  return; // Should never be called
200  }
201  };
202  } // namespace detail
203 } // namespace edm
204 #endif
std::type_info const & operator()()
Definition: WrapperDetail.h:66
std::false_type no_tag
Definition: WrapperDetail.h:22
std::type_info const & operator()()
Definition: WrapperDetail.h:44
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)
void operator()(T &thisProduct, T &newProduct)
std::type_info const & operator()()
Definition: WrapperDetail.h:62
static yes_tag has_member_type(typename T::member_type *)
static constexpr bool value
std::true_type yes_tag
Definition: WrapperDetail.h:23
bool operator()(T const &thisProduct, T const &newProduct)
std::type_info const & operator()()
Definition: WrapperDetail.h:40
static yes_tag has_value_type(typename T::value_type *)
long double T
bool operator()(T &thisProduct, T const &newProduct)
static yes_tag has_swap(swap_function< T,&T::swap > *dummy)