PtrRemapper.h
Go to the documentation of this file.
1 #ifndef art_Framework_Core_PtrRemapper_h
2 #define art_Framework_Core_PtrRemapper_h
3 ////////////////////////////////////////////////////////////////////////
4 // PtrRemapper
5 //
6 // Class to aid in remapping Ptrs in various settings from items in
7 // one branch to (presumably the equivalent) items in another branch
8 // of the same type.
9 //
10 // This class is primarily for use in product mixing and will be
11 // properly initialized by the time it is provided as an argument to
12 // the user-supplied mixing function.
13 //
14 // PtrRemapper is a function object, so all of its work is done with
15 // the apply operator -- operator(). This means that if your mixing
16 // function has an argument (e.g.)
17 //
18 // art::PtrRemapper const& remap
19 //
20 // then the usage is:
21 //
22 // remap(...)
23 //
24 // There are several signatures to operator() and because they are all
25 // templates, they can look fairly impenetrable. It is recommended
26 // therefore to use this header documentation to decide what signature
27 // is most appropriate for your use rather than looking below at the
28 // prototypes or the implementation: there really are "No
29 // User-serviceable Parts."
30 //
31 // Notes common to several signatures.
32 //
33 // * With the exception of the (rarely required) signature 10 (see its
34 // specific documentation), all template arguments are deducible from
35 // the function arguments and therefore it is not necessary to specify
36 // them in <>.
37 //
38 // * Commonly-used arguments:
39 //
40 // * std::vector<COLLECTION<PROD> const*> const& in
41 //
42 // * OutIter& out
43 //
44 // OutIter is a variable of category insert_iterator (usually
45 // created by, for instance std::back_inserter(container)) into a
46 // container of Ptr (either PtrVector or some other collection of
47 // Ptr).
48 //
49 // * offset is a single offset into the container into which the
50 // Ptr points. It should be of type
51 // convertible-to-container::size_type.
52 //
53 // * offsets is an arbitrary container of such offsets as described
54 // in the documentation in
55 // art/Persistency/Common/CollectionUtilities.h.
56 //
57 //
58 // Available signatures to operator() and example usage:
59 //
60 // 1. Remap a single Ptr.
61 //
62 // Ptr<A> newPtr(remap(oldPtr, offset));
63 //
64 // 2. Remap a single PtrVector.
65 //
66 // PtrVector<A> newPV(remap(oldPV, offset));
67 //
68 // 3. Remap a compatible collection (including PtrVector) of Ptr
69 // providing begin, end iterators. (This will also remap a compatible
70 // collection of PtrVector, but not of PtrVector const* -- for the
71 // latter, see 4-10.)
72 //
73 // PtrVector<A> newPV;
74 // remap(oldPV.begin(),
75 // oldPV.end(),
76 // std::back_inserter(newPV),
77 // offset);
78 //
79 // 4. Remap and flatten a set of products which are containers of
80 // Ptrs (which includes PtrVector).
81 //
82 // remap(in, out, offsets)
83 //
84 // where offsets is likely calculated by the appropriate call to
85 // art::flattenCollections. See
86 // art/Persistency/Common/CollectionUtilities for details.
87 //
88 // 5. Remap and flatten a set of containers of Ptrs (including
89 // PtrVector) which may be obtained from a component of the provided
90 // product. Provide a free function of the correct signature to return
91 // a reference to the container of Ptrs given a secondary product,
92 // e.g.:
93 //
94 // PtrVector<B> const& myfunc(A const* prod) {
95 // return prod->myBs();
96 // }
97 //
98 // remap(in, out, offsets, &myfunc);
99 //
100 // 6. Remap and flatten a set of containers of Ptrs (including
101 // PtrVector) which may be obtained from a component of the provided
102 // product. Provide the name of a member function of the provided
103 // product which is an accessor for the container (taking no
104 // arguments).
105 //
106 // remap(in, out, offsets, &A::myBs);
107 //
108 // 7. Remap and flatten a set of containers of Ptrs (including
109 // PtrVector) which may be obtained from a component of the provided
110 // product. Provide the name of a member datum of the provided product
111 // which is the container.
112 //
113 // remap(in, out, offsets, &A::myBs_);
114 //
115 // 8. Remap and flatten a set of containers of Ptrs (including
116 // PtrVector) which is a component of the provided product using the
117 // provided accessor member function of a class which is not the
118 // product.
119 //
120 // class Aprocessor {
121 // public:
122 // B const& myBs(A const*);
123 // };
124 //
125 // Aprocessor myAp;
126 //
127 // remap(in, out, offsets, Aprocessor::myBs, myAp);
128 //
129 // Note: if the compiler complains about an unresolved overload set
130 // for this signature, try an explicit:
131 //
132 // const_cast<Aprocessor&>(myAp);
133 //
134 // 9. Remap and flatten a set of containers of Ptrs (including
135 // PtrVector) which is a component of the provided product using the
136 // provided const accessor member function of a class which is not the
137 // product.
138 //
139 // class Aprocessor {
140 // public:
141 // B const& myBs(A const*) const;
142 // };
143 //
144 // Aprocessor myAp;
145 //
146 // remap(in, out, offsets, Aprocessor::myBs, myAp);
147 //
148 // Note: if the compiler complains about an unresolved overload set
149 // for this signature, try an explicit:
150 //
151 // const_cast<Aprocessor const&>(myAp);
152 //
153 // 10. More general version of 5-9. that takes a final argument which is
154 // of arbitrary type provided it or its operator() has the correct
155 // signature. The drawback is that one of the template arguments (CONT,
156 // specifying the type of the collection of Ptrs you wish to remap) is
157 // not deducible, meaning that instead of:
158 //
159 // remap(...);
160 //
161 // one must type (e.g.):
162 //
163 // remap.operator()<std::vector<art::Ptr<B> > >(...)
164 //
165 // Therefore, 4-9. are the recommended signatures for
166 // straightforward client code -- this one is provided for maximum
167 // flexibility.
168 //
169 ////////////////////////////////////////////////////////////////////////
170 
177 #include "cetlib/exempt_ptr.h"
178 
179 #include <map>
180 
181 namespace art {
182  class PtrRemapper;
183  class ProdToProdMapBuilder;
184 
185  namespace PtrRemapperDetail {
186  // Function template used by 4.
187  template <typename PROD>
188  PROD const&
190  {
191  return *prod;
192  }
193 
194  // Function object used by 10.
195  template <typename CONT, typename PROD, typename CALLBACK>
196  class ContReturner {
197  public:
198  explicit ContReturner(CALLBACK callback) : callback_(callback) {}
199  CONT const&
200  operator()(PROD const* prod) const
201  {
202  return callback_(prod);
203  }
204 
205  private:
206  CALLBACK callback_;
207  };
208 
209  template <typename CONT, typename PROD>
210  class ContReturner<CONT, PROD, CONT const& (PROD::*)() const> {
211  public:
212  typedef CONT const& (PROD::*CALLBACK)() const;
213  explicit ContReturner(CALLBACK callback) : callback_(callback) {}
214  CONT const&
215  operator()(PROD const* prod) const
216  {
217  return (prod->*callback_)();
218  }
219 
220  private:
221  CALLBACK callback_;
222  };
223 
224  template <typename CONT, typename PROD>
225  class ContReturner<CONT, PROD, CONT PROD::*const> {
226  public:
227  typedef CONT PROD::*const CALLBACK;
228  explicit ContReturner(CALLBACK callback) : callback_(callback) {}
229  CONT const&
230  operator()(PROD const* prod) const
231  {
232  return prod->*callback_;
233  }
234 
235  private:
237  };
238  }
239 }
240 
242 public:
243  PtrRemapper() = default;
244 
245  //////////////////////////////////////////////////////////////////////
246  // Signatures for operator() -- see documentation at top of header.
247 
248  // 1.
249  template <typename PROD, typename SIZE_TYPE>
250  Ptr<PROD> operator()(Ptr<PROD> const& oldPtr, SIZE_TYPE offset) const;
251 
252  // 2.
253  template <typename PROD, typename SIZE_TYPE>
255  SIZE_TYPE offset) const;
256 
257  // 3.
258  template <typename InIter, typename OutIter, typename SIZE_TYPE>
259  void operator()(InIter beg, InIter end, OutIter out, SIZE_TYPE offset) const;
260 
261  // 4.
262  template <typename OutIter, typename PROD, typename OFFSETS>
263  void operator()(std::vector<PROD const*> const& in,
264  OutIter out,
265  OFFSETS const& offsets) const;
266 
267  // 5.
268  template <typename CONT, typename OutIter, typename PROD, typename OFFSETS>
269  void operator()(std::vector<PROD const*> const& in,
270  OutIter out,
271  OFFSETS const& offsets,
272  CONT const& (*extractor)(PROD const*)) const;
273 
274  // 6.
275  template <typename CONT, typename OutIter, typename PROD, typename OFFSETS>
276  void operator()(std::vector<PROD const*> const& in,
277  OutIter out,
278  OFFSETS const& offsets,
279  CONT const& (PROD::*extractor)() const) const;
280 
281  // 7.
282  template <typename CONT, typename OutIter, typename PROD, typename OFFSETS>
283  void operator()(std::vector<PROD const*> const& in,
284  OutIter out,
285  OFFSETS const& offsets,
286  CONT PROD::*const data) const;
287 
288  // 8.
289  template <typename PROD,
290  typename OutIter,
291  typename CONT,
292  typename X,
293  typename OFFSETS>
294  void operator()(std::vector<PROD const*> const& in,
295  OutIter out,
296  OFFSETS const& offsets,
297  CONT const& (X::*extractor)(PROD const*),
298  X& x) const;
299 
300  // 9.
301  template <typename PROD,
302  typename OutIter,
303  typename CONT,
304  typename X,
305  typename OFFSETS>
306  void operator()(std::vector<PROD const*> const& in,
307  OutIter out,
308  OFFSETS const& offsets,
309  CONT const& (X::*extractor)(PROD const*)const,
310  X const& x) const;
311 
312  // 10.
313  template <typename CONT,
314  typename CALLBACK,
315  typename OutIter,
316  typename PROD,
317  typename OFFSETS>
318  void operator()(std::vector<PROD const*> const& in,
319  OutIter out,
320  OFFSETS const& offsets,
321  CALLBACK extractor) const;
322 
323 private:
324  friend class ProdToProdMapBuilder;
325  using ProdTransMap_t = std::map<ProductID, ProductID>;
326 
327  // The following data members are filled by
328  // ProdToProdBuilder::populateRemapper, *not* by PtrRemapper.
329  ProdTransMap_t prodTransMap_{};
331 };
332 
333 // 1.
334 template <typename PROD, typename SIZE_TYPE>
337  SIZE_TYPE const offset) const
338 {
339  if (oldPtr.id().isValid()) {
340  auto iter = prodTransMap_.find(oldPtr.id());
341  if (iter == prodTransMap_.end()) {
343  << "PtrRemapper: could not find old ProductID " << oldPtr.id()
344  << " in translation table: already translated?\n";
345  }
346  return oldPtr.isNonnull() ? Ptr<PROD>{iter->second,
347  oldPtr.key() + offset,
348  event_->productGetter(iter->second)} :
349  Ptr<PROD>{iter->second};
350  }
351 
352  // Default-constructed.
353  return Ptr<PROD>{};
354 }
355 
356 // 2.
357 template <typename PROD, typename SIZE_TYPE>
360  SIZE_TYPE const offset) const
361 {
363  result.reserve(old.size());
364  this->operator()(old.begin(),
365  old.end(),
366  std::back_inserter(result),
367  offset); // 3.
368  return result;
369 }
370 
371 // 3.
372 template <typename InIter, typename OutIter, typename SIZE_TYPE>
373 void
375  InIter const end,
376  OutIter out,
377  SIZE_TYPE const offset) const
378 {
379  // Need to assume that all Ptr containers and consistent internally
380  // and with each other due to a lack of productGetters.
381 
382  // Not using transform here allows instantiation for iterator to
383  // collection of Ptr or collection of PtrVector.
384  for (auto i = beg; i != end; ++i) {
385  // Note: this could be signature 1 OR 2 of operator(). If the user
386  // calls this signature (3) with iterators into a collection of
387  // PtrVector, then the call order will be 3, 2, 3, 1 due to the
388  // templates that will be instantiated i.e. the relationship
389  // between signatures 2 and 3 is *not* infinitely recursive.
390  *out++ = this->operator()(*i, offset); // 1 OR 2.
391  }
392 }
393 
394 // 4.
395 template <typename OutIter, typename PROD, typename OFFSETS>
396 void
397 art::PtrRemapper::operator()(std::vector<PROD const*> const& in,
398  OutIter out,
399  OFFSETS const& offsets) const
400 {
401  this->operator()(in,
402  out,
403  offsets,
404  PtrRemapperDetail::simpleProdReturner<PROD>); // 5.
405 }
406 
407 // 5.
408 template <typename CONT, typename OutIter, typename PROD, typename OFFSETS>
409 void
410 art::PtrRemapper::operator()(std::vector<PROD const*> const& in,
411  OutIter out,
412  OFFSETS const& offsets,
413  CONT const& (*extractor)(PROD const*)) const
414 {
415  this->operator()<CONT, CONT const& (*)(PROD const*)>(
416  in, out, offsets, extractor); // 10.
417 }
418 
419 // 6.
420 template <typename CONT, typename OutIter, typename PROD, typename OFFSETS>
421 void
422 art::PtrRemapper::operator()(std::vector<PROD const*> const& in,
423  OutIter out,
424  OFFSETS const& offsets,
425  CONT const& (PROD::*extractor)() const) const
426 {
427  this->operator()<CONT, CONT const& (PROD::*)() const>(
428  in, out, offsets, extractor); // 10.
429 }
430 
431 // 7.
432 template <typename CONT, typename OutIter, typename PROD, typename OFFSETS>
433 void
434 art::PtrRemapper::operator()(std::vector<PROD const*> const& in,
435  OutIter out,
436  OFFSETS const& offsets,
437  CONT PROD::*const data) const
438 {
439  this->operator()<CONT, CONT PROD::*const>(in, out, offsets, data); // 10.
440 }
441 
442 // 8.
443 template <typename PROD,
444  typename OutIter,
445  typename CONT,
446  typename X,
447  typename OFFSETS>
448 void
449 art::PtrRemapper::operator()(std::vector<PROD const*> const& in,
450  OutIter out,
451  OFFSETS const& offsets,
452  CONT const& (X::*)(PROD const*),
453  X& x) const
454 {
455  this->operator()<CONT>(
456  in, out, offsets, [&x](auto& elem) { elem.extractor(x); }); // 10.
457 }
458 
459 // 9.
460 template <typename PROD,
461  typename OutIter,
462  typename CONT,
463  typename X,
464  typename OFFSETS>
465 void
466 art::PtrRemapper::operator()(std::vector<PROD const*> const& in,
467  OutIter out,
468  OFFSETS const& offsets,
469  CONT const& (X::*)(PROD const*)const,
470  X const& x) const
471 {
472  this->operator()<CONT>(
473  in, out, offsets, [&x](auto& elem) { elem.extractor(x); }); // 10.
474 }
475 
476 // 10.
477 template <typename CONT,
478  typename CALLBACK,
479  typename OutIter,
480  typename PROD,
481  typename OFFSETS>
482 void
483 art::PtrRemapper::operator()(std::vector<PROD const*> const& in,
484  OutIter out,
485  OFFSETS const& offsets,
486  CALLBACK extractor) const
487 {
488  if (in.size() != offsets.size()) {
490  << "Collection size of " << in.size()
491  << " disagrees with offset container size of " << offsets.size() << ".\n";
492  }
493  auto i = in.begin();
494  auto const e = in.end();
495  auto off_iter = offsets.begin();
497  extractor);
498  for (; i != e; ++i, ++off_iter) {
499  CONT const& cont(returner.operator()(*i));
500  this->operator()(cont.begin(), cont.end(), out, *off_iter); // 3.
501  }
502 }
503 
504 #endif /* art_Framework_Core_PtrRemapper_h */
505 
506 // Local Variables:
507 // mode: c++
508 // End:
key_type key() const
Definition: Ptr.h:356
void reserve(size_type n)
Definition: PtrVector.h:343
bool isNonnull() const
Definition: Ptr.h:335
iterator begin()
Definition: PtrVector.h:223
const XML_Char const XML_Char * data
Definition: expat.h:268
CONT const & operator()(PROD const *prod) const
Definition: PtrRemapper.h:200
std::map< ProductID, ProductID > ProdTransMap_t
Definition: PtrRemapper.h:325
iterator end()
Definition: PtrVector.h:237
PROD const & simpleProdReturner(PROD const *prod)
Definition: PtrRemapper.h:189
ProductID id() const
Definition: Ptr.h:349
T prod(const std::vector< T > &v)
Definition: prod.hpp:17
size_type size() const
Definition: PtrVector.h:308
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
ifstream in
Definition: comparison.C:7
Service to store calibration data products (CDP) in the SQLite3 metadatabase of a file...
Definition: FillParentInfo.h:8
Ptr< PROD > operator()(Ptr< PROD > const &oldPtr, SIZE_TYPE offset) const
Float_t e
Definition: plot.C:35
Float_t X
Definition: plot.C:38
Definition: fwd.h:28