LArSoft  v09_90_00
Liquid Argon Software toolkit - https://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 "larcorealg/CoreUtils/DebugUtils.h" // lar::debug::demangle()
16 #include "larcorealg/CoreUtils/MetaUtils.h" // util::always_true_type, ...
17 #include "lardata/Utilities/TupleLookupByTag.h" // util::index_of_tag_v, ...
18 
19 // C/C++ standard
20 #include <cstdlib> // std::size_t
21 #include <stdexcept> // std::logic_error
22 #include <tuple> // also std::tuple_element_t<>, std::get()
23 #include <type_traits> // std::integral_constant<>
24 #include <utility> // std::move()
25 
26 namespace proxy {
27 
28  namespace details {
29 
30  template <typename AuxCollTuple>
32 
33  } // namespace details
34 
35  //--- BEGIN Proxy element infrastructure -------------------------------------
50  //----------------------------------------------------------------------------
157  template <typename CollProxy>
159 
160  public:
161  using collection_proxy_t = CollProxy;
162  using main_element_t = typename collection_proxy_t::main_element_t;
163 
165  using aux_elements_t =
167 
170  CollectionProxyElement(std::size_t index, main_element_t const& main, aux_elements_t&& auxData)
171  : fIndex(index), fMain(&main), fAuxData(std::move(auxData))
172  {}
173 
175  main_element_t const* operator->() const { return fMain; }
176 
178  main_element_t const& operator*() const { return *fMain; }
179 
181  std::size_t index() const { return fIndex; };
182 
184  template <typename Tag>
185  auto get() const -> decltype(auto)
186  {
187  return std::get<util::index_of_tag_v<Tag, aux_elements_t>>(fAuxData);
188  }
189 
260  template <typename Tag, typename T = Tag const&>
261  [[deprecated("Use C++17 constexpr if instead and get() instead")]] auto getIf() const
262  -> decltype(auto);
263 
265  template <typename Tag>
266  static constexpr bool has()
267  {
268  return util::has_tag_v<Tag, aux_elements_t>;
269  }
270 
271  private:
272  std::size_t fIndex;
274 
275  // note that the auxiliary data is not tagged, we need to learn which
276  // the tags are from the collection.
278 
279  template <typename Tag, typename>
280  auto getIfHas(std::bool_constant<true>) const -> decltype(auto);
281 
282  template <typename Tag, typename T>
283  [[noreturn]] auto getIfHas(std::bool_constant<false>) const -> T;
284 
285  }; // CollectionProxyElement<>
286 
288  //--- END Proxy element infrastructure ---------------------------------------
289 
290  //----------------------------------------------------------------------------
291  namespace details {
292 
293  //--------------------------------------------------------------------------
294  //--- Stuff for the whole collection proxy
295  //--------------------------------------------------------------------------
305  template <typename ProxyElement, typename... AuxData>
306  auto makeCollectionProxyElement(std::size_t index,
307  typename ProxyElement::main_element_t const& main,
308  AuxData&&... auxData)
309  {
310  return ProxyElement(
311  index, main, typename ProxyElement::aux_elements_t(std::forward<AuxData>(auxData)...));
312  } // makeCollectionProxyElement()
313 
314  //--------------------------------------------------------------------------
315 
316  } // namespace details
317 
318 } // namespace proxy
319 
320 //------------------------------------------------------------------------------
321 //--- template implementation
322 //------------------------------------------------------------------------------
323 namespace proxy {
324 
325  namespace details {
326 
327  //--------------------------------------------------------------------------
328  //--- stuff for auxiliary data
329  //--------------------------------------------------------------------------
330  // Trait replacing each element of the specified tuple with its
331  // `auxiliary_data_t`
332  template <typename Tuple>
333  struct SubstituteWithAuxList {
334  static_assert(util::always_true_type<Tuple>(), "Template argument must be a tuple");
335  }; // SubstituteWithAuxList<>
336 
337  template <typename... T>
338  struct SubstituteWithAuxList<std::tuple<T...>> {
339  using type = std::tuple<typename T::auxiliary_data_t...>;
340  }; // SubstituteWithAuxList<tuple>
341 
342  //--------------------------------------------------------------------------
343 
344  } // namespace details
345 
346  //----------------------------------------------------------------------------
347  //--- CollectionProxyElement
348  //----------------------------------------------------------------------------
349  template <typename CollProxy>
350  template <typename Tag, typename T>
351  auto CollectionProxyElement<CollProxy>::getIf() const -> decltype(auto)
352  {
353  return getIfHas<Tag, T>(std::bool_constant<has<Tag>()>{});
354  }
355 
356  //----------------------------------------------------------------------------
357  template <typename CollProxy>
358  template <typename Tag, typename>
359  auto CollectionProxyElement<CollProxy>::getIfHas(std::bool_constant<true>) const -> decltype(auto)
360  {
361  return get<Tag>();
362  }
363 
364  template <typename CollProxy>
365  template <typename Tag, typename T>
366  auto CollectionProxyElement<CollProxy>::getIfHas(std::bool_constant<false>) const -> T
367  {
368  throw std::logic_error("Tag '" + lar::debug::demangle<Tag>() + "' not available.");
369  }
370 
371  //----------------------------------------------------------------------------
372 
373 } // namespace proxy
374 
375 #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.
Basic C++ metaprogramming utilities.
int main()
Definition: example_main.cc:17
typename collection_proxy_t::main_element_t main_element_t
STL namespace.
std::integral_constant< bool, Value > bool_constant
Definition: ProviderPack.h:298
auto getIfHas(std::bool_constant< true >) const -> decltype(auto)
aux_elements_t fAuxData
Data associated to the main object.
typename details::SubstituteWithAuxList< typename collection_proxy_t::aux_collections_t >::type aux_elements_t
Tuple of elements (expected to be tagged types).
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:140
An element of a collection proxy.
Functions to help debugging by instrumenting code.
Utilities to address elements of a tuple-like class by tag.
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.
CollectionProxyElement(std::size_t index, main_element_t const &main, aux_elements_t &&auxData)