Wrapper.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Common_Wrapper_h
2 #define canvas_Persistency_Common_Wrapper_h
3 // vim: set sw=2:
4 
5 // =====================================================================
6 // Wrapper: A class template that inherits from art::EDProduct, thus
7 // providing the representation needed for providing products
8 // of type T. Each instantiation also includes:
9 // - a Boolean value corresponding to the presence of the
10 // product in the file
11 // - the RangeSet corresponding to the set of events
12 // processed in creating the product.
13 // =====================================================================
14 
20 #include "cetlib/metaprogramming.h"
21 #include "cetlib_except/demangle.h"
22 
23 #include <memory>
24 #include <string>
25 #include <vector>
26 
27 namespace art {
28  template <typename T>
30 
31  template <typename T>
32  class Wrapper;
33 
34  // Implementation detail declarations.
35  namespace detail {
36 
38 
39  // has_size_member
40  template <typename T, typename = void>
41  struct has_size_member : std::false_type {};
42 
43  template <typename T>
45  T,
46  enable_if_function_exists_t<size_t (T::*)() const, &T::size>>
47  : std::true_type {};
48 
49  // has_makePartner_member
50  template <typename T, typename = void>
51  struct has_makePartner_member : std::false_type {};
52 
53  template <typename T>
55  T,
56  enable_if_function_exists_t<std::unique_ptr<EDProduct> (T::*)(
57  std::type_info const&) const,
58  &T::makePartner>> : std::true_type {};
59  }
60 
62  struct productSize;
63 
64  template <typename T>
65  struct DoMakePartner;
66 
67  template <typename T>
69 
70  template <typename T>
71  struct DoSetPtr;
72 
73  template <typename T>
74  struct DoNotSetPtr;
75 }
76 
77 ////////////////////////////////////////////////////////////////////////
78 // Definition of art::Wrapper<T>
79 template <typename T>
80 class art::Wrapper : public art::EDProduct {
81 public:
82  Wrapper() = default;
83 
84  explicit Wrapper(std::unique_ptr<T> ptr);
85  virtual ~Wrapper() = default;
86 
87  T const* product() const;
88  T const* operator->() const;
89 
90  // MUST UPDATE WHEN CLASS IS CHANGED!
91  static short
93  {
94  return 11;
95  }
96 
97 private:
98  void fillView(std::vector<void const*>& view) const override;
99 
100  std::string productSize() const override;
101  void do_combine(EDProduct* product) override;
102 
103  void do_setRangeSetID(unsigned) override;
104  unsigned do_getRangeSetID() const override;
105 
106  std::unique_ptr<EDProduct> do_makePartner(
107  std::type_info const& wanted_type) const override;
108 
109  std::unique_ptr<EDProduct> do_createEmptySampledProduct(
110  InputTag const& tag) const override;
111 
112  template <typename>
113  friend struct prevent_recursion;
114 
115  void do_insertIfSampledProduct(std::string const& dataset,
116  SubRunID const& id,
117  std::unique_ptr<EDProduct> product) override;
118 
119  bool
120  isPresent_() const override
121  {
122  return present;
123  }
124  std::type_info const* typeInfo_() const override;
125 
126  void do_setPtr(std::type_info const& toType,
127  unsigned long index,
128  void const*& ptr) const override;
129 
130  void do_getElementAddresses(std::type_info const& toType,
131  std::vector<unsigned long> const& indices,
132  std::vector<void const*>& ptr) const override;
133 
134  T&& refOrThrow(T* ptr);
135 
136  bool present{false};
137  unsigned rangeSetID{-1u};
138  T obj{};
139 
140 }; // Wrapper<>
141 
142 ////////////////////////////////////////////////////////////////////////
143 // Implementation details.
144 
149 
150 #include "boost/lexical_cast.hpp"
153 #include <memory>
154 #include <type_traits>
155 
156 #include <deque>
157 #include <list>
158 #include <set>
159 #include <string>
160 #include <typeinfo>
161 #include <vector>
162 
163 ////////////////////////////////////////////////////////////////////////
164 // Wrapper member functions.
165 template <typename T>
166 art::Wrapper<T>::Wrapper(std::unique_ptr<T> ptr)
167  : present{ptr.get() != 0}, rangeSetID{-1u}, obj(refOrThrow(ptr.get()))
168 {}
169 
170 template <typename T>
171 T const*
173 {
174  return present ? &obj : nullptr;
175 }
176 
177 template <typename T>
179 {
180  return product();
181 }
182 
183 template <typename T>
184 std::type_info const*
186 {
187  return SupportsView<T>::type_id();
188 }
189 
190 template <typename T>
191 void
192 art::Wrapper<T>::fillView(std::vector<void const*>& view) const
193 {
195 }
196 
197 template <typename T>
200 {
201  return art::productSize<T>()(obj);
202 }
203 
204 template <typename T>
205 void
207 {
208  if (!p->isPresent())
209  return;
210 
211  auto wp = static_cast<Wrapper<T>*>(p);
213 
214  // The presence for the combined product is 'true', if we get this
215  // far.
216  present = true;
217 }
218 
219 template <typename T>
220 void
222 {
223  rangeSetID = id;
224 }
225 
226 template <typename T>
227 unsigned
229 {
230  return rangeSetID;
231 }
232 
233 template <typename T>
234 std::unique_ptr<art::EDProduct>
235 art::Wrapper<T>::do_makePartner(std::type_info const& wanted_wrapper) const
236 {
237  std::unique_ptr<art::EDProduct> retval;
241  maybe_maker;
242  retval = maybe_maker(obj, wanted_wrapper);
243  return retval;
244 }
245 
246 namespace art {
247  template <typename T>
248  struct prevent_recursion {
249  static std::unique_ptr<EDProduct>
251  {
252  auto emptySampledProduct = std::make_unique<Sampled<T>>(tag);
253  return std::make_unique<Wrapper<Sampled<T>>>(move(emptySampledProduct));
254  }
255 
256  [[noreturn]] static void
258  std::string const& dataset,
259  SubRunID const&,
260  std::unique_ptr<EDProduct>)
261  {
263  << "An attempt was made to insert a product from dataset '" << dataset
264  << "'\ninto a non-sampled product of type '"
265  << cet::demangle_symbol(typeid(T).name()) << "'.\n"
266  << "Please contact artists@fnal.gov for guidance.";
267  }
268  };
269 
270  template <typename T>
272  [[noreturn]] static std::unique_ptr<EDProduct>
274  {
276  << "An attempt was made to create an empty sampled product\n"
277  << "for a sampled product. This type of recursion is not allowed.\n"
278  << "Please contact artists@fnal.gov for guidance.";
279  }
280 
281  static void
283  std::string const& dataset,
284  SubRunID const& id,
285  std::unique_ptr<EDProduct> product)
286  {
287  auto& wp = dynamic_cast<Wrapper<T>&>(*product);
288  obj.insert(dataset, id, std::move(wp.obj));
289  }
290  };
291 }
292 
293 template <typename T>
294 std::unique_ptr<art::EDProduct>
296 {
298 }
299 
300 template <typename T>
301 void
303  SubRunID const& id,
304  std::unique_ptr<EDProduct> product)
305 {
307  obj, dataset, id, move(product));
308 }
309 
310 template <typename T>
311 inline void
312 art::Wrapper<T>::do_setPtr(std::type_info const& toType,
313  unsigned long index,
314  void const*& ptr) const
315 {
317  maybe_filler;
318  maybe_filler(this->obj, toType, index, ptr);
319 }
320 
321 template <typename T>
322 inline void
324  std::type_info const& toType,
325  std::vector<unsigned long> const& indices,
326  std::vector<void const*>& ptrs) const
327 {
329  maybe_filler;
330  maybe_filler(this->obj, toType, indices, ptrs);
331 }
332 
333 template <typename T>
334 inline T&&
336 {
337  if (ptr) {
338  return std::move(*ptr);
339  } else {
341  << "Attempt to construct " << cet::demangle_symbol(typeid(*this).name())
342  << " from nullptr.\n";
343  }
344 }
345 
346 ////////////////////////////////////////////////////////////////////////
347 // Metafunction support for compile-time selection of code used in
348 // Wrapper implementation.
349 
350 namespace art {
351 
352  template <typename T>
353  struct productSize<T, true> {
355  operator()(T const& obj) const
356  {
357  return boost::lexical_cast<std::string>(obj.size());
358  }
359  };
360 
361  template <typename T>
362  struct productSize<T, false> {
363  std::string
364  operator()(T const&) const
365  {
366  return "-";
367  }
368  };
369 
370  template <class E>
371  struct productSize<std::vector<E>, false>
372  : public productSize<std::vector<E>, true> {};
373 
374  template <class E>
375  struct productSize<std::list<E>, false>
376  : public productSize<std::list<E>, true> {};
377 
378  template <class E>
379  struct productSize<std::deque<E>, false>
380  : public productSize<std::deque<E>, true> {};
381 
382  template <class E>
383  struct productSize<std::set<E>, false>
384  : public productSize<std::set<E>, true> {};
385 
386  template <class E>
387  struct productSize<PtrVector<E>, false>
388  : public productSize<PtrVector<E>, true> {};
389 
390  template <class E>
391  struct productSize<cet::map_vector<E>, false>
392  : public productSize<cet::map_vector<E>, true> {};
393 
394  template <typename T>
395  struct DoMakePartner {
396  std::unique_ptr<EDProduct>
397  operator()(T const& obj, std::type_info const& wanted_wrapper_type) const
398  {
399  return obj.makePartner(wanted_wrapper_type);
400  }
401  };
402 
403  template <typename T>
404  struct DoNotMakePartner {
405  std::unique_ptr<EDProduct>
406  operator()(T const&, std::type_info const&) const
407  {
408  throw Exception(errors::LogicError, "makePartner")
409  << "Attempted to make partner of a product ("
410  << cet::demangle_symbol(typeid(T).name())
411  << ") that does not know how!\n"
412  << "Please report to the ART framework developers.\n";
413  }
414  };
415 
416  template <typename T>
417  struct DoSetPtr {
418  void operator()(T const& obj,
419  std::type_info const& toType,
420  unsigned long index,
421  void const*& ptr) const;
422  void operator()(T const& obj,
423  std::type_info const& toType,
424  std::vector<unsigned long> const& index,
425  std::vector<void const*>& ptrs) const;
426  };
427 
428  template <typename T>
429  struct DoNotSetPtr {
430  void
431  operator()(T const&,
432  std::type_info const&,
433  unsigned long,
434  void const*&) const
435  {
437  << "The product type " << cet::demangle_symbol(typeid(T).name())
438  << "\ndoes not support art::Ptr\n";
439  }
440 
441  void
442  operator()(T const&,
443  std::type_info const&,
444  std::vector<unsigned long> const&,
445  std::vector<void const*>&) const
446  {
448  << "The product type " << cet::demangle_symbol(typeid(T).name())
449  << "\ndoes not support art::PtrVector\n";
450  }
451  };
452 
453  template <typename T>
454  void
456  std::type_info const& toType,
457  unsigned long const index,
458  void const*& ptr) const
459  {
460  // setPtr is the name of an overload set; each concrete collection
461  // T should supply a setPtr function, in the same namespace at
462  // that in which T is defined, or in the 'art' namespace.
463  setPtr(obj, toType, index, ptr);
464  }
465 
466  template <typename T>
467  void
469  std::type_info const& toType,
470  std::vector<unsigned long> const& indices,
471  std::vector<void const*>& ptr) const
472  {
473  // getElementAddresses is the name of an overload set; each
474  // concrete collection T should supply a getElementAddresses
475  // function, in the same namespace at that in which T is
476  // defined, or in the 'art' namespace.
477  getElementAddresses(obj, toType, indices, ptr);
478  }
479 }
480 
481 #endif /* canvas_Persistency_Common_Wrapper_h */
482 
483 // Local Variables:
484 // mode: c++
485 // End:
::xsd::cxx::tree::id< char, ncname > id
Definition: Database.h:165
const XML_Char * name
Definition: expat.h:151
static void insert_if_sampled_product(Sampled< T > &obj, std::string const &dataset, SubRunID const &id, std::unique_ptr< EDProduct > product)
Definition: Wrapper.h:282
unsigned do_getRangeSetID() const override
Definition: Wrapper.h:228
T const * operator->() const
Definition: Wrapper.h:178
void do_setPtr(std::type_info const &toType, unsigned long index, void const *&ptr) const override
Definition: Wrapper.h:312
Wrapper()=default
void setPtr(std::type_info const &toType, unsigned long index, void const *&ptr) const
const char * p
Definition: xmltok.h:285
std::unique_ptr< EDProduct > do_makePartner(std::type_info const &wanted_type) const override
Definition: Wrapper.h:235
std::unique_ptr< EDProduct > do_createEmptySampledProduct(InputTag const &tag) const override
Definition: Wrapper.h:295
void operator()(T const &, std::type_info const &, std::vector< unsigned long > const &, std::vector< void const * > &) const
Definition: Wrapper.h:442
void do_getElementAddresses(std::type_info const &toType, std::vector< unsigned long > const &indices, std::vector< void const * > &ptr) const override
Definition: Wrapper.h:323
enable_if_same_t< FT, decltype(f), R > enable_if_function_exists_t
void do_insertIfSampledProduct(std::string const &dataset, SubRunID const &id, std::unique_ptr< EDProduct > product) override
Definition: Wrapper.h:302
static std::type_info const * type_id()
Definition: traits.h:90
void do_combine(EDProduct *product) override
Definition: Wrapper.h:206
std::type_info const * typeInfo_() const override
Definition: Wrapper.h:185
bool isPresent_() const override
Definition: Wrapper.h:120
std::unique_ptr< EDProduct > operator()(T const &obj, std::type_info const &wanted_wrapper_type) const
Definition: Wrapper.h:397
static short Class_Version()
Definition: Wrapper.h:92
const XML_Char int const XML_Char * value
Definition: expat.h:331
Float_t E
Definition: plot.C:20
std::string operator()(T const &) const
Definition: Wrapper.h:364
T const * product() const
Definition: Wrapper.h:172
std::string operator()(T const &obj) const
Definition: Wrapper.h:355
void insert(std::string const &dataset, SubRunID const &id, T &&value)
Definition: Sampled.h:92
unsigned rangeSetID
Definition: Wrapper.h:137
std::unique_ptr< EDProduct > operator()(T const &, std::type_info const &) const
Definition: Wrapper.h:406
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
T product(std::vector< T > dims)
static void fill(T const &, std::vector< void const * > &)
Definition: traits.h:143
void getElementAddresses(std::type_info const &toType, std::vector< unsigned long > const &indices, std::vector< void const * > &ptr) const
bool present
Definition: Wrapper.h:136
static std::unique_ptr< EDProduct > create_empty_sampled_product(InputTag const &)
Definition: Wrapper.h:273
void operator()(T const &, std::type_info const &, unsigned long, void const *&) const
Definition: Wrapper.h:431
static std::unique_ptr< EDProduct > create_empty_sampled_product(InputTag const &tag)
Definition: Wrapper.h:250
void operator()(T const &obj, std::type_info const &toType, unsigned long index, void const *&ptr) const
Definition: Wrapper.h:455
Service to store calibration data products (CDP) in the SQLite3 metadatabase of a file...
Definition: FillParentInfo.h:8
bool isPresent() const
Definition: EDProduct.h:30
void fillView(std::vector< void const * > &view) const override
Definition: Wrapper.h:192
double T
Definition: Xdiff_gwt.C:5
T && refOrThrow(T *ptr)
Definition: Wrapper.h:335
static void aggregate(T &, T const &)
Definition: aggregate.h:54
std::string productSize() const override
Definition: Wrapper.h:199
static void insert_if_sampled_product(T &, std::string const &dataset, SubRunID const &, std::unique_ptr< EDProduct >)
Definition: Wrapper.h:257
void do_setRangeSetID(unsigned) override
Definition: Wrapper.h:221
constexpr ProductStatus present() noexcept
Definition: ProductStatus.h:10