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