withZeroOrOne.h
Go to the documentation of this file.
1 /**
2  * @file lardata/RecoBaseProxy/ProxyBase/withZeroOrOne.h
3  * @brief Interface to add optional associated data to a collection proxy.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date July 27, 2017
6  * @see lardata/RecoBaseProxy/ProxyBase.h
7  *
8  * This library is header-only.
9  */
10 
11 #ifndef LARDATA_RECOBASEPROXY_PROXYBASE_WITHZEROORONE_H
12 #define LARDATA_RECOBASEPROXY_PROXYBASE_WITHZEROORONE_H
13 
14 // LArSoft libraries
17 
18 // C/C++ standard libraries
19 #include <tuple>
20 #include <utility> // std::forward(), std::move()
21 
22 
23 namespace proxy {
24 
25  namespace details {
26 
27  template <
28  typename Aux, typename Metadata, typename ArgTuple,
29  typename AuxTag = Aux
30  >
31  using WithOneTo01AssociatedStruct = WithAssociatedStructBase<
32  Aux,
33  Metadata,
34  ArgTuple,
35  OneTo01DataProxyMakerWrapper<Aux, Metadata, AuxTag>::template maker_t,
36  AuxTag
37  >;
38 
39  } // namespace details
40 
41  // --- BEGIN One-to-one (optional) associations ------------------------------
42  /**
43  * @name One-to-one (optional) associations
44  *
45  * These functions allow to merge into a data collection proxy some auxiliary
46  * data via an _art_ association fulfilling the
47  * @ref LArSoftProxyDefinitionOneToZeroOrOneSeqAssn "one-to-(zero-or-one) sequential association requirement".
48  *
49  * One category of functions is currently available:
50  * * `proxy::withZeroOrOne()` reads the relevant association from an event
51  *
52  * Variants of `proxy::withZeroOrOne()` called `proxy::withZeroOrOneMeta()`
53  * will allow merging the metadata of an association too. This feature is not
54  * supported yet, though.
55  *
56  * Also, variants are available to customize the tag class.
57  *
58  * The implementation of this feature is documented in
59  * @ref LArSoftProxiesAssociatedData "its own doxygen module".
60  *
61  * @{
62  */
63 
64  //----------------------------------------------------------------------------
65  /// The same as `withZeroOrOneMeta()`, but it also specified a tag.
66  /// @ingroup LArSoftProxyBase
67  /// @todo Metadata is not supported yet.
68  template <typename Aux, typename Metadata, typename AuxTag, typename... Args>
69  auto withZeroOrOneMetaAs(Args&&... args) {
70  using ArgTuple_t = std::tuple<Args&&...>;
71  ArgTuple_t argsTuple(std::forward<Args>(args)...);
72  return
74  (std::move(argsTuple));
75  } // withZeroOrOneAs()
76 
77 
78  /// The same as `withZeroOrOne()`, but it also specified a tag for the data.
79  /// @ingroup LArSoftProxyBase
80  template <typename Aux, typename AuxTag, typename... Args>
81  auto withZeroOrOneAs(Args&&... args)
82  {
83  return
84  withZeroOrOneMetaAs<Aux, void, AuxTag>(std::forward<Args>(args)...);
85  }
86 
87  /**
88  * @brief Helper function to merge one-to-(zero-or-one) associated data.
89  * @tparam Aux type of associated data requested
90  * @tparam Metadata type of metadata coming with the associated data
91  * @tparam Args types of constructor arguments for associated data collection
92  * @param args constructor arguments for the associated data collection
93  * @return a temporary object that `getCollection()` knows to handle
94  * @ingroup LArSoftProxyBase
95  * @see withZeroOrOneMetaAs(), withZeroOrOne()
96  *
97  * This function is meant to convey to `getCollection()` function the request
98  * for the delivered collection proxy to carry auxiliary data from an
99  * association fulfilling the
100  * @ref LArSoftProxyDefinitionOneToManySeqAssn "one-to-many sequential association"
101  * requirements.
102  *
103  * This data will be tagged with the type `Aux`. To use a different type as
104  * tag, use `withZeroOrOneAs()` instead, specifying the tag as second
105  * template argument, e.g.:
106  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
107  * struct QuestionableVertex {};
108  * auto tracks = proxy::getCollection<proxy::Tracks>(event, trackTag,
109  * withZeroOrOneMeta<recob::Vertex, void>(defaultVertexTag),
110  * withZeroOrOneMetaAs<recob::Vertex, void, QuestionableVertex>
111  * (stinkyVertexTag)
112  * );
113  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
114  * and, since we are not requesting any metadata, this is equivalent to
115  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
116  * struct QuestionableVertex {};
117  * auto tracks = proxy::getCollection<proxy::Tracks>(event, trackTag,
118  * withZeroOrOne<recob::Vertex>(defaultVertexTag),
119  * withZeroOrOneAs<recob::Vertex, QuestionableVertex>(stinkyVertexTag)
120  * );
121  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
122  * The first vertex association (`"defaultVertexTag"`) will be accessed by
123  * using the type `recob::Vertex` as tag, while the second one will be
124  * accessed by the `QuestionableVertex` tag (which is better not be defined
125  * in a local scope):
126  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
127  * for (auto&& track: tracks) {
128  * decltype(auto) vertex = track.get<recob::Vertex>();
129  * decltype(auto) maybeVertex = track.get<QuestionableVertex>();
130  * // ...
131  * }
132  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
133  *
134  *
135  * Customization of the association proxy
136  * =======================================
137  *
138  * See the technical details about `withAssociated()`, which hold for this
139  * function and related classes too.
140  *
141  *
142  * Technical details
143  * ==================
144  *
145  * See the technical details about `withAssociated()`, which hold for this
146  * function and related classes too.
147  *
148  * @todo Metadata is not supported yet (the interface is apparently there though).
149  */
150  template <typename Aux, typename Metadata, typename... Args>
151  auto withZeroOrOneMeta(Args&&... args)
152  {
153  return
154  withZeroOrOneMetaAs<Aux, Metadata, Aux>(std::forward<Args>(args)...);
155  }
156 
157  /// Works like `withZeroOrOneMeta()`, but for associations with no metadata.
158  /// @ingroup LArSoftProxyBase
159  /// @see withZeroOrOneAs(), withZeroOrOneMeta()
160  template <typename Aux, typename... Args>
161  auto withZeroOrOne(Args&&... args)
162  { return withZeroOrOneMeta<Aux, void>(std::forward<Args>(args)...); }
163 
164  /// @}
165  // --- END One-to-one (optional) associations --------------------------------
166 
167 } // namespace proxy
168 
169 
170 #endif // LARDATA_RECOBASEPROXY_PROXYBASE_WITHZEROORONE_H
auto withZeroOrOne(Args &&...args)
Helper to create associated data proxy.
static QCString args
Definition: declinfo.cpp:674
def move(depos, offset)
Definition: depos.py:107
Infrastructure for merging optional associated data to a proxy.
WithAssociatedStructBase< Aux, Metadata, ArgTuple, OneTo01DataProxyMakerWrapper< Aux, Metadata, AuxTag >::template maker_t, AuxTag > WithOneTo01AssociatedStruct
Definition: withZeroOrOne.h:37
auto withZeroOrOneMeta(Args &&...args)
Helper function to merge one-to-(zero-or-one) associated data.
auto withZeroOrOneMetaAs(Args &&...args)
Definition: withZeroOrOne.h:69
Template class to declare addition of associated data to a proxy.
auto withZeroOrOneAs(Args &&...args)
Definition: withZeroOrOne.h:81