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