FindManyP.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Common_FindManyP_h
2 #define canvas_Persistency_Common_FindManyP_h
3 ////////////////////////////////////////////////////////////////////////
4 // 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 //
14 ////////////////////////////////////
15 // Interface.
16 //////////
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 //
122 ////////////////////////////////////////////////////////////////////////
123 
130 #include "cetlib/maybe_ref.h"
131 
132 #include <initializer_list>
133 #include <vector>
134 
135 #define ART_IPR_BY_PTR
136 
137 namespace art {
138  // General template
139  template <typename ProdB, typename DATA = void>
140  class FindManyP;
141 
142  // Specialization.
143  template <typename ProdB>
144  class FindManyP<ProdB, void>;
145 }
146 
147 ////////////////////////////////////////////////////////////////////////
148 // Implementation of the specialization.
149 template <typename ProdB>
150 class art::FindManyP<ProdB, void>
151 {
152 public:
153 #ifdef ART_IPR_BY_PTR
154  using bColl_t = std::vector<std::vector<Ptr<ProdB>>>;
155 #else
156  using bColl_t = std::vector<std::vector<ProdB const*>>;
157 #endif
158  using value_type = typename bColl_t::value_type;
159  using size_type = typename bColl_t::size_type;
160  using difference_type = typename bColl_t::difference_type;
161  using const_reference = typename bColl_t::const_reference;
162  using reference = typename bColl_t::reference;
163 
164  using assoc_t = ProdB;
165 
166  template <typename Handle, typename DataContainer, typename Tag>
167  FindManyP(Handle const& aCollection,
168  DataContainer const& dc,
169  Tag const& tag,
170  std::enable_if_t<detail::is_handle<Handle>::value>* = nullptr);
171 
172  template <typename ProdAColl, typename DataContainer, typename Tag>
173  FindManyP(ProdAColl const& view,
174  DataContainer const& dc,
175  Tag const& tag,
176  std::enable_if_t<std::is_pointer_v<typename ProdAColl::value_type>>* =
177  nullptr);
178 
179  template <typename PtrProdAColl, typename DataContainer, typename Tag>
180  FindManyP(PtrProdAColl const& aPtrColl,
181  DataContainer const& dc,
182  Tag const& tag,
183  std::enable_if_t<std::is_same_v<
184  typename PtrProdAColl::value_type,
186 
187  template <typename ProdA, typename DataContainer, typename Tag>
188  FindManyP(std::initializer_list<Ptr<ProdA>> const& ptrs,
189  DataContainer const& dc,
190  Tag const& tag);
191 
192  // Is this a valid query (did we find an Assns)?
193  bool isValid() const;
194 
195  // Number of query results
196  size_type size() const;
197 
198  // Associated item by index (bounds-checked).
199  const_reference at(size_type i) const;
200 
201  size_type get(size_type i, reference item) const;
202 
203  bool operator==(FindManyP<ProdB, void> const& other) const;
204 
205 protected:
206  FindManyP() = default;
207  bColl_t& bCollection() { return bCollection_; }
208 
209  void setStoredException(std::shared_ptr<art::Exception const>&& e);
210  void throwIfInvalid() const;
211 
212 private:
213  bColl_t bCollection_{};
214  std::shared_ptr<art::Exception const> storedException_{nullptr};
215 };
216 
217 template <typename ProdB, typename Data>
218 class art::FindManyP : private art::FindManyP<ProdB, void> {
219 private:
221 
222 public:
223  using dataColl_t = std::vector<std::vector<Data const*>>;
224  using value_type = typename base::value_type;
225  using size_type = typename base::size_type;
228  using reference = typename base::reference;
229  using assoc_t = typename base::assoc_t;
230 
231  using data_const_pointer = typename dataColl_t::const_pointer;
232  using data_const_reference = typename dataColl_t::const_reference;
233  using data_reference = typename dataColl_t::reference;
234 
235  using data_t = Data;
236 
237  template <typename Handle, typename DataContainer, typename Tag>
238  FindManyP(Handle const& aCollection,
239  DataContainer const& dc,
240  Tag const& tag,
241  std::enable_if_t<detail::is_handle<Handle>::value>* = nullptr);
242 
243  template <typename ProdAColl, typename DataContainer, typename Tag>
244  FindManyP(ProdAColl const& view,
245  DataContainer const& dc,
246  Tag const& tag,
247  std::enable_if_t<std::is_pointer_v<typename ProdAColl::value_type>>* =
248  nullptr);
249 
250  template <typename PtrProdAColl, typename DataContainer, typename Tag>
251  FindManyP(PtrProdAColl const& aPtrColl,
252  DataContainer const& dc,
253  Tag const& tag,
254  std::enable_if_t<std::is_same_v<
255  typename PtrProdAColl::value_type,
257 
258  template <typename ProdA, typename DataContainer, typename Tag>
259  FindManyP(std::initializer_list<Ptr<ProdA>> const& ptrs,
260  DataContainer const& dc,
261  Tag const& tag);
262 
263  using base::at;
264  using base::get;
265  using base::isValid;
266  using base::size;
267 
268  // Association extra-data object by index (bounds-checked).
270 
271  // Associated item and extra-data object by index (bounds-checked).
272  size_type get(size_type i, reference item, data_reference data) const;
273 
274  bool operator==(FindManyP<ProdB, Data> const& other) const;
275 
276 private:
278 };
279 
280 ////////////////////////////////////////////////////////////////////////
281 // Base class implementation.
282 template <typename ProdB>
283 template <typename Handle, typename DataContainer, typename Tag>
285  DataContainer const& dc,
286  Tag const& tag,
287  std::enable_if_t<detail::is_handle<Handle>::value>*)
288 {
289  using ProdA = typename Handle::element_type::value_type;
291  dc, detail::input_tag<ProdA, ProdB, void>(tag)};
292  storedException_ = finder(*aCollection, bCollection_);
293 }
294 
295 template <typename ProdB>
296 template <typename ProdAColl, typename DataContainer, typename Tag>
298  DataContainer const& dc,
299  Tag const& tag,
300  std::enable_if_t<std::is_pointer_v<typename ProdAColl::value_type>>*)
301 {
302  using ProdA =
303  std::remove_const_t<std::remove_pointer_t<typename ProdAColl::value_type>>;
305  dc, detail::input_tag<ProdA, ProdB, void>(tag)};
306  storedException_ = finder(view, bCollection_);
307 }
308 
309 template <typename ProdB>
310 template <typename PtrProdAColl, typename DataContainer, typename Tag>
311 art::FindManyP<ProdB, void>::FindManyP(PtrProdAColl const& aPtrColl,
312  DataContainer const& dc,
313  Tag const& tag,
314  std::enable_if_t<
315  std::is_same_v<typename PtrProdAColl::value_type,
317 {
318  using ProdA = typename PtrProdAColl::value_type::value_type;
320  dc, detail::input_tag<ProdA, ProdB, void>(tag)};
321  storedException_ = finder(aPtrColl, bCollection_);
322 }
323 
324 template <typename ProdB>
325 template <typename ProdA, typename DataContainer, typename Tag>
326 art::FindManyP<ProdB, void>::FindManyP(std::initializer_list<Ptr<ProdA>> const& ptrs,
327  DataContainer const& dc,
328  Tag const& tag)
329 {
331  dc, detail::input_tag<ProdA, ProdB, void>(tag)};
332  storedException_ = finder(ptrs, bCollection_);
333 }
334 
335 template <typename ProdB>
337 {
338  throwIfInvalid();
339  return bCollection_.size();
340 }
341 
342 template <typename ProdB>
344 {
345  return (storedException_.get() == nullptr);
346 }
347 
348 template <typename ProdB>
350  -> const_reference
351 {
352  throwIfInvalid();
353  return bCollection_.at(i);
354 }
355 
356 template <typename ProdB>
358 {
359  throwIfInvalid();
360  const_reference ref(bCollection_.at(i));
361  item.insert(item.end(), ref.begin(), ref.end());
362  return ref.size();
363 }
364 
365 template <typename ProdB>
367 {
368  throwIfInvalid();
369  return bCollection_ == other.bCollection_;
370 }
371 
372 template <typename ProdB>
373 inline void art::FindManyP<ProdB, void>::setStoredException(std::shared_ptr<art::Exception const>&& e)
374 {
375  storedException_ = std::move(e);
376 }
377 
378 template <typename ProdB>
380 {
381  if (!isValid()) {
382  throw Exception(
383  errors::LogicError, "Invalid FindManyP", *storedException_)
384  << "Attempt to use a FindManyP where the underlying "
385  "art::Assns product was not found.";
386  }
387 }
388 
389 ////////////////////////////////////////////////////////////////////////
390 // Derived class implementation.
391 template <typename ProdB, typename Data>
392 template <typename Handle, typename DataContainer, typename Tag>
394  DataContainer const& dc,
395  Tag const& tag,
396  std::enable_if_t<detail::is_handle<Handle>::value>*)
397 {
398  using ProdA = typename Handle::element_type::value_type;
400  dc, detail::input_tag<ProdA, ProdB, void>(tag)};
402  finder(*aCollection, base::bCollection(), dataCollection_));
403 }
404 
405 template <typename ProdB, typename Data>
406 template <typename ProdAColl, typename DataContainer, typename Tag>
408  DataContainer const& dc,
409  Tag const& tag,
410  std::enable_if_t<std::is_pointer_v<typename ProdAColl::value_type>>*)
411 {
412  using ProdA =
413  std::remove_const_t<std::remove_pointer_t<typename ProdAColl::value_type>>;
415  dc, detail::input_tag<ProdA, ProdB, void>(tag)};
417 }
418 
419 template <typename ProdB, typename Data>
420 template <typename PtrProdAColl, typename DataContainer, typename Tag>
421 art::FindManyP<ProdB, Data>::FindManyP(PtrProdAColl const& aPtrColl,
422  DataContainer const& dc,
423  Tag const& tag,
424  std::enable_if_t<
425  std::is_same_v<typename PtrProdAColl::value_type,
427 {
428  using ProdA = typename PtrProdAColl::value_type::value_type;
430  dc, detail::input_tag<ProdA, ProdB, Data>(tag)};
432  finder(aPtrColl, base::bCollection(), dataCollection_));
433 }
434 
435 template <typename ProdB, typename Data>
436 template <typename ProdA, typename DataContainer, typename Tag>
438  std::initializer_list<Ptr<ProdA>> const& ptrs,
439  DataContainer const& dc,
440  Tag const& tag)
441 {
443  dc, detail::input_tag<ProdA, ProdB, Data>(tag)};
445 }
446 
447 template <typename ProdB, typename Data>
449 {
451  return dataCollection_.at(i);
452 }
453 
454 template <typename ProdB, typename Data>
456  reference item,
457  data_reference data) const -> size_type
458 {
459  size_type result = base::get(i, item); // Will check validity.
461  data.insert(data.end(), ref.begin(), ref.end());
462  ;
463  return result;
464 }
465 
466 template <typename ProdB, typename Data>
468 {
469  return this->base::operator==(other) && // Will check validity.
471 }
472 
473 #undef ART_IPR_BY_PTR
474 
475 #endif /* canvas_Persistency_Common_FindManyP_h */
476 
477 // Local Variables:
478 // mode: c++
479 // End:
typename dataColl_t::reference data_reference
Definition: FindManyP.h:233
bool operator==(FindManyP< ProdB, Data > const &other) const
Definition: FindManyP.h:467
typename dataColl_t::const_pointer data_const_pointer
Definition: FindManyP.h:231
typename bColl_t::value_type value_type
Definition: FindManyP.h:158
typename bColl_t::difference_type difference_type
Definition: FindManyP.h:160
data_const_reference data(size_type i) const
Definition: FindManyP.h:448
const XML_Char const XML_Char * data
Definition: expat.h:268
typename base::reference reference
Definition: FindManyP.h:228
typename base::size_type size_type
Definition: FindManyP.h:225
FindManyP(Handle const &aCollection, DataContainer const &dc, Tag const &tag, std::enable_if_t< detail::is_handle< Handle >::value > *=nullptr)
Definition: FindManyP.h:393
typename bColl_t::size_type size_type
Definition: FindManyP.h:159
typename bColl_t::const_reference const_reference
Definition: FindManyP.h:161
typename bColl_t::reference reference
Definition: FindManyP.h:162
bool operator==(FindManyP< ProdB, void > const &other) const
Definition: FindManyP.h:366
typename base::difference_type difference_type
Definition: FindManyP.h:226
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
std::vector< std::vector< Data const * >> dataColl_t
Definition: FindManyP.h:223
typename base::value_type value_type
Definition: FindManyP.h:224
dataColl_t dataCollection_
Definition: FindManyP.h:277
size_type get(size_type i, reference item) const
Definition: FindManyP.h:357
typename base::const_reference const_reference
Definition: FindManyP.h:227
void throwIfInvalid() const
Definition: FindManyP.h:379
std::vector< std::vector< Ptr< ProdB >>> bColl_t
Definition: FindManyP.h:154
Service to store calibration data products (CDP) in the SQLite3 metadatabase of a file...
Definition: FillParentInfo.h:8
const_reference at(size_type i) const
Definition: FindManyP.h:349
size_type get(size_type i, reference item, data_reference data) const
Definition: FindManyP.h:455
typename base::assoc_t assoc_t
Definition: FindManyP.h:229
size_type size() const
Definition: FindManyP.h:336
void setStoredException(std::shared_ptr< art::Exception const > &&e)
Definition: FindManyP.h:373
Float_t e
Definition: plot.C:35
typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData
typename dataColl_t::const_reference data_const_reference
Definition: FindManyP.h:232
Definition: fwd.h:29