traits.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Common_traits_h
2 #define canvas_Persistency_Common_traits_h
3 
4 /*----------------------------------------------------------------------
5  Definition of traits templates used in the event data model.
6  ----------------------------------------------------------------------*/
7 
10 #include "cetlib/map_vector.h"
11 #include "cetlib/metaprogramming.h"
12 #include "cetlib_except/demangle.h"
13 
14 #include <deque>
15 #include <limits>
16 #include <list>
17 #include <map>
18 #include <set>
19 #include <string>
20 #include <type_traits>
21 #include <typeinfo>
22 #include <utility>
23 #include <vector>
24 
25 namespace art {
26 
27  // The trait struct template key_traits<K> is used to carry
28  // information relevant to the type K when used as a 'key' in
29  // PtrVector and its related classes and templates.
30  //
31  // The general case works only for integral types K; for more
32  // 'esoteric' types, one must introduce an explicit specialization.
33  // That specialization must initialize the static data member
34  // 'value'.
35 
36  template <class K>
37  struct key_traits {
38  using key_type = K;
39  static constexpr key_type value{
40  std::numeric_limits<typename key_traits<K>::key_type>::max()};
41  };
42 
43  // Partial specialization for std::pair
44  template <class U, class V>
45  struct key_traits<std::pair<U, V>> {
46  using key_type = std::pair<U, V>;
47  static const key_type value;
48  };
49 
50  // If we ever need to support instantiations of std::basic_string
51  // other than std::string, this is the place to do it.
52  // For value, we make a 1-character long string that contains an
53  // unprintable character; we are hoping nobody ever uses such a
54  // string as a legal key.
55  template <>
56  struct key_traits<std::string> {
58  static const key_type value;
59  };
60 
61  template <typename T, typename = void>
62  struct has_value_type : std::false_type {};
63 
64  template <typename T>
65  struct has_value_type<T, std::void_t<typename T::value_type>>
66  : std::true_type {
67  using element_type = typename T::value_type;
68  };
69 
70  template <typename T, typename = void>
71  struct has_mapped_type : std::false_type {};
72 
73  template <typename T>
74  struct has_mapped_type<T, std::void_t<typename T::mapped_type>>
75  : std::true_type {
76  using element_type = typename T::mapped_type;
77  };
78 
79  // A type supports a view if it has a nested 'value_type' or 'mapped_type'
80  // type name.
81  template <typename T, typename = void>
82  struct SupportsView : std::false_type {
83  static std::type_info const*
85  {
86  return nullptr;
87  }
88  };
89 
90  template <typename T>
91  struct SupportsView<
92  T,
93  std::enable_if_t<(has_value_type<T>::value && !has_mapped_type<T>::value)>>
94  : std::true_type {
96  static std::type_info const*
98  {
99  return &typeid(element_type);
100  }
101  };
102 
103  template <typename T>
104  struct SupportsView<T, std::enable_if_t<has_mapped_type<T>::value>>
105  : std::true_type {
107  static std::type_info const*
109  {
110  return &typeid(element_type);
111  }
112  };
113 
114  //
115  // The trait struct template has_fillView<T> is used to
116  // indicate whether or not the type T has a member function
117  //
118  // void T::fillView(std::vector<void const*>&) const
119  //
120  // We assume the 'general case' for T is to not support fillView.
121  // Classes which do support fillView must specialize this trait.
122  //
123 
124  template <typename T, typename = void>
125  struct has_fillView {};
126 
127  template <typename T>
128  struct has_fillView<
129  T,
130  cet::enable_if_function_exists_t<void (T::*)(std::vector<void const*>&),
131  &T::fillView>> {};
132 
133  template <typename T>
134  struct CannotFillView {
135  static void
136  fill(T const&, std::vector<void const*>&)
137  {
139  << "Product type " << cet::demangle_symbol(typeid(T).name())
140  << " has no fillView() capability.\n";
141  }
142  };
143 
144  template <class T, typename = void>
146 
147  template <typename T>
148  struct MaybeFillView<T, std::enable_if_t<has_fillView<T>::value>> {
149  static void
150  fill(T const& product, std::vector<void const*>& view)
151  {
152  product.fillView(view);
153  }
154  };
155 
156  template <class T, class A>
157  struct MaybeFillView<std::vector<T, A>> {
158  static void
159  fill(std::vector<T> const& product, std::vector<void const*>& view)
160  {
162  product, std::back_inserter(view), [](auto const& p) { return &p; });
163  }
164  };
165 
166  template <class A>
167  struct MaybeFillView<std::vector<bool, A>>
168  : CannotFillView<std::vector<bool, A>> {};
169 
170  template <class T, class A>
171  struct MaybeFillView<std::list<T, A>> {
172  static void
173  fill(std::list<T> const& product, std::vector<void const*>& view)
174  {
176  product, std::back_inserter(view), [](auto const& p) { return &p; });
177  }
178  };
179 
180  template <class T, class A>
181  struct MaybeFillView<std::deque<T, A>> {
182  static void
183  fill(std::deque<T> const& product, std::vector<void const*>& view)
184  {
186  product, std::back_inserter(view), [](auto const& p) { return &p; });
187  }
188  };
189 
190  template <class T, class A>
191  struct MaybeFillView<std::set<T, A>> {
192  static void
193  fill(std::set<T> const& product, std::vector<void const*>& view)
194  {
196  product, std::back_inserter(view), [](auto const& p) { return &p; });
197  }
198  };
199 
200  template <class T>
201  struct MaybeFillView<cet::map_vector<T>> {
202  static void
203  fill(cet::map_vector<T> const& product, std::vector<void const*>& view)
204  {
205  cet::transform_all(product, std::back_inserter(view), [](auto const& p) {
206  return &p.second;
207  });
208  }
209  };
210 
211  //
212  // The trait struct template has_setPtr<T> is used to
213  // indicate whether or not the type T has a member function
214  //
215  // void T::setPtr(const std::type_info&, void const*&) const
216  //
217  // We assume the 'general case' for T is to not support setPtr.
218  // Classes which do support setPtr must specialize this trait.
219  //
220 
221  template <class T>
222  struct has_setPtr : std::false_type {};
223  template <class T, class A>
224  struct has_setPtr<std::vector<T, A>> : std::true_type {};
225  template <class A>
226  struct has_setPtr<std::vector<bool, A>> : std::false_type {};
227  template <class T, class A>
228  struct has_setPtr<std::list<T, A>> : std::true_type {};
229  template <class T, class A>
230  struct has_setPtr<std::deque<T, A>> : std::true_type {};
231  template <class T, class A>
232  struct has_setPtr<std::set<T, A>> : std::true_type {};
233  template <class T>
234  struct has_setPtr<cet::map_vector<T>> : std::true_type {};
235 }
236 
237 #endif /* canvas_Persistency_Common_traits_h */
238 
239 // Local Variables:
240 // mode: c++
241 // End:
const XML_Char * name
Definition: expat.h:151
std::pair< U, V > key_type
Definition: traits.h:46
static const key_type value
Definition: traits.h:47
static void fill(cet::map_vector< T > const &product, std::vector< void const * > &view)
Definition: traits.h:203
const char * p
Definition: xmltok.h:285
static std::type_info const * type_id()
Definition: traits.h:97
enable_if_same_t< FT, decltype(f), R > enable_if_function_exists_t
static std::type_info const * type_id()
Definition: traits.h:84
Double_t K
static const key_type value
Definition: traits.h:58
static void fill(std::deque< T > const &product, std::vector< void const * > &view)
Definition: traits.h:183
static void fill(std::vector< T > const &product, std::vector< void const * > &view)
Definition: traits.h:159
const XML_Char int const XML_Char * value
Definition: expat.h:331
auto transform_all(Container &, OutputIt, UnaryOp)
typename has_mapped_type< T >::element_type element_type
Definition: traits.h:106
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
static void fill(T const &, std::vector< void const * > &)
Definition: traits.h:136
static void fill(std::set< T > const &product, std::vector< void const * > &view)
Definition: traits.h:193
Service to store calibration data products (CDP) in the SQLite3 metadatabase of a file...
Definition: FillParentInfo.h:8
double T
Definition: Xdiff_gwt.C:5
static void fill(T const &product, std::vector< void const * > &view)
Definition: traits.h:150
static void fill(std::list< T > const &product, std::vector< void const * > &view)
Definition: traits.h:173
T max(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:66
typename has_value_type< T >::element_type element_type
Definition: traits.h:95
enum BeamMode string