LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
CollectionProxy.h
Go to the documentation of this file.
1 
11 #ifndef LARDATA_RECOBASEPROXY_PROXYBASE_COLLECTIONPROXY_H
12 #define LARDATA_RECOBASEPROXY_PROXYBASE_COLLECTIONPROXY_H
13 
14 // LArSoft libraries
17 #include "lardata/Utilities/TupleLookupByTag.h" // util::type_with_tag_t, ...
18 #include "larcorealg/CoreUtils/ContainerMeta.h" // util::collection_value_t, ...
19 
20 // C/C++ standard
21 #include <vector>
22 #include <tuple>
23 #include <utility> // std::move()
24 #include <limits> // std::numeric_limits<>
25 #include <cstdlib> // std::size_t
26 
27 
28 namespace proxy {
29 
30  namespace details {
31 
32  template <typename Cont>
34 
35  template <template <typename, typename...> class F, typename...>
37 
38  } // namespace details
39 
40 
41  // --- BEGIN Collection proxy infrastructure ---------------------------------
79  //----------------------------------------------------------------------------
112  template <
113  template <typename CollProxy> class Element,
114  typename MainColl,
115  typename... AuxColls
116  >
118  : public details::MainCollectionProxy<MainColl>, public AuxColls...
119  {
121  using collection_proxy_t
122  = CollectionProxyBase<Element, MainColl, AuxColls...>;
123 
126 
127  public:
130 
133 
135  using element_proxy_t = Element<collection_proxy_t>;
136 
138  using aux_collections_t = std::tuple<AuxColls...>;
139 
142 
145 
148 
158  CollectionProxyBase(main_collection_t const& main, AuxColls&&... aux)
159  : main_collection_proxy_t(main), AuxColls(std::move(aux))...
160  {}
161 
172  element_proxy_t const operator[] (std::size_t i) const
173  {
174  return details::makeCollectionProxyElement<element_proxy_t>
175  (i, getMainAt(i), aux<AuxColls>().operator[](i)...);
176  }
177 
179  const_iterator begin() const { return makeIterator(0U); }
180 
182  const_iterator end() const { return makeIterator(size()); }
183 
185  bool empty() const { return main().empty(); }
186 
188  std::size_t size() const { return main().size(); }
189 
190 
192  template <typename AuxTag>
193  auto get() const -> decltype(auto) { return auxByTag<AuxTag>(); }
194 
195 
246  template <typename Tag, typename T = std::vector<Tag> const&>
247  auto getIf() const -> decltype(auto);
248 
249 
251  template <typename Tag>
252  static constexpr bool has()
253  { return util::has_tag_v<Tag, aux_collections_t>; }
254 
255 
256  protected:
258  using main_collection_proxy_t::mainProxy;
259  using main_collection_proxy_t::getMainAt;
260 
262  template <typename AuxColl>
263  AuxColl const& aux() const { return static_cast<AuxColl const&>(*this); }
264 
266  template <typename AuxTag>
267  auto auxByTag() const -> decltype(auto)
268  { return aux<util::type_with_tag_t<AuxTag, aux_collections_t>>(); }
269 
270 
271  template <typename Tag, typename>
272  auto getIfHas(util::bool_constant<true>) const -> decltype(auto);
273  template <typename Tag, typename T>
274  [[noreturn]] auto getIfHas(util::bool_constant<false>) const -> T;
275 
277  const_iterator makeIterator(std::size_t i) const { return { *this, i }; }
278 
279 
281  "Some auxiliary data collections share the same tag. They should not.");
282 
283  }; // struct CollectionProxyBase
284 
285 
286  //----------------------------------------------------------------------------
296  template <typename MainColl, typename... AuxColls>
297  using CollectionProxy
298  = CollectionProxyBase<CollectionProxyElement, MainColl, AuxColls...>;
299 
300 
301  // this joke is necessary because expanding directly CollectionProxy<Args...>
302  // into CollectionProxy<Main, Aux...> template arguments does not work
303  template <typename... Args>
306 
307 
309  // --- END Collection proxy infrastructure -----------------------------------
310 
311  //----------------------------------------------------------------------------
312  namespace details {
313 
314  //--------------------------------------------------------------------------
316  template <
317  template <typename...> class CollProxy,
318  typename MainColl, typename... AuxColl
319  >
320  auto createCollectionProxy(MainColl const& main, AuxColl&&... aux)
321  {
322  return CollProxy<MainColl, AuxColl...>
323  (main, std::forward<AuxColl>(aux)...);
324  }
325 
326  //--------------------------------------------------------------------------
328  template <typename MainColl, typename... AuxColl>
329  auto makeCollectionProxy(MainColl const& main, AuxColl&&... aux)
330  {
331  return createCollectionProxy<CollectionProxy>
332  (main, std::forward<AuxColl>(aux)...);
333  }
334 
335  //--------------------------------------------------------------------------
342  template <typename Cont>
343  class IndexBasedIterator {
344 
345  public:
346  using container_t = Cont;
347 
350 
352  IndexBasedIterator() = default;
353 
355  IndexBasedIterator(container_t const& cont, std::size_t index = 0)
356  : fCont(&cont), fIndex(index) {}
357 
359  auto operator* () const -> decltype(auto)
360  { return fCont->operator[](fIndex); }
361 
363  const_iterator& operator++ () { ++fIndex; return *this; }
364 
366  bool operator!= (const_iterator const& other) const
367  { return (other.fIndex != fIndex) || (other.fCont != fCont); }
368 
369  protected:
370  container_t const* fCont = nullptr;
371 
374 
375  }; // IndexBasedIterator<>
376 
377  } // namespace details
378 
379 } // namespace proxy
380 
381 
382 //------------------------------------------------------------------------------
383 //--- template implementation
384 //------------------------------------------------------------------------------
385 namespace proxy {
386 
387  namespace details {
388 
389  //--------------------------------------------------------------------------
390  template <
391  template <typename, typename...> class F,
392  typename First, typename... Others
393  >
394  struct TemplateAdaptorOnePlus<F, First, Others...>
395  { using type = F<First, Others...>; };
396 
397  } // namespace details
398 
399 
400  //----------------------------------------------------------------------------
401  //--- CollectionProxyBase
402  //----------------------------------------------------------------------------
403  template <
404  template <typename CollProxy> class Element,
405  typename MainColl,
406  typename... AuxColls
407  >
408  template <typename Tag, typename T>
410  -> decltype(auto)
411  { return getIfHas<Tag, T>(util::bool_constant<has<Tag>()>{}); }
412 
413 
414  template <
415  template <typename CollProxy> class Element,
416  typename MainColl,
417  typename... AuxColls
418  >
419  template <typename Tag, typename>
421  (util::bool_constant<true>) const -> decltype(auto)
422  { return get<Tag>(); }
423 
424  template <
425  template <typename CollProxy> class Element,
426  typename MainColl,
427  typename... AuxColls
428  >
429  template <typename Tag, typename T>
432  {
433  throw std::logic_error
434  ("Tag '" + lar::debug::demangle<Tag>() + "' not available.");
435  }
436 
437 
438  //----------------------------------------------------------------------------
439 
440 } // namespace proxy
441 
442 
443 #endif // LARDATA_RECOBASEPROXY_PROXYBASE_COLLECTIONPROXY_H
const_iterator begin() const
Returns an iterator to the first element of the collection.
std::tuple< AuxColls... > aux_collections_t
Tuple of all auxiliary data collections (wrappers).
util::collection_value_t< MainColl > main_element_t
Type of the elements in the original collection.
std::size_t fIndex
Current index in the main collection.
CollectionProxyBase< CollectionProxyElement, MainColl, AuxColls... > CollectionProxy
Base representation of a collection of proxied objects.
typename details::TemplateAdaptorOnePlus< CollectionProxy, Args... >::type CollectionProxyFromArgs
int main(int argc, char **argv)
Definition: main.cpp:72
CollectionProxyBase(main_collection_t const &main, AuxColls &&...aux)
Constructor: uses the specified data.
std::integral_constant< bool, Value > bool_constant
Definition: MetaUtils.h:168
STL namespace.
auto auxByTag() const -> decltype(auto)
Returns the auxiliary data specified by type.
Iterator to random access collection storing a current index.
Base representation of a collection of proxied objects.
Wrapper for the main collection of a proxy.
auto makeCollectionProxy(MainColl const &main, AuxColl &&...aux)
Creates a CollectionProxy object with the given arguments.
auto createCollectionProxy(MainColl const &main, AuxColl &&...aux)
Creates a collection proxy of a specified type with the given arguments.
const_iterator makeIterator(std::size_t i) const
Returns an iterator pointing to the specified index of this collection.
Proxy class for charged space point proxy elements.
Int_t max
Definition: plot.C:27
intermediate_table::const_iterator const_iterator
bool empty() const
Returns whether this collection is empty.
Utilities for the main collection of a collection proxy.
Utilities for a single element of a collection proxy.
Encloses LArSoft data product proxy objects and utilities.See this doxygen module for an introduction...
auto getIfHas(util::bool_constant< true >) const -> decltype(auto)
MainColl main_collection_t
Type of the original collection.
bool operator!=(AssnsNode< ArtAssnsIterValue > const &A, typename AssnsNode< ArtAssnsIterValue >::valueptr_t const &B)
const_iterator end() const
Returns an iterator past the last element of the collection.
Traits holding whether elements of Tuple have duplicate types.
container_t const * fCont
Pointer to the original container.
IndexBasedIterator(container_t const &cont, std::size_t index=0)
Constructor: initializes from an iterator of the proxy main collection.
std::size_t size() const
Returns the size of this collection.
static constexpr bool has()
Returns whether this class knowns about the specified type (Tag).
An element of a collection proxy.
Utilities to address elements of a tuple-like class by tag.
util::collection_value_t< container_t > value_type
AuxColl const & aux() const
Returns the auxiliary data specified by type.
typename collection_value_type< Coll >::type collection_value_t
Type contained in the collection Coll.
Definition: ContainerMeta.h:65
C++ metaprogramming utilities for dealing with containers.
QuadExpr operator*(double v, const QuadExpr &e)
Definition: QuadExpr.h:39
auto getIf() const -> decltype(auto)
Returns the auxiliary data specified by type (Tag).