CMS 3D CMS Logo

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