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