LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
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 
38  using cet::enable_if_function_exists_t;
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 
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 
141 // Implementation details.
142 
148 
149 #include <deque>
150 #include <list>
151 #include <memory>
152 #include <set>
153 #include <string>
154 #include <type_traits>
155 #include <typeinfo>
156 #include <vector>
157 
159 // Wrapper member functions.
160 template <typename T>
161 art::Wrapper<T>::Wrapper(std::unique_ptr<T> ptr)
162  : present{ptr.get() != nullptr}, rangeSetID{-1u}, obj(refOrThrow(ptr.get()))
163 {}
164 
165 template <typename T>
166 T const*
168 {
169  return present ? &obj : nullptr;
170 }
171 
172 template <typename T>
173 T const*
175 {
176  return product();
177 }
178 
179 template <typename T>
180 std::type_info const*
182 {
183  return SupportsView<T>::type_id();
184 }
185 
186 template <typename T>
187 std::vector<void const*>
189 {
190  return MaybeGetView<T>::get(obj);
191 }
192 
193 template <typename T>
194 std::string
196 {
197  if constexpr (detail::has_size_member<T>::value) {
198  using std::to_string;
199  return to_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>>>(
265  std::move(emptySampledProduct));
266  }
267 
268  [[noreturn]] static void
270  std::string const& dataset,
271  SubRunID const&,
272  std::unique_ptr<EDProduct>)
273  {
275  << "An attempt was made to insert a product from dataset '" << dataset
276  << "'\ninto a non-sampled product of type '"
277  << cet::demangle_symbol(typeid(T).name()) << "'.\n"
278  << "Please contact artists@fnal.gov for guidance.";
279  }
280  };
281 
282  template <typename T>
284  [[noreturn]] static std::unique_ptr<EDProduct>
286  {
288  << "An attempt was made to create an empty sampled product\n"
289  << "for a sampled product. This type of recursion is not allowed.\n"
290  << "Please contact artists@fnal.gov for guidance.";
291  }
292 
293  static void
295  std::string const& dataset,
296  SubRunID const& id,
297  std::unique_ptr<EDProduct> product)
298  {
299  auto& wp = dynamic_cast<Wrapper<T>&>(*product);
300  obj.insert(dataset, id, std::move(wp.obj));
301  }
302  };
303 }
304 
305 template <typename T>
306 std::unique_ptr<art::EDProduct>
308 {
310 }
311 
312 template <typename T>
313 void
315  SubRunID const& id,
316  std::unique_ptr<EDProduct> product)
317 {
319  obj, dataset, id, std::move(product));
320 }
321 
322 template <typename T>
323 inline void const*
324 art::Wrapper<T>::do_getElementAddress(std::type_info const& toType,
325  unsigned long const index
326  [[maybe_unused]]) const
327 {
328  if constexpr (has_setPtr<T>::value) {
329  // Allow setPtr customizations by introducing the art::setPtr
330  // overload set, and not requiring art::setPtr(...).
331  using art::setPtr;
332  void const* result{nullptr};
333  setPtr(obj, toType, index, result);
334  return result;
335  } else {
337  << "The product type " << cet::demangle_symbol(typeid(T).name())
338  << " does not support art::Ptr\n";
339  }
340 }
341 
342 template <typename T>
343 inline std::vector<void const*>
345  std::type_info const& toType,
346  std::vector<unsigned long> const& indices) const
347 {
348  if constexpr (has_setPtr<T>::value) {
349  // getElementAddresses is the name of an overload set; each
350  // concrete collection T should supply a getElementAddresses
351  // function, in the same namespace at that in which T is
352  // defined, or in the 'art' namespace.
354  std::vector<void const*> result;
355  getElementAddresses(obj, toType, indices, result);
356  return result;
357  } else {
359  << "The product type " << cet::demangle_symbol(typeid(T).name())
360  << " does not support art::PtrVector\n";
361  }
362 }
363 
364 template <typename T>
365 inline T&&
367 {
368  if (ptr) {
369  return std::move(*ptr);
370  }
372  << "Attempt to construct " << cet::demangle_symbol(typeid(*this).name())
373  << " from nullptr.\n";
374 }
375 
376 #endif /* canvas_Persistency_Common_Wrapper_h */
377 
378 // Local Variables:
379 // mode: c++
380 // End:
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:294
unsigned do_getRangeSetID() const override
Definition: Wrapper.h:229
T const * operator->() const
Definition: Wrapper.h:174
Wrapper()=default
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:307
STL namespace.
void do_insertIfSampledProduct(std::string const &dataset, SubRunID const &id, std::unique_ptr< EDProduct > product) override
Definition: Wrapper.h:314
static std::type_info const * type_id()
Definition: traits.h:83
std::type_info const * typeInfo_() const override
Definition: Wrapper.h:181
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:101
void do_combine(EDProduct const *product) override
Definition: Wrapper.h:207
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
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:324
T const * product() const
Definition: Wrapper.h:167
std::vector< void const * > do_getElementAddresses(std::type_info const &toType, std::vector< unsigned long > const &indices) const override
Definition: Wrapper.h:344
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
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: types.h:10
std::vector< void const * > getElementAddresses(std::type_info const &toType, std::vector< unsigned long > const &indices) const
Definition: EDProduct.cc:34
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:285
static std::unique_ptr< EDProduct > create_empty_sampled_product(InputTag const &tag)
Definition: Wrapper.h:261
Definition: MVAAlg.h:12
bool isPresent() const
Definition: EDProduct.h:31
T && refOrThrow(T *ptr)
Definition: Wrapper.h:366
std::string productSize() const override
Definition: Wrapper.h:195
std::vector< void const * > getView() const override
Definition: Wrapper.h:188
static void insert_if_sampled_product(T &, std::string const &dataset, SubRunID const &, std::unique_ptr< EDProduct >)
Definition: Wrapper.h:269
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
void do_setRangeSetID(unsigned) override
Definition: Wrapper.h:222
constexpr ProductStatus present() noexcept
Definition: ProductStatus.h:10