LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
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 
9 #include "cetlib/container_algorithms.h"
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> {
59  using key_type = 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 
69  template <typename T>
70  struct has_value_type<T, cet::enable_if_type_exists_t<typename T::value_type>>
71  : std::true_type {
72  using element_type = typename T::value_type;
73  };
74 
75  // ... Check for mapped_type
76  template <typename T, typename = void>
77  struct has_mapped_type : std::false_type {
78  };
79 
80  template <typename T>
81  struct has_mapped_type<T,
82  cet::enable_if_type_exists_t<typename T::mapped_type>>
83  : std::true_type {
84  using element_type = typename T::mapped_type;
85  };
86 
87  // A type supports a view if it has a nested 'value_type' or
88  // 'mapped_type' type name.
89  template <typename T, typename = void>
90  struct SupportsView : std::false_type {
91  static std::type_info const*
93  {
94  return nullptr;
95  }
96  };
97 
98  template <typename T>
99  struct SupportsView<
100  T,
101  std::enable_if_t<(has_value_type<T>::value && !has_mapped_type<T>::value)>>
102  : std::true_type {
104  static std::type_info const*
106  {
107  return &typeid(element_type);
108  }
109  };
110 
111  template <typename T>
112  struct SupportsView<T, std::enable_if_t<has_mapped_type<T>::value>>
113  : std::true_type {
115  static std::type_info const*
117  {
118  return &typeid(element_type);
119  }
120  };
121 
122  //------------------------------------------------------------
123  // The trait struct template has_fillView<T> is used to
124  // indicate whether or not the type T has a member function
125  //
126  // void T::fillView(std::vector<void const*>&) const
127  //
128  // We assume the 'general case' for T is to not support fillView.
129  // Classes which do support fillView must specialize this trait.
130  //------------------------------------------------------------
131 
132  // has_fillView
133  template <typename T, typename = void>
134  struct has_fillView {
135  };
136 
137  template <typename T>
138  struct has_fillView<
139  T,
140  cet::enable_if_function_exists_t<void (T::*)(std::vector<void const*>&),
141  &T::fillView>> {
142  };
143 
144  template <typename T>
145  struct CannotFillView {
146  static void
147  fill(T const&, std::vector<void const*>&)
148  {
150  << "Product type " << cet::demangle_symbol(typeid(T).name())
151  << " has no fillView() capability.\n";
152  }
153  };
154 
155  template <class T, typename = void>
157  };
158 
159  template <typename T>
160  struct MaybeFillView<T, std::enable_if_t<has_fillView<T>::value>> {
161  static void
162  fill(T const& product, std::vector<void const*>& view)
163  {
164  product.fillView(view);
165  }
166  };
167 
168  template <class T, class A>
169  struct MaybeFillView<std::vector<T, A>> {
170  static void
171  fill(std::vector<T> const& product, std::vector<void const*>& view)
172  {
173  cet::transform_all(
174  product, std::back_inserter(view), [](auto const& p) { return &p; });
175  }
176  };
177 
178  template <class A>
179  struct MaybeFillView<std::vector<bool, A>>
180  : CannotFillView<std::vector<bool, A>> {
181  };
182 
183  template <class T, class A>
184  struct MaybeFillView<std::list<T, A>> {
185  static void
186  fill(std::list<T> const& product, std::vector<void const*>& view)
187  {
188  cet::transform_all(
189  product, std::back_inserter(view), [](auto const& p) { return &p; });
190  }
191  };
192 
193  template <class T, class A>
194  struct MaybeFillView<std::deque<T, A>> {
195  static void
196  fill(std::deque<T> const& product, std::vector<void const*>& view)
197  {
198  cet::transform_all(
199  product, std::back_inserter(view), [](auto const& p) { return &p; });
200  }
201  };
202 
203  template <class T, class A>
204  struct MaybeFillView<std::set<T, A>> {
205  static void
206  fill(std::set<T> const& product, std::vector<void const*>& view)
207  {
208  cet::transform_all(
209  product, std::back_inserter(view), [](auto const& p) { return &p; });
210  }
211  };
212 
213  template <class T>
214  struct MaybeFillView<cet::map_vector<T>> {
215  static void
216  fill(cet::map_vector<T> const& product, std::vector<void const*>& view)
217  {
218  cet::transform_all(product, std::back_inserter(view), [](auto const& p) {
219  return &p.second;
220  });
221  }
222  };
223 
224  //------------------------------------------------------------
225  // The trait struct template has_setPtr<T> is used to
226  // indicate whether or not the type T has a member function
227  //
228  // void T::setPtr(const std::type_info&, void const*&) const
229  //
230  // We assume the 'general case' for T is to not support setPtr.
231  // Classes which do support setPtr must specialize this trait.
232  //------------------------------------------------------------
233 
234  template <class T>
235  struct has_setPtr : std::false_type {
236  };
237 
238  template <class T, class A>
239  struct has_setPtr<std::vector<T, A>> : std::true_type {
240  };
241 
242  template <class A>
243  struct has_setPtr<std::vector<bool, A>> : std::false_type {
244  };
245 
246  template <class T, class A>
247  struct has_setPtr<std::list<T, A>> : std::true_type {
248  };
249 
250  template <class T, class A>
251  struct has_setPtr<std::deque<T, A>> : std::true_type {
252  };
253 
254  template <class T, class A>
255  struct has_setPtr<std::set<T, A>> : std::true_type {
256  };
257 
258  template <class T>
259  struct has_setPtr<cet::map_vector<T>> : std::true_type {
260  };
261 }
262 
263 #endif /* canvas_Persistency_Common_traits_h */
264 
265 // Local Variables:
266 // mode: c++
267 // End:
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:216
STL namespace.
static std::type_info const * type_id()
Definition: traits.h:105
static std::type_info const * type_id()
Definition: traits.h:92
Double_t K
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
static void fill(std::deque< T > const &product, std::vector< void const * > &view)
Definition: traits.h:196
static void fill(std::vector< T > const &product, std::vector< void const * > &view)
Definition: traits.h:171
Int_t max
Definition: plot.C:27
typename enable_if_type_exists< T, R >::type enable_if_type_exists_t
static const key_type value
Definition: traits.h:60
typename has_mapped_type< T >::element_type element_type
Definition: traits.h:114
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
static void fill(T const &, std::vector< void const * > &)
Definition: traits.h:147
static void fill(std::set< T > const &product, std::vector< void const * > &view)
Definition: traits.h:206
static constexpr key_type value
Definition: traits.h:40
HLT enums.
static void fill(T const &product, std::vector< void const * > &view)
Definition: traits.h:162
static void fill(std::list< T > const &product, std::vector< void const * > &view)
Definition: traits.h:186
typename has_value_type< T >::element_type element_type
Definition: traits.h:103