LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
CollectionProxyMaker.h
Go to the documentation of this file.
1 
11 #ifndef LARDATA_RECOBASEPROXY_PROXYBASE_COLLECTIONPROXYMAKER_H
12 #define LARDATA_RECOBASEPROXY_PROXYBASE_COLLECTIONPROXYMAKER_H
13 
14 // LArSoft libraries
16 #include "larcorealg/CoreUtils/ContainerMeta.h" // util::collection_value_t, ...
17 #include "larcorealg/CoreUtils/MetaUtils.h" // util::always_true_type
18 
19 // framework libraries
21 
22 // C/C++ standard
23 #include <vector>
24 
25 
26 namespace proxy {
27 
28  // --- BEGIN Collection proxy infrastructure ---------------------------------
31 
32  //----------------------------------------------------------------------------
56  template <typename Proxy, typename Selector = Proxy>
58  static_assert
59  (util::always_true_type<Proxy>(), "This class requires specialization.");
60  };
61 
62 
63  //----------------------------------------------------------------------------
83  template <typename CollProxy>
85 
88 
90  using main_collection_proxy_t = typename traits_t::main_collection_proxy_t;
91 
93  using main_element_t = typename traits_t::main_element_t;
94 
96  using main_collection_t = typename traits_t::main_collection_t;
97 
117  template <typename Event, typename... WithArgs>
118  static auto make
119  (Event const& event, art::InputTag const& tag, WithArgs&&... withArgs);
120 
121  }; // struct CollectionProxyMakerBase<>
122 
123 
124  //----------------------------------------------------------------------------
143  template <typename CollProxy>
145 
146 
148  // --- END Collection proxy infrastructure -----------------------------------
149 
150 
151  //----------------------------------------------------------------------------
152  //--- specializations of CollectionProxyMakerTraits
153  //----------------------------------------------------------------------------
154 
155  template <typename T>
157 
159  using main_collection_t = std::vector<T>;
160 
163 
167 
168  }; // CollectionProxyMakerTraits<std::vector<T>>
169 
170 
171  template <typename MainColl>
175 
178 
180  using main_collection_t
182 
183  }; // CollectionProxyMakerTraits<CollectionProxy>
184 
185 
186  // ---------------------------------------------------------------------------
187 
188 } // namespace proxy
189 
190 
191 
192 // -----------------------------------------------------------------------------
193 // --- Template implementation
194 // -----------------------------------------------------------------------------
195 namespace proxy {
196 
197  namespace details {
198 
199  // -------------------------------------------------------------------------
200  //
201  // We need to discover whether the trait class contains a
202  // `collection_proxy_impl_t` type. Unfortunately, that is not a plain type
203  // but rather a template type (it is expected to take the same template
204  // arguments as `proxy::CollectionProxy`).
205  //
206  // Since Gianluca is not able to detect the presence of a templated type in
207  // a class, but only of fully specified type, the following machinery is in
208  // place. At the time we need to know the `collection_proxy_impl_t` type, we
209  // are trying to create one and therefore we know the full argument set for
210  // it already (let's call it `Args...`, that is `MainColl` plus
211  // `AuxColls...`). Then, we test the presence of
212  // `collection_proxy_impl_t<Args...>` instead of just
213  // `collection_proxy_impl_t`.
214  // An additional complication is the presence of a parameter pack, that
215  // impedes the usual pattern of having `std::enable_if_t` as the last,
216  // optional template parameter (`Args` must be the last). So we give up the
217  // elegant feature of having a default value, and we force the caller to
218  // explicitly spell it: `void` (always that one).
219  // We absorb this ugliness and the need for the usual and cumbersome
220  // `typename ...::type` in the definition of
221  // `CollectionProxyImplFromTraits_t`, which should be the only access point
222  // to this machinery.
223  // About the naming: a "collection proxy" is the final proxy class.
224  // `CollectionProxy` is also the name, already taken, of the class we
225  // provide as reference for that role. So I have called the role an
226  // "implementation" of the "collection proxy" idea, and `CollectionProxy` is
227  // in fact an implementation (the "standard" one) of that idea.
228  // The name of that idea in the proxy traits is `collection_proxy_impl_t`.
229  // `CollectionProxyImpl` is supposed to be a generic name for that concept,
230  // and the utility `CollectionProxyImplFromTraits` is in charge of
231  // extracting it from the traits. This utility also needs an implementation,
232  // hence the second "Impl": `CollectionProxyImplFromTraitsImpl`. Urgh.
233  //
234  // I don't know whether to be worried that the explanation of this code is
235  // longer than the code itself...
236  //
237  template <typename Traits, typename, typename... Args>
239  using type = CollectionProxyFromArgs<Args...>;
240  };
241 
242  template <typename Traits, typename... Args>
244  Traits,
245  std::enable_if_t<util::always_true_v
246  <typename Traits::template collection_proxy_impl_t<Args...>>
247  >,
248  Args...
249  >
250  {
251  using type = typename Traits::template collection_proxy_impl_t<Args...>;
252  };
253 
256  template <typename Traits, typename... Args>
258  = typename CollectionProxyImplFromTraitsImpl<Traits, void, Args...>::type;
259 
260 
261  // -------------------------------------------------------------------------
262  template <typename Traits, typename... Args>
263  auto createCollectionProxyFromTraits(Args&&... args) {
264  using collection_proxy_impl_t
266  return collection_proxy_impl_t(std::forward<Args>(args)...);
267  } // createCollectionProxyFromTraits()
268 
269 
270  // -------------------------------------------------------------------------
271 
272  } // namespace details
273 
274 
275  // ---------------------------------------------------------------------------
276  // --- CollectionProxyMakerBase implementation
277  // ---------------------------------------------------------------------------
278  template <typename CollProxy>
279  template <typename Event, typename... WithArgs>
281  (Event const& event, art::InputTag const& tag, WithArgs&&... withArgs)
282  {
283  auto mainHandle = event.template getValidHandle<main_collection_t>(tag);
284 
285  // The actual type of collection proxy implementation is extracted from
286  // the traits of the proxy (`collection_proxy_impl_t`), but if that is not
287  // provided a default implementation, `proxy::CollectionProxy`, is used:
288  return details::createCollectionProxyFromTraits<traits_t>(
289  *mainHandle,
290  withArgs.template createAuxProxyMaker<main_collection_proxy_t>
291  (event, mainHandle, tag)...
292  );
293  } // CollectionProxyMakerBase<>::make<>()
294 
295 
296  // ---------------------------------------------------------------------------
297 
298 } // namespace proxy
299 
300 #endif // LARDATA_RECOBASEPROXY_PROXYBASE_COLLECTIONPROXYMAKER_H
auto createCollectionProxyFromTraits(Args &&...args)
Collection of data type definitions for collection proxies.
Basic C++ metaprogramming utilities.
MainColl main_collection_t
Type of the original collection.
Class to assemble the required proxy.
typename details::TemplateAdaptorOnePlus< CollectionProxy, Args... >::type CollectionProxyFromArgs
util::collection_value_t< MainColl > main_element_t
Type of the elements in the original collection.
Define the traits of proxy::Tracks proxy.
Definition: Track.h:1202
STL namespace.
typename traits_t::main_element_t main_element_t
Type returned by the main collection indexing operator.
typename traits_t::main_collection_proxy_t main_collection_proxy_t
Type of main collection proxy.
Base representation of a collection of proxied objects.
Wrapper for the main collection of a proxy.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
typename main_collection_proxy_t::main_collection_t main_collection_t
Type of element of the main collection.
static auto make(Event const &event, art::InputTag const &tag, WithArgs &&...withArgs)
Creates and returns a collection proxy based on CollProxy and with the requested associated data...
Utilities for the collection proxy object.
Class to assemble the required proxy.
Encloses LArSoft data product proxy objects and utilities.See this doxygen module for an introduction...
A std::true_type with a template argument.
Definition: MetaUtils.h:139
util::collection_value_t< main_collection_t > main_element_t
Type returned by the main collection indexing operator.
std::vector< T > main_collection_t
Type of element of the main collection.
typename traits_t::main_collection_t main_collection_t
Type of element of the main collection.
typename collection_value_type< Coll >::type collection_value_t
Type contained in the collection Coll.
Definition: ContainerMeta.h:65
typename main_collection_proxy_t::main_element_t main_element_t
Type returned by the main collection indexing operator.
C++ metaprogramming utilities for dealing with containers.
typename CollectionProxyImplFromTraitsImpl< Traits, void, Args... >::type CollectionProxyImplFromTraits_t
Event finding and building.