LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
CollectionProxyElement.h
Go to the documentation of this file.
1 
11 #ifndef LARDATA_RECOBASEPROXY_PROXYBASE_COLLECTIONPROXYELEMENT_H
12 #define LARDATA_RECOBASEPROXY_PROXYBASE_COLLECTIONPROXYELEMENT_H
13 
14 // LArSoft libraries
15 #include "lardata/Utilities/TupleLookupByTag.h" // util::index_of_tag_v, ...
16 #include "larcorealg/CoreUtils/MetaUtils.h" // util::always_true_type, ...
17 #include "larcorealg/CoreUtils/DebugUtils.h" // lar::debug::demangle()
18 
19 // C/C++ standard
20 #include <tuple> // also std::tuple_element_t<>, std::get()
21 #include <utility> // std::move()
22 #include <stdexcept> // std::logic_error
23 #include <type_traits> // std::integral_constant<>
24 #include <cstdlib> // std::size_t
25 
26 
27 
28 namespace proxy {
29 
30 
31  namespace details {
32 
33  template <typename AuxCollTuple>
35 
36  } // namespace details
37 
38 
39  //--- BEGIN Proxy element infrastructure -------------------------------------
54  //----------------------------------------------------------------------------
161  template <typename CollProxy>
163 
164  public:
165  using collection_proxy_t = CollProxy;
166  using main_element_t = typename collection_proxy_t::main_element_t;
167 
170  <typename collection_proxy_t::aux_collections_t>::type;
171 
175  (std::size_t index, main_element_t const& main, aux_elements_t&& auxData)
176  : fIndex(index), fMain(&main) , fAuxData(std::move(auxData))
177  {}
178 
180  main_element_t const* operator->() const { return fMain; }
181 
183  main_element_t const& operator*() const { return *fMain; }
184 
186  std::size_t index() const { return fIndex; };
187 
189  template <typename Tag>
190  auto get() const -> decltype(auto)
191  { return std::get<util::index_of_tag_v<Tag, aux_elements_t>>(fAuxData); }
192 
193 
261  template <typename Tag, typename T = Tag const&>
262  auto getIf() const -> decltype(auto);
263 
264 
266  template <typename Tag>
267  static constexpr bool has() { return util::has_tag_v<Tag, aux_elements_t>; }
268 
269  private:
270 
271  std::size_t fIndex;
273 
274  // note that the auxiliary data is not tagged, we need to learn which
275  // the tags are from the collection.
277 
278  template <typename Tag, typename>
279  auto getIfHas(util::bool_constant<true>) const -> decltype(auto);
280 
281  template <typename Tag, typename T>
282  [[noreturn]] auto getIfHas(util::bool_constant<false>) const -> T;
283 
284  }; // CollectionProxyElement<>
285 
286 
288  //--- END Proxy element infrastructure ---------------------------------------
289 
290 
291  //----------------------------------------------------------------------------
292  namespace details {
293 
294  //--------------------------------------------------------------------------
295  //--- Stuff for the whole collection proxy
296  //--------------------------------------------------------------------------
306  template <typename ProxyElement, typename... AuxData>
308  std::size_t index,
309  typename ProxyElement::main_element_t const& main,
310  AuxData&&... auxData
311  ) {
312  return ProxyElement(
313  index, main,
314  typename ProxyElement::aux_elements_t(std::forward<AuxData>(auxData)...)
315  );
316  } // makeCollectionProxyElement()
317 
318 
319  //--------------------------------------------------------------------------
320 
321  } // namespace details
322 
323 } // namespace proxy
324 
325 
326 //------------------------------------------------------------------------------
327 //--- template implementation
328 //------------------------------------------------------------------------------
329 namespace proxy {
330 
331  namespace details {
332 
333  //--------------------------------------------------------------------------
334  //--- stuff for auxiliary data
335  //--------------------------------------------------------------------------
336  // Trait replacing each element of the specified tuple with its
337  // `auxiliary_data_t`
338  template <typename Tuple>
339  struct SubstituteWithAuxList {
340  static_assert
341  (util::always_true_type<Tuple>(), "Template argument must be a tuple");
342  }; // SubstituteWithAuxList<>
343 
344  template <typename... T>
345  struct SubstituteWithAuxList<std::tuple<T...>> {
346  using type = std::tuple<typename T::auxiliary_data_t...>;
347  }; // SubstituteWithAuxList<tuple>
348 
349  //--------------------------------------------------------------------------
350 
351  } // namespace details
352 
353 
354  //----------------------------------------------------------------------------
355  //--- CollectionProxyElement
356  //----------------------------------------------------------------------------
357  template <typename CollProxy>
358  template <typename Tag, typename T>
359  auto CollectionProxyElement<CollProxy>::getIf() const -> decltype(auto)
360  { return getIfHas<Tag, T>(util::bool_constant<has<Tag>()>{}); }
361 
362 
363  //----------------------------------------------------------------------------
364  template <typename CollProxy>
365  template <typename Tag, typename>
367  (util::bool_constant<true>) const -> decltype(auto)
368  { return get<Tag>(); }
369 
370  template <typename CollProxy>
371  template <typename Tag, typename T>
374  {
375  throw std::logic_error
376  ("Tag '" + lar::debug::demangle<Tag>() + "' not available.");
377  }
378 
379 
380  //----------------------------------------------------------------------------
381 
382 } // namespace proxy
383 
384 
385 #endif // LARDATA_RECOBASEPROXY_PROXYBASE_COLLECTIONPROXYELEMENT_H
main_element_t const * operator->() const
Returns a pointer to the main element.
auto makeCollectionProxyElement(std::size_t index, typename ProxyElement::main_element_t const &main, AuxData &&...auxData)
Creates a collection proxy element object from data structures.
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:17
Basic C++ metaprogramming utilities.
int main(int argc, char **argv)
Definition: main.cpp:72
typename collection_proxy_t::main_element_t main_element_t
std::integral_constant< bool, Value > bool_constant
Definition: MetaUtils.h:168
STL namespace.
aux_elements_t fAuxData
Data associated to the main object.
static constexpr bool has()
Returns whether this class knowns about the specified type (Tag).
main_element_t const * fMain
Pointer to the main object of the element.
Encloses LArSoft data product proxy objects and utilities.See this doxygen module for an introduction...
std::size_t index() const
Returns the index of this element in the collection.
std::size_t fIndex
Index of this element in the proxy.
A std::true_type with a template argument.
Definition: MetaUtils.h:139
An element of a collection proxy.
Functions to help debugging by instrumenting code.
typename details::SubstituteWithAuxList< typename collection_proxy_t::aux_collections_t >::type aux_elements_t
Tuple of elements (expected to be tagged types).
Utilities to address elements of a tuple-like class by tag.
std::tuple< typename T::auxiliary_data_t... > type
auto getIf() const -> decltype(auto)
Returns the auxiliary data specified by type (Tag).
main_element_t const & operator*() const
Returns a reference to the main element.
auto getIfHas(util::bool_constant< true >) const -> decltype(auto)