All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OneTo01DataProxyMaker.h
Go to the documentation of this file.
1 /**
2  * @file lardata/RecoBaseProxy/ProxyBase/OneTo01DataProxyMaker.h
3  * @brief Infrastructure for merging optional associated data to a proxy.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date July 27, 2017
6  * @see lardata/RecoBaseProxy/ProxyBase/withZeroOrOne.h
7  *
8  * This library is header-only.
9  */
10 
11 #ifndef LARDATA_RECOBASEPROXY_PROXYBASE_ONETO01DATAPROXYMAKER_H
12 #define LARDATA_RECOBASEPROXY_PROXYBASE_ONETO01DATAPROXYMAKER_H
13 
14 // LArSoft libraries
17 
18 // framework libraries
19 #include "canvas/Utilities/InputTag.h"
20 
21 // C/C++ standard libraries
22 #include <utility> // std::forward()
23 #include <type_traits> // std::is_convertible<>
24 
25 
26 namespace proxy {
27 
28  // --- BEGIN LArSoftProxiesAssociatedData ------------------------------------
29  /// @addtogroup LArSoftProxiesAssociatedData
30  /// @{
31 
32  //----------------------------------------------------------------------------
33  //--- one-to-(zero/one) associations
34  //----------------------------------------------------------------------------
35  /**
36  * @brief Creates an one-to-(zero-or-one) wrapper for the specified types.
37  * @tparam Main type of main datum (element) to associate from ("left")
38  * @tparam Aux type of datum (element) to associate to ("right")
39  * @tparam Metadata type of metadata coming with the association
40  * @tparam AuxTag tag labelling this association
41  *
42  * Usually, `AuxTag` is also the type of datum (element) to associate to
43  * ("right").
44  *
45  * This class works as a base class for `OneTo01DataProxyMaker` so that
46  * the specializations of the latter can still inherit from this one if they
47  * its facilities.
48  */
49  template <
50  typename Main, typename Aux, typename Metadata = void,
51  typename AuxTag = Aux
52  >
54 
55  /// Tag labelling the associated data we are going to produce.
56  using data_tag = AuxTag;
57 
58  /// Type of the main datum ("left").
59  using main_element_t = Main;
60 
61  /// Type of the auxiliary associated datum ("right").
62  using aux_element_t = Aux;
63 
64  /// Type of associated metadata.
65  using metadata_t = Metadata;
66 
67  /// Type of associated data proxy being created.
70 
71  /// Type of _art_ association being used as input.
73 
74  /**
75  * @brief Create a association proxy collection using main collection tag.
76  * @tparam Event type of the event to read associations from
77  * @tparam Handle type of handle to the main data product
78  * @tparam MainArgs any type convertible to `art::InputTag`
79  * @param event the event to read associations from
80  * @param mainHandle handle to the main collection data product
81  * @param mainArgs an object describing the main data product
82  * @return an auxiliary data proxy object
83  *
84  * The returned object exposes a random access container interface, with
85  * data indexed by the index of the corresponding object in the main
86  * collection.
87  *
88  * The `mainArgs` object is of an arbitrary type that must be convertible
89  * by explicit type cast into a `art::InputTag`; that input tag will be
90  * used to fetch the association.
91  */
92  template<typename Event, typename Handle, typename MainArgs>
93  static auto make
94  (Event const& event, Handle&& mainHandle, MainArgs const& mainArgs)
95  {
96  return createFromTag
97  (event, std::forward<Handle>(mainHandle), art::InputTag(mainArgs));
98  }
99 
100  /**
101  * @brief Create a association proxy collection using the specified tag.
102  * @tparam Event type of the event to read associations from
103  * @tparam Handle type of handle to the main data product
104  * @tparam MainArgs any type convertible to `art::InputTag` (unused)
105  * @param event the event to read associations from
106  * @param mainHandle handle to the main collection data product
107  * @param auxInputTag the tag of the association to be read
108  * @return a auxiliary data proxy object
109  *
110  * The returned object exposes a random access container interface, with
111  * data indexed by the index of the corresponding object in the main
112  * collection.
113  */
114  template<typename Event, typename Handle, typename MainArgs>
115  static auto make(
116  Event const& event, Handle&& mainHandle,
117  MainArgs const&, art::InputTag const& auxInputTag
118  )
119  {
120  return
121  createFromTag(event, std::forward<Handle>(mainHandle), auxInputTag);
122  }
123 
124  /**
125  * @brief Create a association proxy collection using the specified tag.
126  * @tparam Event type of the event to read associations from (unused)
127  * @tparam Handle type of handle to the main data product
128  * @tparam MainArgs any type convertible to `art::InputTag` (unused)
129  * @param handle handle to the main data collection
130  * @param assns the associations to be wrapped
131  * @return a auxiliary data proxy object
132  *
133  * The returned object exposes a random access container interface, with
134  * data indexed by the index of the corresponding object in the main
135  * collection.
136  */
137  template<typename Event, typename Handle, typename MainArgs, typename Assns>
138  static auto make
139  (Event const&, Handle&& handle, MainArgs const&, Assns const& assns)
140  {
141  static_assert(
142  std::is_convertible<typename Assns::right_t, aux_element_t>(),
143  "Improper right type for one-to-(zero-or-one) association."
144  );
145  return makeOneTo01dataFrom<data_tag>(assns, handle->size());
146  }
147 
148 
149  private:
150  template<typename Event, typename Handle>
151  static auto createFromTag(
152  Event const& event, Handle&& mainHandle, art::InputTag const& auxInputTag
153  )
154  {
155  return makeOneTo01dataFrom
157  (event, auxInputTag, mainHandle->size());
158  }
159 
160  }; // struct OneTo01DataProxyMakerBase<>
161 
162 
163  //--------------------------------------------------------------------------
164  /**
165  * @brief Creates an one-to-(zero-or-one) wrapper for the specified types.
166  * @tparam Main type of main datum (element) to associate from ("left")
167  * @tparam Aux type of datum (element) to associate to ("right")
168  * @tparam Metadata type of metadata in the association
169  * @tparam CollProxy type of proxy this associated data works for
170  * @tparam Tag tag for the association proxy to be created
171  * @see `withZeroOrOne()`
172  * This class is (indirectly) called when using `proxy::withZeroOrOne()`
173  * in `getCollection()`.
174  * Its task is to supervise the creation of the proxy to the data
175  * association between the main data type and an auxiliary one.
176  * The interface required by `withZeroOrOne()` includes:
177  * * a static `make()` method creating and returning the associated data
178  * proxy with arguments an event, the main data product handle, a template
179  * argument representing the main collection information, and all the
180  * arguments required for the creation of the associated proxy (coming from
181  * `withZeroOrOne()`); equivalent to the signature:
182  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
183  * template <typename Event, typename Handle, typename MainArg, typename... Args>
184  * auto make(Event const&, Handle&&, MainArg const&, Args&&...);
185  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
186  *
187  * This class can be specialized (see `withAssociated()` for an example
188  * of the general procedure).
189  * The default implementation just wraps a one-to-(zero-or-one)
190  * `art::Assns<Main, Aux>` data product fulfilling
191  * @ref LArSoftProxyDefinitionOneToZeroOrOneSeqAssn "one-to-(zero or one) sequential association"
192  * requirement.
193  *
194  * The last template argument is designed for specialization of associations
195  * in the context of a specific proxy type.
196  */
197  template <
198  typename Main, typename Aux, typename Metadata,
199  typename CollProxy, typename Tag = Aux
200  >
202  : public OneTo01DataProxyMakerBase<Main, Aux, Metadata, Tag>
203  {
204  //
205  // Note that this implementation is here only to document how to derive
206  // a OneTo01DataProxyMaker (specialization) from
207  // OneTo01DataProxyMakerBase. It's just mirroring the base class.
208  //
210 
211  public:
212 
213  /// Type of the main datum ("left").
214  using typename base_t::main_element_t;
215 
216  /// Type of the auxiliary associated datum ("right").
217  using typename base_t::aux_element_t;
218 
219  /// Type of metadata in the association.
220  using typename base_t::metadata_t;
221 
222  /// Type of associated data proxy being created.
223  using typename base_t::aux_collection_proxy_t;
224 
225  /// Type of _art_ association being used as input.
226  using typename base_t::assns_t;
227 
228  /**
229  * @brief Create a association proxy collection using main collection tag.
230  * @tparam Event type of the event to read associations from
231  * @tparam Handle type of data product handle
232  * @tparam MainArgs any type convertible to `art::InputTag`
233  * @tparam Args optional single type (`art::InputTag` required)
234  * @param event the event to read associations from
235  * @param mainHandle handle of the main collection data product
236  * @param margs an object describing the main data product
237  * @param args input tag for associated data, if different from main
238  * @return an auxiliary data proxy object
239  *
240  * The returned object exposes a random access container interface, with
241  * data indexed by the index of the corresponding object in the main
242  * collection.
243  *
244  * This implementation requires `margs` object to be convertible
245  * by explicit type cast into a `art::InputTag`; that input tag will be
246  * used to fetch the association.
247  */
248  template
249  <typename Event, typename Handle, typename MainArgs, typename... Args>
250  static auto make(
251  Event const& event, Handle&& mainHandle, MainArgs const& margs,
252  Args&&... args
253  )
254  {
255  return base_t::make(
256  event,
257  std::forward<Handle>(mainHandle),
258  margs,
259  std::forward<Args>(args)...
260  );
261  }
262 
263  }; // struct OneTo01DataProxyMaker<>
264 
265 
266  /// @}
267  // --- END LArSoftProxiesAssociatedData --------------------------------------
268 
269 
270  namespace details {
271 
272  //--------------------------------------------------------------------------
273  //--- Stuff for one-to-(zero or one) associated data
274  //--------------------------------------------------------------------------
275  template <
276  typename Aux, typename Metadata /* = void */,
277  typename AuxTag /* = Aux */
278  >
280  template <typename CollProxy>
282  <typename CollProxy::main_element_t, Aux, Metadata, CollProxy, AuxTag>;
283  };
284 
285  } // namespace details
286 
287 
288 } // namespace proxy
289 
290 
291 #endif // LARDATA_RECOBASEPROXY_PROXYBASE_ONETO01DATAPROXYMAKER_H
static auto make(Event const &event, Handle &&mainHandle, MainArgs const &mainArgs)
Create a association proxy collection using main collection tag.
auto makeOneTo01dataFrom(Assns const &assns, std::size_t minSize=0)
Processes and returns an one-to-(zero/one) associated data object.
art::Assns< main_t, aux_t > assns_t
Type of the source association.
Definition: OneTo01Data.h:97
static auto createFromTag(Event const &event, Handle &&mainHandle, art::InputTag const &auxInputTag)
details::OneTo01Data< main_element_t, aux_element_t, metadata_t, data_tag > aux_collection_proxy_t
Type of associated data proxy being created.
Auxiliary data from one-to-(zero-or-one) sequential association.
Aux aux_element_t
Type of the auxiliary associated datum (&quot;right&quot;).
static auto make(Event const &event, Handle &&mainHandle, MainArgs const &, art::InputTag const &auxInputTag)
Create a association proxy collection using the specified tag.
Creates an one-to-(zero-or-one) wrapper for the specified types.
Main main_element_t
Type of the main datum (&quot;left&quot;).
Object for one-to-zero/or/one associated data interface.
Definition: OneTo01Data.h:71
static auto make(Event const &event, Handle &&mainHandle, MainArgs const &margs, Args &&...args)
Create a association proxy collection using main collection tag.
j template void())
Definition: json.hpp:3108
typename aux_collection_proxy_t::assns_t assns_t
Type of art association being used as input.
Helper functions to create data structures associated to a proxy.
Tag data_tag
Tag labelling the associated data we are going to produce.
Creates an one-to-(zero-or-one) wrapper for the specified types.