LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
geometry_iterators.h
Go to the documentation of this file.
1 #ifndef LARCOREALG_GEOMETRY_DETAILS_GEOMETRY_ITERATORS_H
2 #define LARCOREALG_GEOMETRY_DETAILS_GEOMETRY_ITERATORS_H
3 
4 // LArSoft libraries
9 
10 // C/C++ standard libraries
11 #include <iterator> // std::forward_iterator_tag
12 #include <string>
13 #include <utility>
14 
15 namespace geo::details {
16 
19  public:
21  geometry_iterator_base(GeometryCore const* geom) : pGeo(geom) {}
22 
23  protected:
25  GeometryCore const* geometry() const { return pGeo; }
26 
28  geometry_iterator_base() = default;
29 
30  private:
31  GeometryCore const* pGeo = nullptr;
32 
33  }; // class geometry_iterator_base
34 
47  template <typename LocalID, typename GEOID>
49 
50  template <typename GEOID>
52  public:
53  using GeoID_t = GEOID;
54 
57 
58  static_assert(std::is_base_of<LocalID_t, GEOID>{}, "template type GEOID is not a LocalID_t");
59 
62  using difference_type = std::ptrdiff_t;
64  using reference = value_type const&;
65  using pointer = value_type const*;
66  using iterator_category = std::forward_iterator_tag;
68 
70  id_iterator_base() = default;
71 
73  id_iterator_base(GeometryCore const* geom, GeoID_t const& start_from)
74  : geometry_iterator_base{geom}, id{start_from}, limit{NSiblings(geom, localID())}
75  {}
76 
78  bool operator==(id_iterator_base const& as) const { return localID() == as.localID(); }
79 
80  bool operator!=(id_iterator_base const& as) const { return localID() != as.localID(); }
81 
83  reference operator*() const { return localID(); }
84 
86  pointer operator->() const { return &(localID()); }
87 
90  {
91  next();
92  return *this;
93  }
94 
97  {
98  iterator old(*this);
99  next();
100  return old;
101  }
102 
103  protected:
104  using ID_t = typename LocalID_t::CryostatID_t;
105 
107  GeoID_t const& ID() const { return id; }
109  GeoID_t& ID() { return id; }
111 
113  void next()
114  {
115  if (at_end()) return;
116  if (++local_index() < limit) return;
117  localID().isValid = false;
118  }
119 
121  bool at_end() const { return local_index() == limit; }
122 
123  private:
124  GeoID_t id{};
125  ID_t limit = LocalID_t::InvalidID;
126 
128  LocalID_t const& localID() const { return ID(); }
130  LocalID_t& localID() { return ID(); }
132 
134  ID_t const& local_index() const { return localID().deepestIndex(); }
136  ID_t& local_index() { return localID().deepestIndex(); }
138  }; // class id_iterator_base<CryostatID>
139 
157  template <typename LocalID, typename GEOID>
158  class id_iterator_base : protected id_iterator_base<typename LocalID::ParentID_t, GEOID> {
160 
161  public:
163 
164  using LocalID_t = LocalID;
165  static_assert(std::is_base_of<LocalID_t, GEOID>{}, "template type GEOID is not a LocalID_t");
166 
168 
171  using difference_type = std::ptrdiff_t;
173  using reference = value_type const&;
174  using pointer = value_type const*;
175  using iterator_category = std::forward_iterator_tag;
177 
179  id_iterator_base() = default;
180 
182  id_iterator_base(GeometryCore const* geo, GeoID_t const& start_from)
183  : upper_iterator{geo, start_from}, geom{geo}, limit(NSiblings(geom, localID()))
184  {}
185 
187  bool operator==(id_iterator_base const& as) const { return localID() == as.localID(); }
188 
190  bool operator!=(id_iterator_base const& as) const { return !operator==(as); }
191 
193  reference operator*() const { return localID(); }
194 
196  pointer operator->() const { return &(localID()); }
197 
200  {
201  next();
202  return *this;
203  }
204 
207  {
208  iterator old(*this);
209  next();
210  return old;
211  }
212 
213  protected:
215  LocalID_t const& localID() const { return upper_iterator::ID(); }
216 
217  using ID_t = std::remove_reference_t<
218  decltype(std::declval<LocalID_t>().deepestIndex())>;
219 
221  void next()
222  {
223  // if at end (checked in the inherited context), do nothing
224  if (upper_iterator::at_end()) return;
225 
226  // if after incrementing we haven't reached the limit, we are done
227  if (++local_index() < limit) return;
228 
229  // we reached the end of the current elements list, we need to escalate:
230  // - go to the next parent; if that becomes invalid, too bad, but we go on
231  upper_iterator::next();
232  // - set the index to the first element of the new parent
233  local_index() = 0;
234  // - update how many elements there are
235  // (expect 0 if it is now at_end() -- and it does not even matter)
236  limit = NSiblings(geom, localID());
237  }
238 
240  ID_t const& local_index() const { return localID().deepestIndex(); }
241 
242  private:
245  ID_t limit = LocalID_t::InvalidID;
246 
248  LocalID_t& localID() { return upper_iterator::ID(); }
249 
251  ID_t& local_index() { return localID().deepestIndex(); }
252  }; // class id_iterator_base
253 
254  template <typename LocalID>
256 
258  template <typename GEOIT>
259  std::enable_if_t<std::is_base_of_v<geometry_iterator_base, GEOIT>, std::ostream&> operator<<(
260  std::ostream& out,
261  GEOIT const& it)
262  {
263  return out << "geometry_iterator{ " << *it << " }";
264  }
265 
282  template <typename Element, typename GEOIDITER>
284  public:
285  using id_iterator_t = GEOIDITER;
286 
287  static_assert(std::is_base_of<geometry_iterator_base, id_iterator_t>{},
288  "template class for geometry_element_iterator"
289  " must be a geometry iterator");
290 
292 
295  using LocalID_t = typename id_iterator_t::LocalID_t;
296  using GeoID_t = typename id_iterator_t::GeoID_t;
297  using ElementPtr_t = Element const*;
299 
302  using difference_type = std::ptrdiff_t;
303  using value_type = Element;
304  using reference = value_type const&;
305  using pointer = value_type const*;
306  using iterator_category = std::forward_iterator_tag;
308 
310  geometry_element_iterator() = default;
311 
314  : geom{geo}, id_iterator(iter)
315  {}
316 
319  : geom{geo}, id_iterator(iter)
320  {}
321 
324  : geom{geo}, id_iterator(geom, start_from)
325  {}
326 
328  bool operator==(iterator const& as) const { return id_iterator == as.id_iterator; }
329 
331  bool operator!=(iterator const& as) const { return id_iterator != as.id_iterator; }
332 
340  {
341  ElementPtr_t ptr = get();
342  if (ptr) return *ptr;
343  throw cet::exception("geometry_iterator")
344  << "iterator attempted to obtain geometry element " << std::string(ID());
345  } // operator*()
346 
348  pointer operator->() const { return get(); }
349 
352  {
353  ++id_iterator;
354  return *this;
355  }
356 
359  {
360  iterator old(*this);
361  ++id_iterator;
362  return old;
363  }
364 
366  operator bool() const { return validElement(geom, *id_iterator); }
367 
369  ElementPtr_t get() const { return getElementPtr(geom, *id_iterator); }
370 
372  LocalID_t const& ID() const { return *id_iterator; }
373 
374  private:
377  }; // class geometry_element_iterator<>
378 
379  // Element here supports types like CryostatGeo, etc.
380  template <typename Element>
381  using element_iterator_for =
383 
384 } // namespace geo::details
385 
386 #endif // LARCOREALG_GEOMETRY_DETAILS_GEOMETRY_ITERATORS_H
IDparameter< geo::CryostatID > CryostatID
Member type of validated geo::CryostatID parameter.
LocalID LocalID_t
type of the ID we change
geometry_element_iterator(GeometryCore const *geo, GeoID_t const &start_from)
Constructor: points to the specified geometry element.
bool operator!=(iterator const &as) const
Returns true if the two iterators point to different objects.
iterator operator++(int)
Postfix increment: returns the current iterator, then increments it.
geometry_iterator_base()=default
Default constructor; do not use a default-constructed iterator as-is!
bool validElement(GeometryCore const *geom, CryostatID const &id)
Definition: helpers.cxx:60
CryostatGeo const * getElementPtr(GeometryCore const *geom, CryostatID const &id)
Definition: helpers.cxx:36
Classes identifying readout-related concepts.
Base forward iterator browsing all cryostat IDs in the detector.
bool operator!=(id_iterator_base const &as) const
id_iterator_base< LocalID, LocalID > id_iterator
typename id_iterator_t::LocalID_t LocalID_t
ID_t const & local_index() const
Returns the index (part if the ID) this iterator runs on.
constexpr bool operator==(CryostatID const &a, CryostatID const &b)
Comparison: the IDs point to the same cryostat (validity is ignored)
Definition: geo_types.h:680
geometry_element_iterator(GeometryCore const *geo, id_iterator_t &&iter)
Constructor: points to the same element as the specified ID iterator.
id_iterator_base(GeometryCore const *geom, GeoID_t const &start_from)
Constructor: points to the specified cryostat.
typename id_iterator_t::GeoID_t GeoID_t
unsigned int NSiblings(GeometryCore const *geom, CryostatID const &id)
Definition: helpers.cxx:6
pointer operator->() const
Returns the element ID the iterator points to.
LocalID_t const & localID() const
Returns the type of ID we act on.
pointer operator->() const
Returns a pointer to the ID the iterator points to.
GeometryCore const * geometry() const
Returns a pointer to the geometry.
std::enable_if_t< std::is_base_of_v< geometry_iterator_base, GEOIT >, std::ostream & > operator<<(std::ostream &out, GEOIT const &it)
Stream output for all geometry ID iterator types: prints the pointed ID.
typename upper_iterator::GeoID_t GeoID_t
iterator operator++(int)
Postfix increment: returns the current iterator, then increments it.
bool operator!=(id_iterator_base const &as) const
Returns true if the two iterators point to different elements.
bool operator==(iterator const &as) const
Returns true if the two iterators point to the same object.
pointer operator->() const
Returns a pointer to the element the iterator points to (or nullptr)
std::forward_iterator_tag iterator_category
Description of geometry of one entire detector.
Definition: GeometryCore.h:119
ID_t & local_index()
Returns the index (part if the ID) this iterator runs on (non-const)
Definition of data types for geometry description.
geometry_iterator_base(GeometryCore const *geom)
Constructor: associates with the specified geometry.
iterator operator++(int)
Postfix increment: returns the current iterator, then increments it.
reference operator*() const
Returns the ID the iterator points to.
void next()
Skips to the next element.
reference operator*() const
Returns the element ID the iterator points to.
std::remove_reference_t< decltype(std::declval< LocalID_t >().deepestIndex())> ID_t
specific type for element ID
unsigned int CryostatID_t
Type for the ID number.
Definition: geo_types.h:193
LocalID_t & localID()
Returns the type of ID we act on (non-const version)
bool operator==(id_iterator_base const &as) const
Returns true if the two iterators point to the same cryostat.
LocalID_t & localID()
Returns the type of ID we act on.
GeometryCore const * pGeo
pointer to the geometry
iterator & operator++()
Prefix increment: returns this iterator pointing to the next element.
GEOID GeoID_t
type of the actual ID stored in the iterator
geo::GeometryCore const * geom
Base class for geometry iterators (note: this is not an iterator)
id_iterator_base(GeometryCore const *geo, GeoID_t const &start_from)
Constructor: points to the specified element.
iterator & operator++()
Prefix increment: returns this iterator pointing to the next element.
iterator & operator++()
Prefix increment: returns this iterator pointing to the next cryostat.
ID_t & local_index()
Returns the index (part if the ID) this iterator runs on.
std::forward_iterator_tag iterator_category
geometry_element_iterator(GeometryCore const *geo, id_iterator_t const &iter)
Constructor: points to the same element as the specified ID iterator.
Forward iterator browsing all geometry elements in the detector.
bool at_end() const
Returns whether this iterator has reached the end.
bool operator==(id_iterator_base const &as) const
Returns true if the two iterators point to the same element.
Namespace collecting geometry-related classes utilities.
GeoID_t & ID()
Returns the actual type of ID we store.
reference operator*() const
Returns the geometry element the iterator points to.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
The data type to uniquely identify a cryostat.
Definition: geo_types.h:192
LocalID_t const & ID() const
Returns the ID of the pointed geometry element.