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 
21 #include "cetlib/metaprogramming.h"
22 #include "cetlib_except/demangle.h"
23 
24 #include <memory>
25 #include <string>
26 #include <vector>
27 
28 namespace art {
29  template <typename T>
31 
32  template <typename T>
33  class Wrapper;
34 
35  // Implementation detail declarations.
36  namespace detail {
37 
39 
40  // has_size_member
41  template <typename T>
42  using size_expression_t = decltype(std::declval<T const>().size());
43 
44  template <typename T, typename = void>
45  struct has_size_member : std::false_type {};
46 
47  template <typename T>
48  struct has_size_member<T, std::void_t<size_expression_t<T>>>
49  : std::true_type {};
50 
51  // has_makePartner_member
52  template <typename T, typename = void>
53  struct has_makePartner_member : std::false_type {};
54 
55  template <typename T>
57  T,
58  enable_if_function_exists_t<std::unique_ptr<EDProduct> (T::*)(
59  std::type_info const&) const,
60  &T::makePartner>> : std::true_type {};
61  }
62 
63  template <typename T>
64  struct DoMakePartner;
65 
66  template <typename T>
68 
69  template <typename T>
70  struct DoSetPtr;
71 
72  template <typename T>
73  struct DoNotSetPtr;
74 }
75 
76 ////////////////////////////////////////////////////////////////////////
77 // Definition of art::Wrapper<T>
78 template <typename T>
79 class art::Wrapper : public art::EDProduct {
80 public:
81  Wrapper() = default;
82 
83  explicit Wrapper(std::unique_ptr<T> ptr);
84  virtual ~Wrapper() = default;
85 
86  T const* product() const;
87  T const* operator->() const;
88 
89  // MUST UPDATE WHEN CLASS IS CHANGED!
90  static short
92  {
93  return 11;
94  }
95 
96 private:
97  std::vector<void const*> getView() const override;
98 
99  std::string productSize() const override;
100 
101  product_typeids_t do_getTypeIDs() const override;
102  std::unique_ptr<EDProduct> do_makePartner(
103  std::type_info const& wanted_type) const override;
104 
105  unsigned do_getRangeSetID() const override;
106  void do_setRangeSetID(unsigned) override;
107  void do_combine(EDProduct const* product) override;
108  std::unique_ptr<EDProduct> do_createEmptySampledProduct(
109  InputTag const& tag) const override;
110 
111  template <typename>
112  friend struct prevent_recursion;
113 
114  void do_insertIfSampledProduct(std::string const& dataset,
115  SubRunID const& id,
116  std::unique_ptr<EDProduct> product) override;
117 
118  bool
119  isPresent_() const override
120  {
121  return present;
122  }
123  std::type_info const* typeInfo_() const override;
124 
125  void const* do_getElementAddress(std::type_info const& toType,
126  unsigned long index) const override;
127 
128  std::vector<void const*> do_getElementAddresses(
129  std::type_info const& toType,
130  std::vector<unsigned long> const& indices) const override;
131 
132  T&& refOrThrow(T* ptr);
133 
134  bool present{false};
135  unsigned rangeSetID{-1u};
136  T obj{};
137 
138 }; // Wrapper<>
139 
140 ////////////////////////////////////////////////////////////////////////
141 // Implementation details.
142 
143 #include "boost/lexical_cast.hpp"
150 
151 #include <deque>
152 #include <list>
153 #include <memory>
154 #include <set>
155 #include <string>
156 #include <type_traits>
157 #include <typeinfo>
158 #include <vector>
159 
160 ////////////////////////////////////////////////////////////////////////
161 // Wrapper member functions.
162 template <typename T>
163 art::Wrapper<T>::Wrapper(std::unique_ptr<T> ptr)
164  : present{ptr.get() != nullptr}, rangeSetID{-1u}, obj(refOrThrow(ptr.get()))
165 {}
166 
167 template <typename T>
168 T const*
170 {
171  return present ? &obj : nullptr;
172 }
173 
174 template <typename T>
176 {
177  return product();
178 }
179 
180 template <typename T>
181 std::type_info const*
183 {
184  return SupportsView<T>::type_id();
185 }
186 
187 template <typename T>
188 std::vector<void const*>
190 {
191  return MaybeGetView<T>::get(obj);
192 }
193 
194 template <typename T>
197 {
198  if constexpr (detail::has_size_member<T>::value) {
199  return boost::lexical_cast<std::string>(obj.size());
200  } else {
201  return "-";
202  }
203 }
204 
205 template <typename T>
206 void
208 {
209  if (!p->isPresent())
210  return;
211 
212  auto wp = static_cast<Wrapper<T> const*>(p);
214 
215  // The presence for the combined product is 'true', if we get this
216  // far.
217  present = true;
218 }
219 
220 template <typename T>
221 void
223 {
224  rangeSetID = id;
225 }
226 
227 template <typename T>
228 unsigned
230 {
231  return rangeSetID;
232 }
233 
234 template <typename T>
237 {
239 }
240 
241 template <typename T>
242 std::unique_ptr<art::EDProduct>
243 art::Wrapper<T>::do_makePartner(std::type_info const& wanted_wrapper) const
244 {
245  std::unique_ptr<art::EDProduct> retval;
247  retval = obj.makePartner(wanted_wrapper);
248  } else {
249  throw Exception{errors::LogicError, "makePartner"}
250  << "Attempted to make partner of a product ("
251  << cet::demangle_symbol(typeid(T).name()) << ") that does not know how!\n"
252  << "Please report to the art framework developers.\n";
253  }
254  return retval;
255 }
256 
257 namespace art {
258  template <typename T>
259  struct prevent_recursion {
260  static std::unique_ptr<EDProduct>
262  {
263  auto emptySampledProduct = std::make_unique<Sampled<T>>(tag);
264  return std::make_unique<Wrapper<Sampled<T>>>(move(emptySampledProduct));
265  }
266 
267  [[noreturn]] static void
269  std::string const& dataset,
270  SubRunID const&,
271  std::unique_ptr<EDProduct>)
272  {
274  << "An attempt was made to insert a product from dataset '" << dataset
275  << "'\ninto a non-sampled product of type '"
276  << cet::demangle_symbol(typeid(T).name()) << "'.\n"
277  << "Please contact artists@fnal.gov for guidance.";
278  }
279  };
280 
281  template <typename T>
283  [[noreturn]] static std::unique_ptr<EDProduct>
285  {
287  << "An attempt was made to create an empty sampled product\n"
288  << "for a sampled product. This type of recursion is not allowed.\n"
289  << "Please contact artists@fnal.gov for guidance.";
290  }
291 
292  static void
294  std::string const& dataset,
295  SubRunID const& id,
296  std::unique_ptr<EDProduct> product)
297  {
298  auto& wp = dynamic_cast<Wrapper<T>&>(*product);
299  obj.insert(dataset, id, std::move(wp.obj));
300  }
301  };
302 }
303 
304 template <typename T>
305 std::unique_ptr<art::EDProduct>
307 {
309 }
310 
311 template <typename T>
312 void
314  SubRunID const& id,
315  std::unique_ptr<EDProduct> product)
316 {
318  obj, dataset, id, move(product));
319 }
320 
321 template <typename T>
322 inline void const*
323 art::Wrapper<T>::do_getElementAddress(std::type_info const& toType,
324  unsigned long const index
325  [[maybe_unused]]) const
326 {
327  if constexpr (has_setPtr<T>::value) {
328  // Allow setPtr customizations by introducing the art::setPtr
329  // overload set, and not requiring art::setPtr(...).
330  using art::setPtr;
331  void const* result{nullptr};
332  setPtr(obj, toType, index, result);
333  return result;
334  } else {
336  << "The product type " << cet::demangle_symbol(typeid(T).name())
337  << " does not support art::Ptr\n";
338  }
339 }
340 
341 template <typename T>
342 inline std::vector<void const*>
344  std::type_info const& toType,
345  std::vector<unsigned long> const& indices) const
346 {
347  if constexpr (has_setPtr<T>::value) {
348  // getElementAddresses is the name of an overload set; each
349  // concrete collection T should supply a getElementAddresses
350  // function, in the same namespace at that in which T is
351  // defined, or in the 'art' namespace.
353  std::vector<void const*> result;
354  getElementAddresses(obj, toType, indices, result);
355  return result;
356  } else {
358  << "The product type " << cet::demangle_symbol(typeid(T).name())
359  << " does not support art::PtrVector\n";
360  }
361 }
362 
363 template <typename T>
364 inline T&&
366 {
367  if (ptr) {
368  return std::move(*ptr);
369  }
371  << "Attempt to construct " << cet::demangle_symbol(typeid(*this).name())
372  << " from nullptr.\n";
373 }
374 
375 #endif /* canvas_Persistency_Common_Wrapper_h */
376 
377 // Local Variables:
378 // mode: c++
379 // End:
static QCString name
Definition: declinfo.cpp:673
static product_typeids_t get()
static void insert_if_sampled_product(Sampled< T > &obj, std::string const &dataset, SubRunID const &id, std::unique_ptr< EDProduct > product)
Definition: Wrapper.h:293
unsigned do_getRangeSetID() const override
Definition: Wrapper.h:229
T const * operator->() const
Definition: Wrapper.h:175
static QCString result
Wrapper()=default
std::string string
Definition: nybbler.cc:12
std::unique_ptr< EDProduct > do_makePartner(std::type_info const &wanted_type) const override
Definition: Wrapper.h:243
decltype(std::declval< T const >().size()) size_expression_t
Definition: Wrapper.h:42
std::unique_ptr< EDProduct > do_createEmptySampledProduct(InputTag const &tag) const override
Definition: Wrapper.h:306
STL namespace.
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:313
static std::type_info const * type_id()
Definition: traits.h:83
std::type_info const * typeInfo_() const override
Definition: Wrapper.h:182
bool isPresent_() const override
Definition: Wrapper.h:119
static short Class_Version()
Definition: Wrapper.h:91
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
void do_combine(EDProduct const *product) override
Definition: Wrapper.h:207
void setPtr(COLLECTION const &coll, std::type_info const &iToType, unsigned long iIndex, void const *&oPtr)
static void aggregate(T &, T const &)
Definition: aggregate.h:53
void const * do_getElementAddress(std::type_info const &toType, unsigned long index) const override
Definition: Wrapper.h:323
T const * product() const
Definition: Wrapper.h:169
def move(depos, offset)
Definition: depos.py:107
std::vector< void const * > do_getElementAddresses(std::type_info const &toType, std::vector< unsigned long > const &indices) const override
Definition: Wrapper.h:343
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
p
Definition: test.py:223
void getElementAddresses(Collection const &coll, std::type_info const &iToType, std::vector< unsigned long > const &indices, std::vector< void const * > &oPtr)
void insert(std::string const &dataset, SubRunID const &id, T &&value)
Definition: Sampled.h:92
unsigned rangeSetID
Definition: Wrapper.h:135
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
static std::vector< void const * > get(T const &)
Definition: traits.h:147
std::map< product_metatype, TypeID > product_typeids_t
Definition: fwd.h:43
std::vector< void const * > getElementAddresses(std::type_info const &toType, std::vector< unsigned long > const &indices) const
Definition: EDProduct.cc:20
product_typeids_t do_getTypeIDs() const override
Definition: Wrapper.h:236
bool present
Definition: Wrapper.h:134
static std::unique_ptr< EDProduct > create_empty_sampled_product(InputTag const &)
Definition: Wrapper.h:284
static std::unique_ptr< EDProduct > create_empty_sampled_product(InputTag const &tag)
Definition: Wrapper.h:261
bool isPresent() const
Definition: EDProduct.h:31
T && refOrThrow(T *ptr)
Definition: Wrapper.h:365
std::string productSize() const override
Definition: Wrapper.h:196
std::vector< void const * > getView() const override
Definition: Wrapper.h:189
static void insert_if_sampled_product(T &, std::string const &dataset, SubRunID const &, std::unique_ptr< EDProduct >)
Definition: Wrapper.h:268
void do_setRangeSetID(unsigned) override
Definition: Wrapper.h:222
constexpr ProductStatus present() noexcept
Definition: ProductStatus.h:10