LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
Iterable.h
Go to the documentation of this file.
1 #ifndef LARCOREALG_GEOMETRY_ITERABLE_H
2 #define LARCOREALG_GEOMETRY_ITERABLE_H
3 
4 // LArSoft libraries
9 
10 // External libraries
11 #include "range/v3/view.hpp"
12 
13 // C/C++ standard libraries
14 #include <type_traits>
15 #include <utility>
16 
17 namespace geo {
18 
19  struct void_tag {};
20 
21  namespace details {
22  template <typename T, typename = void>
24  static_assert(std::is_base_of_v<CryostatID, T>);
25  using type = T;
26  };
27 
28  template <typename T>
29  struct IDIteratorValueType<T, std::void_t<typename T::ID_t>> {
30  static_assert(!std::is_base_of_v<CryostatID, T>);
31  using type = typename T::ID_t;
32  };
33 
34  template <typename T, typename Policy, typename Transform, typename = void>
35  struct IteratorFor {
36  using ID = typename IDIteratorValueType<T>::type;
37  using type = decltype(iterator_for(ID{}, std::declval<Policy>()));
38  };
39 
40  template <typename T, typename Policy, typename Transform>
41  struct IteratorFor<T,
42  Policy,
43  Transform,
44  std::enable_if_t<!std::is_same_v<Transform, void_tag> and
45  !std::is_base_of_v<CryostatID, T>>> {
46  using ID = typename IDIteratorValueType<T>::type;
47  using type = decltype(std::declval<Transform>().template transform<T>(
48  iterator_for(ID{}, std::declval<Policy>())));
49  };
50 
51  template <typename Begin, typename End>
52  using RangeType = decltype(ranges::make_subrange(std::declval<Begin>(), std::declval<End>()));
53  }
54 
55  template <typename IterationPolicy, typename Transform = void_tag>
56  class Iterable {
57  template <typename T>
59 
60  template <typename T>
62 
63  public:
64  explicit Iterable(IterationPolicy const& policy) : fPolicy{policy} {}
65 
66  Iterable(IterationPolicy const& policy, Transform const& transform)
67  : fPolicy{policy}, fTransform{transform}
68  {}
69 
70  // FIXME: Need Doxygen comments
71  template <typename T>
73  {
74  using namespace details;
75  using ID = typename IDIteratorValueType<T>::type;
76  auto const iterator = iterator_for(ID::first(), fPolicy);
77  if constexpr (std::is_base_of<CryostatID, T>{}) { return iterator; }
78  else {
79  static_assert(!std::is_same_v<Transform, void_tag>);
80  return fTransform.template transform<T>(iterator);
81  }
82  }
83 
84  template <typename T, typename BaseID>
85  iterator_type<T> begin(BaseID const& id) const
86  {
87  using namespace details;
88  using ID = typename IDIteratorValueType<T>::type;
89  static_assert(is_base_of_strict<BaseID, ID>);
90  auto const iterator = iterator_for(ID::first(id), fPolicy);
91  if constexpr (std::is_base_of<CryostatID, T>{}) { return iterator; }
92  else {
93  static_assert(!std::is_same_v<Transform, void_tag>);
94  return fTransform.template transform<T>(iterator);
95  }
96  }
97 
98  template <typename T>
100  {
101  using namespace details;
102  using ID = typename IDIteratorValueType<T>::type;
103  static_assert(std::is_base_of<CryostatID, ID>{});
104  return {fPolicy.template GetEndID<ID>()};
105  }
106 
107  template <typename T, typename BaseID>
108  id_sentinel_for<T> end(BaseID const& id) const
109  {
110  using namespace details;
111  using ID = typename IDIteratorValueType<T>::type;
112  static_assert(std::is_base_of<CryostatID, ID>{});
113  static_assert(is_base_of_strict<BaseID, ID>);
114  return {fPolicy.template GetEndID<ID>(id)};
115  }
116 
117  template <typename T>
119 
120  template <typename T>
122  {
123  return ranges::make_subrange(begin<T>(), end<T>());
124  }
125 
126  template <typename T, typename ID>
127  range_type<T> Iterate(ID const& id) const
128  {
129  return ranges::make_subrange(begin<T>(id), end<T>(id));
130  }
131 
132  private:
133  IterationPolicy fPolicy;
134  std::conditional_t<std::is_same_v<Transform, void>, void_tag, Transform> fTransform;
135  }; // Iterable
136 
137 } // namespace geo
138 
139 #endif // LARCOREALG_GEOMETRY_ITERABLE_H
intermediate_table::iterator iterator
Policy
Enumeration of all supported random seed policies.
Definition: PolicyNames.h:38
typename details::IteratorFor< T, details::ReadoutIterationPolicy, details::ToReadoutGeometryElement >::type iterator_type
Definition: Iterable.h:61
details::RangeType< iterator_type< T >, id_sentinel_for< T >> range_type
Definition: Iterable.h:118
STL namespace.
iterator_type< T > begin(BaseID const &id) const
Definition: Iterable.h:85
iterator_type< T > begin() const
Definition: Iterable.h:72
id_sentinel_for< T > end(BaseID const &id) const
Definition: Iterable.h:108
IterationPolicy fPolicy
Definition: Iterable.h:133
auto iterator_for(LocalID const &id, SiblingPolicy const &siblingPolicy)
Definition: id_iterators.h:236
typename IDIteratorValueType< T >::type ID
Definition: Iterable.h:36
Definition of data types for geometry description.
range_type< T > Iterate(ID const &id) const
Definition: Iterable.h:127
id_sentinel_for< T > end() const
Definition: Iterable.h:99
Iterable(IterationPolicy const &policy)
Definition: Iterable.h:64
decltype(ranges::make_subrange(std::declval< Begin >(), std::declval< End >())) RangeType
Definition: Iterable.h:52
std::conditional_t< std::is_same_v< Transform, void >, void_tag, Transform > fTransform
Definition: Iterable.h:134
range_type< T > Iterate() const
Definition: Iterable.h:121
ROOT libraries.
Iterable(IterationPolicy const &policy, Transform const &transform)
Definition: Iterable.h:66
decltype(iterator_for(ID{}, std::declval< Policy >())) type
Definition: Iterable.h:37