LArSoft  v09_90_00
Liquid Argon Software toolkit - https://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
15 #include "larcorealg/CoreUtils/ContainerMeta.h" // util::collection_value_t, ...
16 #include "larcorealg/CoreUtils/MetaUtils.h" // util::always_true_type
18 
19 // framework libraries
21 
22 // C/C++ standard
23 #include <vector>
24 
25 namespace proxy {
26 
27  // --- BEGIN Collection proxy infrastructure ---------------------------------
30 
31  //----------------------------------------------------------------------------
55  template <typename Proxy, typename Selector = Proxy>
57  static_assert(util::always_true_type<Proxy>(), "This class requires specialization.");
58  };
59 
60  //----------------------------------------------------------------------------
80  template <typename CollProxy>
82 
85 
87  using main_collection_proxy_t = typename traits_t::main_collection_proxy_t;
88 
90  using main_element_t = typename traits_t::main_element_t;
91 
93  using main_collection_t = typename traits_t::main_collection_t;
94 
114  template <typename Event, typename... WithArgs>
115  static auto make(Event const& event, art::InputTag const& tag, WithArgs&&... withArgs);
116 
117  }; // struct CollectionProxyMakerBase<>
118 
119  //----------------------------------------------------------------------------
138  template <typename CollProxy>
140 
142  // --- END Collection proxy infrastructure -----------------------------------
143 
144  //----------------------------------------------------------------------------
145  //--- specializations of CollectionProxyMakerTraits
146  //----------------------------------------------------------------------------
147 
148  template <typename T>
150 
152  using main_collection_t = std::vector<T>;
153 
156 
159 
160  }; // CollectionProxyMakerTraits<std::vector<T>>
161 
162  template <typename MainColl>
166 
169 
172 
173  }; // CollectionProxyMakerTraits<CollectionProxy>
174 
175  // ---------------------------------------------------------------------------
176 
177 } // namespace proxy
178 
179 // -----------------------------------------------------------------------------
180 // --- Template implementation
181 // -----------------------------------------------------------------------------
182 namespace proxy {
183 
184  namespace details {
185 
186  // -------------------------------------------------------------------------
187  //
188  // We need to discover whether the trait class contains a
189  // `collection_proxy_impl_t` type. Unfortunately, that is not a plain type
190  // but rather a template type (it is expected to take the same template
191  // arguments as `proxy::CollectionProxy`).
192  //
193  // Since Gianluca is not able to detect the presence of a templated type in
194  // a class, but only of fully specified type, the following machinery is in
195  // place. At the time we need to know the `collection_proxy_impl_t` type, we
196  // are trying to create one and therefore we know the full argument set for
197  // it already (let's call it `Args...`, that is `MainColl` plus
198  // `AuxColls...`). Then, we test the presence of
199  // `collection_proxy_impl_t<Args...>` instead of just
200  // `collection_proxy_impl_t`.
201  // An additional complication is the presence of a parameter pack, that
202  // impedes the usual pattern of having `std::enable_if_t` as the last,
203  // optional template parameter (`Args` must be the last). So we give up the
204  // elegant feature of having a default value, and we force the caller to
205  // explicitly spell it: `void` (always that one).
206  // We absorb this ugliness and the need for the usual and cumbersome
207  // `typename ...::type` in the definition of
208  // `CollectionProxyImplFromTraits_t`, which should be the only access point
209  // to this machinery.
210  // About the naming: a "collection proxy" is the final proxy class.
211  // `CollectionProxy` is also the name, already taken, of the class we
212  // provide as reference for that role. So I have called the role an
213  // "implementation" of the "collection proxy" idea, and `CollectionProxy` is
214  // in fact an implementation (the "standard" one) of that idea.
215  // The name of that idea in the proxy traits is `collection_proxy_impl_t`.
216  // `CollectionProxyImpl` is supposed to be a generic name for that concept,
217  // and the utility `CollectionProxyImplFromTraits` is in charge of
218  // extracting it from the traits. This utility also needs an implementation,
219  // hence the second "Impl": `CollectionProxyImplFromTraitsImpl`. Urgh.
220  //
221  // I don't know whether to be worried that the explanation of this code is
222  // longer than the code itself...
223  //
224  template <typename Traits, typename, typename... Args>
226  using type = CollectionProxyFromArgs<Args...>;
227  };
228 
229  template <typename Traits, typename... Args>
231  Traits,
232  std::enable_if_t<
233  util::always_true_v<typename Traits::template collection_proxy_impl_t<Args...>>>,
234  Args...> {
235  using type = typename Traits::template collection_proxy_impl_t<Args...>;
236  };
237 
240  template <typename Traits, typename... Args>
242  typename CollectionProxyImplFromTraitsImpl<Traits, void, Args...>::type;
243 
244  // -------------------------------------------------------------------------
245  template <typename Traits, typename... Args>
246  auto createCollectionProxyFromTraits(Args&&... args)
247  {
248  using collection_proxy_impl_t =
250  return collection_proxy_impl_t(std::forward<Args>(args)...);
251  } // createCollectionProxyFromTraits()
252 
253  // -------------------------------------------------------------------------
254 
255  } // namespace details
256 
257  // ---------------------------------------------------------------------------
258  // --- CollectionProxyMakerBase implementation
259  // ---------------------------------------------------------------------------
260  template <typename CollProxy>
261  template <typename Event, typename... WithArgs>
263  art::InputTag const& tag,
264  WithArgs&&... withArgs)
265  {
266  auto mainHandle = event.template getValidHandle<main_collection_t>(tag);
267 
268  // The actual type of collection proxy implementation is extracted from
269  // the traits of the proxy (`collection_proxy_impl_t`), but if that is not
270  // provided a default implementation, `proxy::CollectionProxy`, is used:
271  return details::createCollectionProxyFromTraits<traits_t>(
272  *mainHandle,
273  withArgs.template createAuxProxyMaker<main_collection_proxy_t>(event, mainHandle, tag)...);
274  } // CollectionProxyMakerBase<>::make<>()
275 
276  // ---------------------------------------------------------------------------
277 
278 } // namespace proxy
279 
280 #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.
std::unique_ptr< InputSource > make(fhicl::ParameterSet const &conf, InputSourceDescription &desc)
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:1154
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:289
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:140
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:62
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.