LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
AssnsIter.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Common_AssnsIter_h
2 #define canvas_Persistency_Common_AssnsIter_h
3 
4 /* Assns Iterator for art::Assns<L, R, D> */
7 
8 #include <iostream>
9 #include <iterator>
10 
11 namespace art {
12  // for dereference return type
13  template <class L, class R, class D>
14  struct AssnsNode {
17  D const* data{nullptr};
18  AssnsNode() = default;
19  AssnsNode(art::Ptr<L> const& l, art::Ptr<R> const& r, D const& d)
20  : first{l}, second{r}, data{&d}
21  {}
22  };
23 
24  enum class Direction : int { Forward = 1, Reverse = -1 };
25 
26  template <Direction Dir>
27  constexpr int
29  {
30  return static_cast<std::underlying_type_t<Direction>>(Dir);
31  }
32 
34  // Const Iterator
35  template <class L, class R, class D, Direction Dir = Direction::Forward>
37  public:
38  using iterator_category = std::random_access_iterator_tag;
40  using pointer = value_type const*;
41  using reference = value_type const&;
42  using difference_type = std::ptrdiff_t;
43 
44  const_AssnsIter() = default;
45  explicit const_AssnsIter(art::Assns<L, R, D> const& assns)
46  : coll_{&assns}, index_{assns.size()}
47  {}
48  explicit const_AssnsIter(art::Assns<L, R, D> const& assns,
49  std::size_t const i)
50  : coll_{&assns}, index_{i}
51  {}
54 
55  reference operator*() const;
56  pointer operator->() const;
57  const_AssnsIter<L, R, D, Dir>& operator++();
58  const_AssnsIter<L, R, D, Dir> operator++(int);
59  const_AssnsIter<L, R, D, Dir>& operator--();
60  const_AssnsIter<L, R, D, Dir> operator--(int);
61  bool operator==(art::const_AssnsIter<L, R, D, Dir> const& iter) const;
62  bool operator!=(art::const_AssnsIter<L, R, D, Dir> const& iter) const;
64  const_AssnsIter<L, R, D, Dir> operator+(std::size_t i) const;
65  const_AssnsIter<L, R, D, Dir>& operator-=(std::size_t i);
66  const_AssnsIter<L, R, D, Dir> operator-(std::size_t i) const;
67  std::size_t operator-(
68  art::const_AssnsIter<L, R, D, Dir> const& iter1) const;
69  value_type operator[](std::size_t i) const;
70 
71  bool operator<(art::const_AssnsIter<L, R, D, Dir> const& iter) const;
72  bool operator<=(art::const_AssnsIter<L, R, D, Dir> const& iter) const;
73  bool operator>(art::const_AssnsIter<L, R, D, Dir> const& iter) const;
74  bool operator>=(art::const_AssnsIter<L, R, D, Dir> const& iter) const;
75 
76  std::size_t
77  getIndex() const
78  {
79  return index_;
80  };
81 
82  private:
83  art::Assns<L, R, D> const* coll_{nullptr};
84  std::size_t index_{-1ull};
85  mutable AssnsNode<L, R, D> node_{};
86  };
87 
88  // For reverse iterators, we do not shift the underlying index into
89  // the collection since this wreaks havoc with the comparison
90  // operators. The shifting happens during dereferencing. Note that
91  // an attempt to dereference rend() will result in an out-of-range
92  // error.
93  template <Direction Dir>
94  constexpr auto
95  index_for_dereferencing(std::size_t const i)
96  {
97  return (Dir == Direction::Forward) ? i : i - 1;
98  }
99 
100  // Utilities for determining the left and right operands of iterator
101  // comparisons based on the direction of the iterator.
102  template <class L, class R, class D, Direction Dir>
103  constexpr auto const&
106  {
107  return (Dir == Direction::Forward) ? a : b;
108  }
109 
110  template <class L, class R, class D, Direction Dir>
111  constexpr auto const&
114  {
115  return (Dir == Direction::Forward) ? b : a;
116  }
117 
118  // Dereference
119  template <class L, class R, class D, Direction Dir>
122  {
123  auto const index = index_for_dereferencing<Dir>(index_);
124  node_.first = (*coll_)[index].first;
125  node_.second = (*coll_)[index].second;
126  node_.data = &(coll_->data(index));
127  return node_;
128  }
129 
130  // right arrow
131  template <class L, class R, class D, Direction Dir>
134  {
135  auto const index = index_for_dereferencing<Dir>(index_);
136  node_.first = (*coll_)[index].first;
137  node_.second = (*coll_)[index].second;
138  node_.data = &(coll_->data(index));
139  return &node_;
140  }
141 
142  // Pre-increment
143  template <class L, class R, class D, Direction Dir>
146  {
147  index_ = index_ + signed_one<Dir>();
148  return *this;
149  }
150 
151  // Post-increment
152  template <class L, class R, class D, Direction Dir>
154  int)
155  {
157  index_ = index_ + signed_one<Dir>();
158  return tmp;
159  }
160 
161  // Pre-decrement
162  template <class L, class R, class D, Direction Dir>
165  {
166  index_ = index_ - signed_one<Dir>();
167  return *this;
168  }
169  // post-decrement
170  template <class L, class R, class D, Direction Dir>
172  int)
173  {
175  index_ = index_ - signed_one<Dir>();
176  return tmp;
177  }
178 
179  // equality
180  template <class L, class R, class D, Direction Dir>
181  bool
183  art::const_AssnsIter<L, R, D, Dir> const& iter) const
184  {
185  return index_ == iter.index_;
186  }
187 
188  // in-equality
189  template <class L, class R, class D, Direction Dir>
190  bool
192  art::const_AssnsIter<L, R, D, Dir> const& iter) const
193  {
194  return !(index_ == iter.index_);
195  }
196 
197  // increment by a given value ...
198  template <class L, class R, class D, Direction Dir>
201  {
202  // to do add check for index bounds and make sure it works for both positive
203  // and negative values
204  index_ = index_ + signed_one<Dir>() * i;
205  return *this;
206  }
207 
208  // random access
209  template <class L, class R, class D, Direction Dir>
211  const_AssnsIter<L, R, D, Dir>::operator+(std::size_t const i) const
212  {
214  tmp.index_ = tmp.index_ + signed_one<Dir>() * i;
215  return tmp;
216  }
217 
218  // decrement by a given value ...
219  template <class L, class R, class D, Direction Dir>
222  {
223  // to do add check for index bounds and make sure it works for both positive
224  // and negative values
225  index_ = index_ - signed_one<Dir>() * i;
226  return *this;
227  }
228 
229  // random access
230  template <class L, class R, class D, Direction Dir>
232  const_AssnsIter<L, R, D, Dir>::operator-(std::size_t const i) const
233  {
235  tmp.index_ = tmp.index_ - signed_one<Dir>() * i;
236  return tmp;
237  }
238 
239  // difference between two iterators to return an index
240  template <class L, class R, class D, Direction Dir>
241  std::size_t
243  art::const_AssnsIter<L, R, D, Dir> const& iter1) const
244  {
245  return (iter1.index_ - index_);
246  }
247 
248  // Dereference
249  template <class L, class R, class D, Direction Dir>
251  const_AssnsIter<L, R, D, Dir>::operator[](std::size_t const i) const
252  {
254  tmp.index_ = tmp.index_ + signed_one<Dir>() * i;
255  return tmp.node_;
256  }
257 
258  // less than
259  template <class L, class R, class D, Direction Dir>
260  bool
262  art::const_AssnsIter<L, R, D, Dir> const& iter) const
263  {
264  auto const& l = left(*this, iter);
265  auto const& r = right(*this, iter);
266  return l.index_ < r.index_;
267  }
268 
269  // less than equal to
270  template <class L, class R, class D, Direction Dir>
271  bool
273  art::const_AssnsIter<L, R, D, Dir> const& iter) const
274  {
275  auto const& l = left(*this, iter);
276  auto const& r = right(*this, iter);
277  return l.index_ <= r.index_;
278  }
279 
280  // less than equal to
281  template <class L, class R, class D, Direction Dir>
282  bool
284  art::const_AssnsIter<L, R, D, Dir> const& iter) const
285  {
286  auto const& l = left(*this, iter);
287  auto const& r = right(*this, iter);
288  return l.index_ > r.index_;
289  }
290 
291  // greater than equal to
292  template <class L, class R, class D, Direction Dir>
293  bool
295  art::const_AssnsIter<L, R, D, Dir> const& iter) const
296  {
297  auto const& l = left(*this, iter);
298  auto const& r = right(*this, iter);
299  return l.index_ >= r.index_;
300  }
301 
302  template <class L, class R, class D, Direction Dir>
306  {
307  node_ = iter.node_;
308  return *this;
309  }
310 }
311 
312 #endif /* canvas_Persistency_Common_AssnsIter_h */
313 
314 // Local Variables:
315 // mode: c++
316 // End:
reference operator*() const
Definition: AssnsIter.h:121
size_type size() const
Definition: Assns.h:440
const_AssnsIter< L, R, D, Dir > & operator+=(std::size_t i)
Definition: AssnsIter.h:200
D const * data
Definition: AssnsIter.h:17
value_type const & reference
Definition: AssnsIter.h:41
pointer operator->() const
Definition: AssnsIter.h:133
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:112
std::size_t getIndex() const
Definition: AssnsIter.h:77
bool operator>=(art::const_AssnsIter< L, R, D, Dir > const &iter) const
Definition: AssnsIter.h:294
std::random_access_iterator_tag iterator_category
Definition: AssnsIter.h:38
bool operator>(art::const_AssnsIter< L, R, D, Dir > const &iter) const
Definition: AssnsIter.h:283
bool operator>=(ScheduleID left, ScheduleID right)
Definition: ScheduleID.h:142
value_type const * pointer
Definition: AssnsIter.h:40
const_AssnsIter(art::Assns< L, R, D > const &assns)
Definition: AssnsIter.h:45
bool operator<(art::const_AssnsIter< L, R, D, Dir > const &iter) const
Definition: AssnsIter.h:261
AssnsNode(art::Ptr< L > const &l, art::Ptr< R > const &r, D const &d)
Definition: AssnsIter.h:19
Float_t tmp
Definition: plot.C:37
bool operator!=(debugging_allocator< X > const &, debugging_allocator< Y > const &)
const_AssnsIter(art::Assns< L, R, D > const &assns, std::size_t const i)
Definition: AssnsIter.h:48
bool operator>(ScheduleID left, ScheduleID right)
Definition: ScheduleID.h:136
const_AssnsIter< L, R, D, Dir > & operator--()
Definition: AssnsIter.h:164
bool operator<=(art::const_AssnsIter< L, R, D, Dir > const &iter) const
Definition: AssnsIter.h:272
art::Ptr< R > second
Definition: AssnsIter.h:16
QuadExpr operator-(double v, const QuadExpr &e)
Definition: QuadExpr.h:38
const_AssnsIter< L, R, D, Dir > operator+(std::size_t i) const
Definition: AssnsIter.h:211
Float_t d
Definition: plot.C:237
String & operator+=(String &s, VectorDumper< Vector > const &manip)
Appends a string rendering of a vector to the specified string.
Definition: DumpUtils.h:424
const_AssnsIter< L, R, D, Dir > & operator++()
Definition: AssnsIter.h:145
art::Ptr< L > first
Definition: AssnsIter.h:15
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:104
constexpr int signed_one()
Definition: AssnsIter.h:28
QuadExpr operator+(double v, const QuadExpr &e)
Definition: QuadExpr.h:37
std::size_t index_
Definition: AssnsIter.h:84
constexpr auto index_for_dereferencing(std::size_t const i)
Definition: AssnsIter.h:95
value_type operator[](std::size_t i) const
Definition: AssnsIter.h:251
std::ptrdiff_t difference_type
Definition: AssnsIter.h:42
bool operator==(art::const_AssnsIter< L, R, D, Dir > const &iter) const
Definition: AssnsIter.h:182
AssnsNode()=default
const_AssnsIter< L, R, D, Dir > operator-(std::size_t i) const
Definition: AssnsIter.h:232
HLT enums.
Direction
Definition: AssnsIter.h:24
AssnsNode< L, R, D > node_
Definition: AssnsIter.h:85
const_AssnsIter< L, R, D, Dir > & operator-=(std::size_t i)
Definition: AssnsIter.h:221
bool operator==(Provenance const &a, Provenance const &b)
Definition: Provenance.h:168
const_AssnsIter< L, R, D, Dir > & operator=(art::const_AssnsIter< L, R, D, Dir > const &iter)
Definition: AssnsIter.h:304
QuadExpr operator*(double v, const QuadExpr &e)
Definition: QuadExpr.h:39
bool operator!=(art::const_AssnsIter< L, R, D, Dir > const &iter) const
Definition: AssnsIter.h:191