LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
FindOne.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Common_FindOne_h
2 #define canvas_Persistency_Common_FindOne_h
3 // 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 //
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.
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 //
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 
141 // Implementation of the specialization.
142 template <typename ProdB>
143 class art::FindOne<ProdB, void> {
144 public:
145 
146  using assoc_t = ProdB;
147 
148 #ifdef ART_IPR_BY_PTR
149  using bColl_t = std::vector<Ptr<assoc_t> >;
150 #else
151  using bColl_t = std::vector<ProdB const*>;
152 #endif
153  using value_type = typename bColl_t::value_type;
154  using size_type = typename bColl_t::size_type;
155  using difference_type = typename bColl_t::difference_type;
156  using const_reference = typename bColl_t::const_reference;
157  using reference = typename bColl_t::reference;
158 
159  template <typename Handle, typename DataContainer, typename Tag>
160  FindOne(Handle const& aCollection,
161  DataContainer const& dc,
162  Tag const& tag,
163  std::enable_if_t<detail::is_handle<Handle>::value>* = nullptr);
164 
165  template <typename ProdAColl, typename DataContainer, typename Tag>
166  FindOne(ProdAColl const& view,
167  DataContainer const& dc,
168  Tag const& tag,
169  std::enable_if_t<std::is_pointer<typename ProdAColl::value_type>::value>* = nullptr);
170 
171  template <typename PtrProdAColl, typename DataContainer, typename Tag>
172  FindOne(PtrProdAColl const& aPtrColl,
173  DataContainer const& dc,
174  Tag const& tag,
175  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
177 
178  template <typename ProdA, typename DataContainer, typename Tag>
179  FindOne(std::initializer_list<Ptr<ProdA> > const& ptrs,
180  DataContainer const& dc,
181  Tag const& tag);
182 
183  // Is this a valid query (did we find an Assns)?
184  bool isValid() const;
185 
186  // Number of query results
187  size_type size() const;
188 
189  // Associated item by index (bounds-checked).
190 #ifdef ART_IPR_BY_PTR
191  Ptr<assoc_t> const& at(size_type i) const;
192  void get(size_type i, Ptr<assoc_t>& item) const;
193 #else
194  cet::maybe_ref<assoc_t const> at(size_type i) const;
195  void get(size_type i, cet::maybe_ref<assoc_t const>& item) const;
196 #endif
197  bool operator == (FindOne<ProdB, void> const& other) const;
198 
199 protected:
200  FindOne() = default;
201  bColl_t& bCollection() { return bCollection_; }
202 
203  void setStoredException(std::shared_ptr<art::Exception const>&& e);
204  void throwIfInvalid() const;
205 
206 private:
207  bColl_t bCollection_{};
208  std::shared_ptr<art::Exception const> storedException_{};
209 };
210 
211 template <typename ProdB, typename Data>
212 class art::FindOne : private art::FindOne<ProdB, void> {
213 private:
215 public:
216  using dataColl_t = std::vector<Data const*>;
217  using value_type = typename base::value_type;
218  using size_type = typename base::size_type;
221  using reference = typename base::reference;
222  using assoc_t = typename base::assoc_t;
223 
224  using data_const_pointer = Data const*;
225  using data_const_reference = Data const&;
226  using data_reference = Data&;
227  using data_t = Data;
228 
229  template <typename Handle, typename DataContainer, typename Tag>
230  FindOne(Handle const& aCollection,
231  DataContainer const& dc,
232  Tag const& tag,
233  std::enable_if_t<detail::is_handle<Handle>::value>* = nullptr);
234 
235  template <typename ProdAColl, typename DataContainer, typename Tag>
236  FindOne(ProdAColl const& view,
237  DataContainer const& dc,
238  Tag const& tag,
239  std::enable_if_t<std::is_pointer<typename ProdAColl::value_type>::value>* = nullptr);
240 
241  template <typename PtrProdAColl, typename DataContainer, typename Tag>
242  FindOne(PtrProdAColl const& aPtrColl,
243  DataContainer const& dc,
244  Tag const& tag,
245  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
247 
248  template <typename ProdA, typename DataContainer, typename Tag>
249  FindOne(std::initializer_list<Ptr<ProdA> > const& ptrs,
250  DataContainer const& dc,
251  Tag const& tag);
252 
253  using base::size;
254  using base::isValid;
255  using base::at;
256  using base::get;
257 
258  // Association extra-data object by index (bounds-checked).
259  cet::maybe_ref<Data const> data(size_type i) const;
260 
261  // Associated item and extra-data object by index (bounds-checked).
262  void get(size_type i,
263 #ifdef ART_IPR_BY_PTR
264  art::Ptr<assoc_t>& item,
265 #else
266  cet::maybe_ref<assoc_t const>& item,
267 #endif
268  cet::maybe_ref<Data const>& data) const;
269 
270  bool operator == (FindOne<ProdB, Data> const& other) const;
271 
272 private:
274 };
275 
277 // Base class implementation.
278 template <typename ProdB>
279 template <typename Handle, typename DataContainer, typename Tag>
281 FindOne(Handle const& aCollection,
282  DataContainer const& dc,
283  Tag const& tag,
284  std::enable_if_t<detail::is_handle<Handle>::value>*)
285 {
286  using ProdA = typename Handle::element_type::value_type;
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 = std::remove_const_t<std::remove_pointer_t<typename ProdAColl::value_type>>;
301  storedException_ = finder(view, bCollection_);
302 }
303 
304 template <typename ProdB>
305 template <typename PtrProdAColl, typename DataContainer, typename Tag>
307 FindOne(PtrProdAColl const& aPtrColl,
308  DataContainer const& dc,
309  Tag const& tag,
310  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
312 {
313  using ProdA = typename PtrProdAColl::value_type::value_type;
315  storedException_ = finder(aPtrColl, bCollection_);
316 }
317 
318 template <typename ProdB>
319 template <typename ProdA, typename DataContainer, typename Tag>
321 FindOne(std::initializer_list<Ptr<ProdA> > const& ptrs,
322  DataContainer const& dc,
323  Tag const& tag)
324 {
326  storedException_ = finder(ptrs, bCollection_);
327 }
328 
329 template <typename ProdB>
330 inline
331 auto
333 size() const
334  -> size_type
335 {
336  throwIfInvalid();
337  return bCollection_.size();
338 }
339 
340 template <typename ProdB>
341 inline
342 bool
344 isValid() const
345 {
346  return storedException_.get() == nullptr;
347 }
348 
349 template <typename ProdB>
350 inline
351 auto
353 at(size_type const i) const
354  ->
355 #ifdef ART_IPR_BY_PTR
356  art::Ptr<assoc_t> const&
357 #else
358  cet::maybe_ref<assoc_t const>
359 #endif
360 {
361  throwIfInvalid();
362 #ifdef ART_IPR_BY_PTR
363  return bCollection_.at(i);
364 #else
365  return cet::maybe_ref<assoc_t const>{*bCollection_.at(i)};
366 #endif
367 }
368 
369 template <typename ProdB>
370 inline
371 void
373 get(size_type const i,
374 #ifdef ART_IPR_BY_PTR
375  Ptr<assoc_t>& item
376 #else
377  cet::maybe_ref<assoc_t const>& item
378 #endif
379  ) const
380 {
381  throwIfInvalid();
382 #ifdef ART_IPR_BY_PTR
383  item = bCollection_.at(i);
384 #else
385  item.reseat(*bCollection_.at(i));
386 #endif
387 }
388 
389 template <typename ProdB>
390 inline
391 bool
394 {
395  throwIfInvalid();
396  return bCollection_ == other.bCollection_;
397 }
398 
399 template <typename ProdB>
400 inline
401 void
403 setStoredException(std::shared_ptr<art::Exception const>&& e)
404 {
405  storedException_ = std::move(e);
406 }
407 
408 template <typename ProdB>
409 inline
410 void
413 {
414  if (!isValid()) {
415  throw Exception(errors::LogicError, "Invalid FindOne", *storedException_)
416  << "Attempt to use a FindOne where the underlying art::Assns product was not found.";
417  }
418 }
419 
421 // Derived class implementation.
422 template <typename ProdB, typename Data>
423 template <typename Handle, typename DataContainer, typename Tag>
425 FindOne(Handle const& aCollection,
426  DataContainer const& dc,
427  Tag const& tag,
428  std::enable_if_t<detail::is_handle<Handle>::value>*)
429 {
430  using ProdA = typename Handle::element_type::value_type;
433 }
434 
435 template <typename ProdB, typename Data>
436 template <typename ProdAColl, typename DataContainer, typename Tag>
438 FindOne(ProdAColl const& view,
439  DataContainer const& dc,
440  Tag const& tag,
442 {
443  using ProdA = std::remove_const_t<std::remove_pointer_t<typename ProdAColl::value_type>>;
446 }
447 
448 template <typename ProdB, typename Data>
449 template <typename PtrProdAColl, typename DataContainer, typename Tag>
451 FindOne(PtrProdAColl const& aPtrColl,
452  DataContainer const& dc,
453  Tag const& tag,
454  std::enable_if_t<std::is_same<typename PtrProdAColl::value_type,
456 {
457  using ProdA = typename PtrProdAColl::value_type::value_type;
460 }
461 
462 template <typename ProdB, typename Data>
463 template <typename ProdA, typename DataContainer, typename Tag>
465 FindOne(std::initializer_list<Ptr<ProdA> > const& ptrs,
466  DataContainer const& dc,
467  Tag const& tag)
468 {
471 }
472 
473 template <typename ProdB, typename Data>
474 inline
475 cet::maybe_ref<Data const>
477 data(size_type i) const
478 {
480  return cet::maybe_ref<Data const>{*dataCollection_.at(i)};
481 }
482 
483 template <typename ProdB, typename Data>
484 inline
485 void
487 get(size_type const i,
488 #ifdef ART_IPR_BY_PTR
489  Ptr<assoc_t>& item,
490 #else
491  cet::maybe_ref<assoc_t const>& item,
492 #endif
493  cet::maybe_ref<Data const>& data) const
494 {
495  base::get(i, item); // Will check validity.
496  data.reseat(*dataCollection_.at(i));
497 }
498 
499 template <typename ProdB, typename Data>
500 inline
501 bool
504 {
505  return this->base::operator==(other) && // Will check validity.
507 }
508 
509 #undef ART_IPR_BY_PTR
510 
511 #endif /* canvas_Persistency_Common_FindOne_h */
512 
513 // Local Variables:
514 // mode: c++
515 // End:
bool isValid() const
Definition: FindOne.h:344
void get(size_type i, cet::maybe_ref< assoc_t const > &item) const
Definition: FindOne.h:373
typename base::size_type size_type
Definition: FindOne.h:218
InputTag input_tag(InputTag const &tag)
Definition: IPRHelper.h:21
void get(size_type i, cet::maybe_ref< assoc_t const > &item, cet::maybe_ref< Data const > &data) const
Definition: FindOne.h:487
#define ART_IPR_BY_PTR
Definition: FindManyP.h:134
bool operator==(FindOne< ProdB, Data > const &other) const
Definition: FindOne.h:503
bool operator==(FindOne< ProdB, void > const &other) const
Definition: FindOne.h:393
std::vector< ProdB const * > bColl_t
Definition: FindOne.h:151
typename bColl_t::size_type size_type
Definition: FindOne.h:154
typename base::const_reference const_reference
Definition: FindOne.h:220
typename base::reference reference
Definition: FindOne.h:221
size_type size() const
Definition: FindOne.h:333
typename bColl_t::value_type value_type
Definition: FindOne.h:153
std::vector< Data const * > dataColl_t
Definition: FindOne.h:216
typename base::assoc_t assoc_t
Definition: FindOne.h:222
dataColl_t dataCollection_
Definition: FindOne.h:273
cet::maybe_ref< assoc_t const > at(size_type i) const
Definition: FindOne.h:353
Data & data_reference
Definition: FindOne.h:226
Data data_t
Definition: FindOne.h:227
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:477
typename base::value_type value_type
Definition: FindOne.h:217
std::string value(boost::any const &)
FindOne(Handle const &aCollection, DataContainer const &dc, Tag const &tag, std::enable_if_t< detail::is_handle< Handle >::value > *=nullptr)
Definition: FindOne.h:425
typename bColl_t::reference reference
Definition: FindOne.h:157
HLT enums.
Data const & data_const_reference
Definition: FindOne.h:225
void throwIfInvalid() const
Definition: FindOne.h:412
typename bColl_t::const_reference const_reference
Definition: FindOne.h:156
Float_t e
Definition: plot.C:34
void setStoredException(std::shared_ptr< art::Exception const > &&e)
Definition: FindOne.h:403
typename base::difference_type difference_type
Definition: FindOne.h:219
Definition: fwd.h:25
Data const * data_const_pointer
Definition: FindOne.h:224
typename bColl_t::difference_type difference_type
Definition: FindOne.h:155