FindOne.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Common_FindOne_h
2 #define canvas_Persistency_Common_FindOne_h
3 ////////////////////////////////////////////////////////////////////////
4 // FindOne
5 //
6 // A smart query object used as the main way of accessing associated
7 // objects in a one-to-one association.
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
11 // found 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.
20 //
21 // Notes:
22 //
23 // * ProdB and Data (if needed) are the only template arguments that
24 // must be specified when constructing a FindOne. Any other
25 // items are deducible from arguments.
26 //
27 // * An attempt to create a FindOne where one of the listed
28 // A objects actually has multiple B objects associated with it will
29 // result in an exception: use FindMany{,P} instead.
30 //
31 // * The FindOne needs a source of objects of type A, a
32 // data container (e.g. event and an input tag corresponding to the
33 // underlying association collection from which to create itself.
34 //
35 // * When constructed, the FindOne will obtain and
36 // interrogate the correct Assns and provide access to the B (and/or D)
37 // object(s) associated with each supplied A object in the order in
38 // which the A objects were specified.
39 //
40 // * If the specified A does not have an associated B or D then the
41 // cet::maybe_ref will be invalid.
42 //
43 // * If the required association collection has an extra data object D
44 // with each association then it *must* be specified as a template
45 // argument, even if it is not relevant to the current query.
46 //
47 // * *All* indexed accessors (at(), data(), get()) are bounds-checked.
48 //
49 // Useful type aliases.
50 //
51 // using assoc_t = ProdB;
52 // using data_t = Data;
53 // using size_type = typename std::vector<assoc_t const*>::size_type; // FindOne
54 // using size_type = typename std::vector<art::Ptr<assoc_t> >::size_type; // FindOneP
55 //
56 // Constructors.
57 //
58 // // From Handle or ValidHandle to collection of A.
59 // FindOne<ProdB>(Handle<ProdAColl> const&,
60 // DataContainer const&,
61 // InputTag const&);
62 // FindOne<ProdB, Data>(Handle<ProdAColl> const&,
63 // DataContainer const&,
64 // InputTag const&);
65 //
66 // // From sequence of pointer to A (including View<A>).
67 // FindOne<ProdB>(View<ProdA> const&,
68 // DataContainer const&,
69 // InputTag const&);
70 // FindOne<ProdB, Data>(View<ProdA> const&,
71 // DataContainer const&,
72 // InputTag const&);
73 //
74 // // From arbitrary sequence of Ptr<A>.
75 // FindOne<ProdB>(PtrProdAColl const&,
76 // DataContainer const&,
77 // InputTag const&);
78 // FindOne<ProdB, Data>(PtrProdAColl const&,
79 // DataContainer const&,
80 // InputTag const&);
81 //
82 // // From an initializer list of Ptr<A>.
83 // FindOne<ProdB>(<brace-enclosed initializer list>,
84 // DataContainer const&,
85 // InputTag const&);
86 // FindOne<ProdB, Data>(<brace-enclosed initializer list>,
87 // DataContainer const&,
88 // InputTag const&);
89 //
90 // Modifiers.
91 //
92 // <NONE>.
93 //
94 // Accessors.
95 //
96 // size_type size() const;
97 // cet::maybe_ref<assoc_t const> at(size_type) const; // FindOne
98 // art::Ptr<assoc_t> const& at(size_type) const; // FindOneP
99 // cet::maybe_ref<data_t const> data(size_type) const;
100 // void get(size_type,
101 // cet::maybe_ref<assoc_t const>&) const; // FindOne
102 // void get(size_type,
103 // art::Ptr<assoc_t>&) const; // FindOneP
104 // void get(size_type,
105 // cet::maybe_ref<assoc_t const>&,
106 // cet::maybe_ref<data_t const>&)
107 // const; // *Must* be used for FindOne<ProdB, Data>.
108 // void get(size_type,
109 // art::Ptr<assoc_t>&,
110 // cet::maybe_ref<data_t const>&)
111 // const; // *Must* be used for FindOneP<ProdB, Data>.
112 //
113 // Comparison operations.
114 //
115 // bool operator == (FindOne const& other) const;
116 //
117 ////////////////////////////////////////////////////////////////////////
123 #include "cetlib/maybe_ref.h"
124 
125 #include <initializer_list>
126 #include <vector>
127 
128 /* #undef ART_IPR_BY_PTR */
129 
130 namespace art {
131  // General template
132  template <typename ProdB, typename DATA = void>
133  class FindOne;
134 
135  // Specialization.
136  template <typename ProdB>
137  class FindOne<ProdB, void>;
138 }
139 
140 ////////////////////////////////////////////////////////////////////////
141 // Implementation of the specialization.
142 template <typename ProdB>
143 class art::FindOne<ProdB, void> {
144 public:
145  using assoc_t = ProdB;
146 
147 #ifdef ART_IPR_BY_PTR
148  using bColl_t = std::vector<Ptr<assoc_t>>;
149 #else
150  using bColl_t = std::vector<ProdB const*>;
151 #endif
152  using value_type = typename bColl_t::value_type;
153  using size_type = typename bColl_t::size_type;
154  using difference_type = typename bColl_t::difference_type;
155  using const_reference = typename bColl_t::const_reference;
156  using reference = typename bColl_t::reference;
157 
158  template <typename Handle, typename DataContainer, typename Tag>
159  FindOne(Handle const& aCollection,
160  DataContainer const& dc,
161  Tag const& tag,
162  std::enable_if_t<detail::is_handle<Handle>::value>* = nullptr);
163 
164  template <typename ProdAColl, typename DataContainer, typename Tag>
165  FindOne(ProdAColl const& view,
166  DataContainer const& dc,
167  Tag const& tag,
168  std::enable_if_t<std::is_pointer<typename ProdAColl::value_type>::value>* = nullptr);
169 
170  template <typename PtrProdAColl, typename DataContainer, typename Tag>
171  FindOne(PtrProdAColl const& aPtrColl,
172  DataContainer const& dc,
173  Tag const& tag,
174  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
176 
177  template <typename ProdA, typename DataContainer, typename Tag>
178  FindOne(std::initializer_list<Ptr<ProdA> > const& ptrs,
179  DataContainer const& dc,
180  Tag const& tag);
181 
182  // Is this a valid query (did we find an Assns)?
183  bool isValid() const;
184 
185  // Number of query results
186  size_type size() const;
187 
188  // Associated item by index (bounds-checked).
189 #ifdef ART_IPR_BY_PTR
190  Ptr<assoc_t> const& at(size_type i) const;
191  void get(size_type i, Ptr<assoc_t>& item) const;
192 #else
194  void get(size_type i, cet::maybe_ref<assoc_t const>& item) const;
195 #endif
196  bool operator == (FindOne<ProdB, void> const& other) const;
197 
198 protected:
199  FindOne() = default;
200  bColl_t& bCollection() { return bCollection_; }
201 
202  void setStoredException(std::shared_ptr<art::Exception const>&& e);
203  void throwIfInvalid() const;
204 
205 private:
206  bColl_t bCollection_{};
207  std::shared_ptr<art::Exception const> storedException_{};
208 };
209 
210 template <typename ProdB, typename Data>
211 class art::FindOne : private art::FindOne<ProdB, void> {
212 private:
214 public:
215  using dataColl_t = std::vector<Data const*>;
216  using value_type = typename base::value_type;
217  using size_type = typename base::size_type;
220  using reference = typename base::reference;
221  using assoc_t = typename base::assoc_t;
222 
223  using data_const_pointer = Data const*;
224  using data_const_reference = Data const&;
225  using data_reference = Data&;
226  using data_t = Data;
227 
228  template <typename Handle, typename DataContainer, typename Tag>
229  FindOne(Handle const& aCollection,
230  DataContainer const& dc,
231  Tag const& tag,
232  std::enable_if_t<detail::is_handle<Handle>::value>* = nullptr);
233 
234  template <typename ProdAColl, typename DataContainer, typename Tag>
235  FindOne(ProdAColl const& view,
236  DataContainer const& dc,
237  Tag const& tag,
238  std::enable_if_t<std::is_pointer<typename ProdAColl::value_type>::value>* = nullptr);
239 
240  template <typename PtrProdAColl, typename DataContainer, typename Tag>
241  FindOne(PtrProdAColl const& aPtrColl,
242  DataContainer const& dc,
243  Tag const& tag,
244  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
246 
247  template <typename ProdA, typename DataContainer, typename Tag>
248  FindOne(std::initializer_list<Ptr<ProdA> > const& ptrs,
249  DataContainer const& dc,
250  Tag const& tag);
251 
252  using base::at;
253  using base::get;
254  using base::isValid;
255  using base::size;
256 
257  // Association extra-data object by index (bounds-checked).
259 
260  // Associated item and extra-data object by index (bounds-checked).
261  void get(size_type i,
262 #ifdef ART_IPR_BY_PTR
263  art::Ptr<assoc_t>& item,
264 #else
266 #endif
268 
269  bool operator == (FindOne<ProdB, Data> const& other) const;
270 
271 private:
273 };
274 
275 ////////////////////////////////////////////////////////////////////////
276 // Base class implementation.
277 template <typename ProdB>
278 template <typename Handle, typename DataContainer, typename Tag>
280 FindOne(Handle const& aCollection,
281  DataContainer const& dc,
282  Tag const& tag,
283  std::enable_if_t<detail::is_handle<Handle>::value>*)
284 {
285  using ProdA = typename Handle::element_type::value_type;
287  dc, detail::input_tag<ProdA, ProdB, void>(tag)};
288  storedException_ = finder(*aCollection, bCollection_);
289 }
290 
291 template <typename ProdB>
292 template <typename ProdAColl, typename DataContainer, typename Tag>
294 FindOne(ProdAColl const& view,
295  DataContainer const& dc,
296  Tag const& tag,
298 {
299  using ProdA =
300  std::remove_const_t<std::remove_pointer_t<typename ProdAColl::value_type>>;
302  dc, detail::input_tag<ProdA, ProdB, void>(tag)};
303  storedException_ = finder(view, bCollection_);
304 }
305 
306 template <typename ProdB>
307 template <typename PtrProdAColl, typename DataContainer, typename Tag>
309 FindOne(PtrProdAColl const& aPtrColl,
310  DataContainer const& dc,
311  Tag const& tag,
312  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
314 {
315  using ProdA = typename PtrProdAColl::value_type::value_type;
317  dc, detail::input_tag<ProdA, ProdB, void>(tag)};
318  storedException_ = finder(aPtrColl, bCollection_);
319 }
320 
321 template <typename ProdB>
322 template <typename ProdA, typename DataContainer, typename Tag>
324 FindOne(std::initializer_list<Ptr<ProdA> > const& ptrs,
325  DataContainer const& dc,
326  Tag const& tag)
327 {
329  dc, detail::input_tag<ProdA, ProdB, void>(tag)};
330  storedException_ = finder(ptrs, bCollection_);
331 }
332 
333 template <typename ProdB>
334 inline
335 auto
338  -> size_type
339 {
340  throwIfInvalid();
341  return bCollection_.size();
342 }
343 
344 template <typename ProdB>
345 inline
346 bool
348 isValid() const
349 {
350  return storedException_.get() == nullptr;
351 }
352 
353 template <typename ProdB>
354 inline
355 auto
357 at(size_type const i) const
358  ->
359 #ifdef ART_IPR_BY_PTR
360  art::Ptr<assoc_t> const&
361 #else
363 #endif
364 {
365  throwIfInvalid();
366 #ifdef ART_IPR_BY_PTR
367  return bCollection_.at(i);
368 #else
369  return cet::maybe_ref<assoc_t const>{*bCollection_.at(i)};
370 #endif
371 }
372 
373 template <typename ProdB>
374 inline
375 void
378 #ifdef ART_IPR_BY_PTR
379  Ptr<assoc_t>& item
380 #else
382 #endif
383  ) const
384 {
385  throwIfInvalid();
386 #ifdef ART_IPR_BY_PTR
387  item = bCollection_.at(i);
388 #else
389  item.reseat(*bCollection_.at(i));
390 #endif
391 }
392 
393 template <typename ProdB>
394 inline
395 bool
398 {
399  throwIfInvalid();
400  return bCollection_ == other.bCollection_;
401 }
402 
403 template <typename ProdB>
404 inline
405 void
407 setStoredException(std::shared_ptr<art::Exception const>&& e)
408 {
409  storedException_ = std::move(e);
410 }
411 
412 template <typename ProdB>
413 inline
414 void
417 {
418  if (!isValid()) {
419  throw Exception(errors::LogicError, "Invalid FindOne", *storedException_)
420  << "Attempt to use a FindOne where the underlying art::Assns product was not found.";
421  }
422 }
423 
424 ////////////////////////////////////////////////////////////////////////
425 // Derived class implementation.
426 template <typename ProdB, typename Data>
427 template <typename Handle, typename DataContainer, typename Tag>
429  Handle const& aCollection,
430  DataContainer const& dc,
431  Tag const& tag,
432  std::enable_if_t<detail::is_handle<Handle>::value>*)
433 {
434  using ProdA = typename Handle::element_type::value_type;
436  dc, detail::input_tag<ProdA, ProdB, Data>(tag)};
438  finder(*aCollection, base::bCollection(), dataCollection_));
439 }
440 
441 template <typename ProdB, typename Data>
442 template <typename ProdAColl, typename DataContainer, typename Tag>
444  ProdAColl const& view,
445  DataContainer const& dc,
446  Tag const& tag,
448 {
449  using ProdA =
450  std::remove_const_t<std::remove_pointer_t<typename ProdAColl::value_type>>;
452  dc, detail::input_tag<ProdA, ProdB, Data>(tag)};
454 }
455 
456 template <typename ProdB, typename Data>
457 template <typename PtrProdAColl, typename DataContainer, typename Tag>
459  PtrProdAColl const& aPtrColl,
460  DataContainer const& dc,
461  Tag const& tag,
462  std::enable_if_t<std::is_same<
463  typename PtrProdAColl::value_type,
465 {
466  using ProdA = typename PtrProdAColl::value_type::value_type;
468  dc, detail::input_tag<ProdA, ProdB, Data>(tag)};
470  finder(aPtrColl, base::bCollection(), dataCollection_));
471 }
472 
473 template <typename ProdB, typename Data>
474 template <typename ProdA, typename DataContainer, typename Tag>
476  std::initializer_list<Ptr<ProdA>> const& ptrs,
477  DataContainer const& dc,
478  Tag const& tag)
479 {
481  dc, detail::input_tag<ProdA, ProdB, Data>(tag)};
483 }
484 
485 template <typename ProdB, typename Data>
487 {
490 }
491 
492 template <typename ProdB, typename Data>
494 #ifdef ART_IPR_BY_PTR
495  Ptr<assoc_t>& item,
496 #else
498 #endif
500 {
501  base::get(i, item); // Will check validity.
502  data.reseat(*dataCollection_.at(i));
503 }
504 
505 template <typename ProdB, typename Data>
507 {
508  return this->base::operator==(other) && // Will check validity.
510 }
511 
512 #undef ART_IPR_BY_PTR
513 
514 #endif /* canvas_Persistency_Common_FindOne_h */
515 
516 // Local Variables:
517 // mode: c++
518 // End:
bool isValid() const
Definition: FindOne.h:348
void get(size_type i, cet::maybe_ref< assoc_t const > &item) const
Definition: FindOne.h:377
typename base::size_type size_type
Definition: FindOne.h:217
void get(size_type i, cet::maybe_ref< assoc_t const > &item, cet::maybe_ref< Data const > &data) const
Definition: FindOne.h:493
#define ART_IPR_BY_PTR
Definition: FindManyP.h:135
bool operator==(FindOne< ProdB, Data > const &other) const
Definition: FindOne.h:506
bool operator==(FindOne< ProdB, void > const &other) const
Definition: FindOne.h:397
std::vector< ProdB const * > bColl_t
Definition: FindOne.h:150
typename bColl_t::size_type size_type
Definition: FindOne.h:153
typename base::const_reference const_reference
Definition: FindOne.h:219
const XML_Char const XML_Char * data
Definition: expat.h:268
typename base::reference reference
Definition: FindOne.h:220
size_type size() const
Definition: FindOne.h:337
typename bColl_t::value_type value_type
Definition: FindOne.h:152
std::vector< Data const * > dataColl_t
Definition: FindOne.h:215
const XML_Char int const XML_Char * value
Definition: expat.h:331
typename base::assoc_t assoc_t
Definition: FindOne.h:221
dataColl_t dataCollection_
Definition: FindOne.h:272
cet::maybe_ref< assoc_t const > at(size_type i) const
Definition: FindOne.h:357
Data & data_reference
Definition: FindOne.h:225
Data data_t
Definition: FindOne.h:226
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
cet::maybe_ref< Data const > data(size_type i) const
Definition: FindOne.h:486
typename base::value_type value_type
Definition: FindOne.h:216
FindOne(Handle const &aCollection, DataContainer const &dc, Tag const &tag, std::enable_if_t< detail::is_handle< Handle >::value > *=nullptr)
Definition: FindOne.h:428
typename bColl_t::reference reference
Definition: FindOne.h:156
Service to store calibration data products (CDP) in the SQLite3 metadatabase of a file...
Definition: FillParentInfo.h:8
Data const & data_const_reference
Definition: FindOne.h:224
void throwIfInvalid() const
Definition: FindOne.h:416
typename bColl_t::const_reference const_reference
Definition: FindOne.h:155
Float_t e
Definition: plot.C:35
void setStoredException(std::shared_ptr< art::Exception const > &&e)
Definition: FindOne.h:407
typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData
typename base::difference_type difference_type
Definition: FindOne.h:218
Definition: fwd.h:29
Data const * data_const_pointer
Definition: FindOne.h:223
typename bColl_t::difference_type difference_type
Definition: FindOne.h:154