LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
FindManyP.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Common_FindManyP_h
2 #define canvas_Persistency_Common_FindManyP_h
3 // FindManyP
5 //
6 // A smart query object used as the main way of accessing associated
7 // objects in an association (one-to-one, one-to-many or many-to-many).
8 //
9 // Given an Assns associating A with B (or B with A) (possibly with an
10 // associated data object D) and a source ACOLL of A objects to be found
11 // in the Assns, allow indexed access to the B and/or D objects
12 // associated with the A objects in ACOLL.
13 //
15 // Interface.
17 //
18 // For ease of understanding, the interface is presented here; reading
19 // the rest of the header is not for the faint of heart. Compare with
20 // the corresponding interface for FindOne.
21 //
22 // Notes:
23 //
24 // * ProdB and Data are the only template arguments that must be
25 // specified when constructing a FindManyP. Any other items
26 // are deducible from arguments.
27 //
28 // * The FindManyP needs a source of objects of type A, a
29 // data container (e.g. an event) and an input tag corresponding to
30 // the underlying association collection from which to create itself.
31 //
32 // * When constructed, the FindManyP will obtain and
33 // interrogate the correct Assns and provide access to the B (and/or D)
34 // object(s) associated with each supplied A object in the order in
35 // which the A objects were specified.
36 //
37 // * If the specified A does not have an associated B or D then the
38 // vector will be empty.
39 //
40 // * If the required association collection has an extra data object D
41 // with each association then it *must* be specified as a template
42 // argument, even if it is not relevant to the current query.
43 //
44 // * *All* indexed accessors (at(), data(), get()) are
45 // bounds-checked. Note that, because of the possible one-to-many
46 // association, these functions all return (or take as a reference in
47 // the case of get()) vectors, viz:
48 // * at() returns a const reference to a vector of const* (FindMany)
49 // or Ptr (FindManyP).
50 // * data returns a const reference to a vector of data objects.
51 // * get() takes references to a vector of const* or Ptr as
52 // appropriate, and a vector of data objects (if the data type is not
53 // void).
54 //
55 // Useful type aliases.
56 //
57 // using assoc_t = ProdB;
58 // using data_t = Data;
59 // using value_type = std::vector<assoc_t const*>; // FindMany
60 // using value_type = std::vector<art::Ptr<assoc_t>>; // FindManyP
61 // using size_type = typename std::vector<value_type>::size_type;
62 // using const_reference = value_type const&;
63 // using reference = value_type&;
64 // using data_const_reference = typename std::vector<data_t const*> const&;
65 // using data_reference = typename std::vector<data_t const*>&;
66 //
67 // Constructors.
68 //
69 // // From Handle or ValidHandle to collection of A.
70 // FindManyP<ProdB>(Handle<ProdAColl> const&,
71 // DataContainer const&,
72 // InputTag const&);
73 // FindManyP<ProdB, Data>(Handle<ProdAColl> const&,
74 // DataContainer const&,
75 // InputTag const&);
76 //
77 // // From sequence of pointer to A (including View<A>).
78 // FindManyP<ProdB>(View<ProdA> const&,
79 // DataContainer const&,
80 // InputTag const&);
81 // FindManyP<ProdB, Data>(View<ProdA> const&,
82 // DataContainer const&,
83 // InputTag const&);
84 //
85 // // From arbitrary sequence of Ptr<A>.
86 // FindManyP<ProdB>(PtrProdAColl const&,
87 // DataContainer const&,
88 // InputTag const&);
89 // FindManyP<ProdB, Data>(PtrProdAColl const&,
90 // DataContainer const&,
91 // InputTag const&);
92 //
93 // // From an initializer list of Ptr<A>.
94 // FindManyP<ProdB>(<brace-enclosed initializer list>,
95 // DataContainer const&,
96 // InputTag const&);
97 // FindManyP<ProdB, Data>(<brace-enclosed initializer list>,
98 // DataContainer const&,
99 // InputTag const&);
100 //
101 // Modifiers.
102 //
103 // <NONE>.
104 //
105 // Accessors.
106 //
107 // size_type size() const;
108 // const_reference at(size_type) const;
109 // const_data_reference data(size_type) const;
110 // size_type get(size_type,
111 // reference)
112 // const; // Returns number of elements appended.
113 // size_type get(size_type,
114 // reference,
115 // data_reference)
116 // const; // *Must* be used for FindManyP<ProdB, Data>.
117 //
118 // Comparison operations.
119 //
120 // bool operator == (FindManyP const& other) const;
121 //
123 
129 #include "cetlib/maybe_ref.h"
130 
131 #include <initializer_list>
132 #include <vector>
133 
134 #define ART_IPR_BY_PTR
135 
136 namespace art {
137  // General template
138  template <typename ProdB, typename DATA = void>
139  class FindManyP;
140 
141  // Specialization.
142  template <typename ProdB>
143  class FindManyP<ProdB, void>;
144 }
145 
147 // Implementation of the specialization.
148 template <typename ProdB>
149 class art::FindManyP<ProdB, void> {
150 public:
151 #ifdef ART_IPR_BY_PTR
152  using bColl_t = std::vector<std::vector<Ptr<ProdB> > >;
153 #else
154  using bColl_t = std::vector<std::vector<ProdB const*> >;
155 #endif
156  using value_type = typename bColl_t::value_type;
157  using size_type = typename bColl_t::size_type;
158  using difference_type = typename bColl_t::difference_type;
159  using const_reference = typename bColl_t::const_reference;
160  using reference = typename bColl_t::reference;
161 
162  using assoc_t = ProdB;
163 
164  template <typename Handle, typename DataContainer, typename Tag>
165  FindManyP(Handle const& aCollection,
166  DataContainer const& dc,
167  Tag const& tag,
168  std::enable_if_t<detail::is_handle<Handle>::value>* = nullptr);
169 
170  template <typename ProdAColl, typename DataContainer, typename Tag>
171  FindManyP(ProdAColl const& view,
172  DataContainer const& dc,
173  Tag const& tag,
174  std::enable_if_t<std::is_pointer<typename ProdAColl::value_type>::value>* = nullptr);
175 
176  template <typename PtrProdAColl, typename DataContainer, typename Tag>
177  FindManyP(PtrProdAColl const& aPtrColl,
178  DataContainer const& dc,
179  Tag const& tag,
180  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
182 
183  template <typename ProdA, typename DataContainer, typename Tag>
184  FindManyP(std::initializer_list<Ptr<ProdA> > const& ptrs,
185  DataContainer const& dc,
186  Tag const& tag);
187 
188  // Is this a valid query (did we find an Assns)?
189  bool isValid() const;
190 
191  // Number of query results
192  size_type size() const;
193 
194  // Associated item by index (bounds-checked).
195  const_reference at(size_type i) const;
196 
197  size_type get(size_type i, reference item) const;
198 
199  bool operator == (FindManyP<ProdB, void> const& other) const;
200 
201 protected:
202  FindManyP() = default;
203  bColl_t& bCollection() { return bCollection_; }
204 
205  void setStoredException(std::shared_ptr<art::Exception const>&& e);
206  void throwIfInvalid() const;
207 
208 private:
209  bColl_t bCollection_{};
210  std::shared_ptr<art::Exception const> storedException_{nullptr};
211 };
212 
213 template <typename ProdB, typename Data>
214 class art::FindManyP : private art::FindManyP<ProdB, void> {
215 private:
217 public:
218  using dataColl_t = std::vector<std::vector<Data const*> >;
219  using value_type = typename base::value_type;
220  using size_type = typename base::size_type;
223  using reference = typename base::reference;
224  using assoc_t = typename base::assoc_t;
225 
226  using data_const_pointer = typename dataColl_t::const_pointer;
227  using data_const_reference = typename dataColl_t::const_reference;
228  using data_reference = typename dataColl_t::reference;
229 
230  using data_t = Data;
231 
232  template <typename Handle, typename DataContainer, typename Tag>
233  FindManyP(Handle const& aCollection,
234  DataContainer const& dc,
235  Tag const& tag,
236  std::enable_if_t<detail::is_handle<Handle>::value>* = nullptr);
237 
238  template <typename ProdAColl, typename DataContainer, typename Tag>
239  FindManyP(ProdAColl const& view,
240  DataContainer const& dc,
241  Tag const& tag,
242  std::enable_if_t<std::is_pointer<typename ProdAColl::value_type>::value>* = nullptr);
243 
244  template <typename PtrProdAColl, typename DataContainer, typename Tag>
245  FindManyP(PtrProdAColl const& aPtrColl,
246  DataContainer const& dc,
247  Tag const& tag,
248  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
250 
251  template <typename ProdA, typename DataContainer, typename Tag>
252  FindManyP(std::initializer_list<Ptr<ProdA> > const& ptrs,
253  DataContainer const& dc,
254  Tag const& tag);
255 
256  using base::size;
257  using base::isValid;
258  using base::at;
259  using base::get;
260 
261  // Association extra-data object by index (bounds-checked).
263 
264  // Associated item and extra-data object by index (bounds-checked).
265  size_type get(size_type i, reference item, data_reference data) const;
266 
267  bool operator == (FindManyP<ProdB, Data> const& other) const;
268 
269 private:
271 };
272 
274 // Base class implementation.
275 template <typename ProdB>
276 template <typename Handle, typename DataContainer, typename Tag>
278 FindManyP(Handle const& aCollection,
279  DataContainer const& dc,
280  Tag const& tag,
281  std::enable_if_t<detail::is_handle<Handle>::value>*)
282 {
283  using ProdA = typename Handle::element_type::value_type;
285  storedException_ = finder(*aCollection, bCollection_);
286 }
287 
288 template <typename ProdB>
289 template <typename ProdAColl, typename DataContainer, typename Tag>
291 FindManyP(ProdAColl const& view,
292  DataContainer const& dc,
293  Tag const& tag,
295 {
296  using ProdA = std::remove_const_t<std::remove_pointer_t<typename ProdAColl::value_type>>;
298  storedException_ = finder(view, bCollection_);
299 }
300 
301 template <typename ProdB>
302 template <typename PtrProdAColl, typename DataContainer, typename Tag>
304 FindManyP(PtrProdAColl const& aPtrColl,
305  DataContainer const& dc,
306  Tag const& tag,
307  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
309 {
310  using ProdA = typename PtrProdAColl::value_type::value_type;
312  storedException_ = finder(aPtrColl, bCollection_);
313 }
314 
315 template <typename ProdB>
316 template <typename ProdA, typename DataContainer, typename Tag>
318 FindManyP(std::initializer_list<Ptr<ProdA> > const& ptrs,
319  DataContainer const& dc,
320  Tag const& tag)
321 {
323  storedException_ = finder(ptrs, bCollection_);
324 }
325 
326 template <typename ProdB>
327 inline
328 auto
330 size() const
331  -> size_type
332 {
333  throwIfInvalid();
334  return bCollection_.size();
335 }
336 
337 template <typename ProdB>
338 inline
339 bool
341 isValid() const
342 {
343  return (storedException_.get() == nullptr);
344 }
345 
346 template <typename ProdB>
347 inline
348 auto
350 at(size_type const i) const
351  -> const_reference
352 {
353  throwIfInvalid();
354  return bCollection_.at(i);
355 }
356 
357 template <typename ProdB>
358 inline
359 auto
361 get(size_type const i, reference item) const
362  -> size_type
363 {
364  throwIfInvalid();
365  const_reference ref(bCollection_.at(i));
366  item.insert(item.end(), ref.begin(), ref.end());
367  return ref.size();
368 }
369 
370 template <typename ProdB>
371 inline
372 bool
375 {
376  throwIfInvalid();
377  return bCollection_ == other.bCollection_;
378 }
379 
380 template <typename ProdB>
381 inline
382 void
384 setStoredException(std::shared_ptr<art::Exception const>&& e)
385 {
386  storedException_ = std::move(e);
387 }
388 
389 template <typename ProdB>
390 inline
391 void
394 {
395  if (!isValid()) {
396  throw Exception(errors::LogicError, "Invalid FindManyP", *storedException_)
397  << "Attempt to use a FindManyP where the underlying art::Assns product was not found.";
398  }
399 }
400 
402 // Derived class implementation.
403 template <typename ProdB, typename Data>
404 template <typename Handle, typename DataContainer, typename Tag>
406 FindManyP(Handle const& aCollection,
407  DataContainer const& dc,
408  Tag const& tag,
409  std::enable_if_t<detail::is_handle<Handle>::value>*)
410 {
411  using ProdA = typename Handle::element_type::value_type;
414 }
415 
416 template <typename ProdB, typename Data>
417 template <typename ProdAColl, typename DataContainer, typename Tag>
419 FindManyP(ProdAColl const& view,
420  DataContainer const& dc,
421  Tag const& tag,
423 {
424  using ProdA = std::remove_const_t<std::remove_pointer_t<typename ProdAColl::value_type>>;
427 }
428 
429 template <typename ProdB, typename Data>
430 template <typename PtrProdAColl, typename DataContainer, typename Tag>
432 FindManyP(PtrProdAColl const& aPtrColl,
433  DataContainer const& dc,
434  Tag const& tag,
435  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
437 {
438  using ProdA = typename PtrProdAColl::value_type::value_type;
441 }
442 
443 template <typename ProdB, typename Data>
444 template <typename ProdA, typename DataContainer, typename Tag>
446 FindManyP(std::initializer_list<Ptr<ProdA> > const& ptrs,
447  DataContainer const& dc,
448  Tag const& tag)
449 {
452 }
453 
454 template <typename ProdB, typename Data>
455 inline
456 auto
458 data(size_type const i) const
460 {
462  return dataCollection_.at(i);
463 }
464 
465 template <typename ProdB, typename Data>
466 inline
467 auto
470  -> size_type
471 {
472  size_type result = base::get(i, item); // Will check validity.
474  data.insert(data.end(), ref.begin(), ref.end());;
475  return result;
476 }
477 
478 template <typename ProdB, typename Data>
479 inline
480 bool
483 {
484  return this->base::operator==(other) && // Will check validity.
486 }
487 
488 #undef ART_IPR_BY_PTR
489 
490 #endif /* canvas_Persistency_Common_FindManyP_h */
491 
492 // Local Variables:
493 // mode: c++
494 // End:
typename dataColl_t::reference data_reference
Definition: FindManyP.h:228
InputTag input_tag(InputTag const &tag)
Definition: IPRHelper.h:21
bool operator==(FindManyP< ProdB, Data > const &other) const
Definition: FindManyP.h:482
typename dataColl_t::const_pointer data_const_pointer
Definition: FindManyP.h:226
std::vector< std::vector< Ptr< ProdB > > > bColl_t
Definition: FindManyP.h:152
typename bColl_t::value_type value_type
Definition: FindManyP.h:156
typename bColl_t::difference_type difference_type
Definition: FindManyP.h:158
data_const_reference data(size_type i) const
Definition: FindManyP.h:458
typename base::reference reference
Definition: FindManyP.h:223
typename base::size_type size_type
Definition: FindManyP.h:220
FindManyP(Handle const &aCollection, DataContainer const &dc, Tag const &tag, std::enable_if_t< detail::is_handle< Handle >::value > *=nullptr)
Definition: FindManyP.h:406
typename bColl_t::size_type size_type
Definition: FindManyP.h:157
typename bColl_t::const_reference const_reference
Definition: FindManyP.h:159
std::vector< std::vector< Data const * > > dataColl_t
Definition: FindManyP.h:218
typename bColl_t::reference reference
Definition: FindManyP.h:160
bool operator==(FindManyP< ProdB, void > const &other) const
Definition: FindManyP.h:374
typename base::difference_type difference_type
Definition: FindManyP.h:221
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
typename base::value_type value_type
Definition: FindManyP.h:219
dataColl_t dataCollection_
Definition: FindManyP.h:270
size_type get(size_type i, reference item) const
Definition: FindManyP.h:361
std::string value(boost::any const &)
typename base::const_reference const_reference
Definition: FindManyP.h:222
void throwIfInvalid() const
Definition: FindManyP.h:393
HLT enums.
const_reference at(size_type i) const
Definition: FindManyP.h:350
size_type get(size_type i, reference item, data_reference data) const
Definition: FindManyP.h:469
typename base::assoc_t assoc_t
Definition: FindManyP.h:224
size_type size() const
Definition: FindManyP.h:330
void setStoredException(std::shared_ptr< art::Exception const > &&e)
Definition: FindManyP.h:384
Float_t e
Definition: plot.C:34
typename dataColl_t::const_reference data_const_reference
Definition: FindManyP.h:227
Definition: fwd.h:25