LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
counter.h
Go to the documentation of this file.
1 
10 #ifndef LARCOREALG_COREUTILS_COUNTER_H
11 #define LARCOREALG_COREUTILS_COUNTER_H
12 
13 // External libraries
14 #include "range/v3/view.hpp"
15 
16 // C/C++ libraries
17 #include <cstddef> // std::size_t
18 #include <utility> // std::move()
19 
20 namespace util {
21 
22  // -- BEGIN -- Counted iterations --------------------------------------------
25 
51  template <typename T = std::size_t>
53  public:
54  // --- BEGIN -- Traits and data types --------------------------------------
57 
59 
60  using difference_type = std::ptrdiff_t;
61  using value_type = T;
62  using reference = T const&;
63  using pointer = T*;
64  using iterator_category = std::bidirectional_iterator_tag;
65 
67  // --- END -- Traits and data types ----------------------------------------
68 
69  // --- BEGIN Constructors --------------------------------------------------
72 
79  count_iterator() = default;
80 
85  count_iterator(value_type count) : fCount(count) {}
86 
88  // --- END Constructors ----------------------------------------------------
89 
90  // --- BEGIN -- Data access ------------------------------------------------
93 
95  reference operator*() const { return fCount; }
96 
98  // --- END -- Data access --------------------------------------------------
99 
100  // --- BEGIN -- Modification -----------------------------------------------
103 
106  {
107  ++fCount;
108  return *this;
109  }
110 
114  {
115  iterator_type const old = *this;
116  operator++();
117  return old;
118  }
119 
122  {
123  --fCount;
124  return *this;
125  }
126 
130  {
131  iterator_type const old = *this;
132  operator--();
133  return old;
134  }
135 
137  // --- END -- Modification -------------------------------------------------
138 
139  // --- BEGIN -- Comparisons ------------------------------------------------
142 
144  template <typename U>
145  bool operator==(count_iterator<U> const& other) const
146  {
147  return fCount == other.fCount;
148  }
149 
151  template <typename U>
152  bool operator!=(count_iterator<U> const& other) const
153  {
154  return fCount != other.fCount;
155  }
156 
158  // --- END -- Comparisons --------------------------------------------------
159 
160  private:
162 
163  }; // class count_iterator<>
164 
187  template <typename T>
188  auto counter(T begin, T end);
189 
192  template <typename T>
193  auto counter(T end)
194  {
195  return counter(T{}, end);
196  }
197 
217  template <typename T = std::size_t>
218  auto infinite_counter(T begin = T{});
219 
221  // -- END -- Counted iterations ----------------------------------------------
222 
223 } // namespace util
224 
225 //==============================================================================
226 //=== template implementation
227 //==============================================================================
228 //------------------------------------------------------------------------------
229 //--- util::counter()
230 //------------------------------------------------------------------------------
231 namespace util::details {
232 
242  template <typename T>
246 
247  public:
248  // mock-up of stuff required by `ranges::subrange`
249  using value_type = T;
250  using reference = T const&;
251  using pointer = T const*;
252  using difference_type = std::ptrdiff_t;
253  using iterator_category = std::forward_iterator_tag; // this is a lie
254 
256  bool operator==(this_iterator_t const&) const { return true; }
257 
259  bool operator!=(this_iterator_t const&) const { return false; }
260 
261  }; // class infinite_endcount_iterator
262 
264  template <typename T>
266  {
267  return true;
268  }
269 
270  template <typename T>
272  {
273  return true;
274  }
275 
276  template <typename T>
278  {
279  return false;
280  }
281 
282  template <typename T>
284  {
285  return false;
286  }
287 
288 } // namespace util::details
289 
290 //------------------------------------------------------------------------------
291 template <typename T>
293 {
294  return ranges::make_subrange(count_iterator(begin), count_iterator(end));
295 }
296 
297 //------------------------------------------------------------------------------
298 template <typename T>
300 {
301  return ranges::make_subrange(count_iterator(begin), details::infinite_endcount_iterator<T>());
302 }
303 
304 //------------------------------------------------------------------------------
305 
306 #endif // LARCOREALG_COREUTILS_COUNTER_H
T value_type
Type of index returned by this iterator.
Definition: counter.h:61
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:26
An iterator dereferencing to a counter value.
Definition: counter.h:52
auto infinite_counter(T begin=T{})
Version of util::counter() starting at begin and never ending.
Definition: counter.h:299
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
std::ptrdiff_t difference_type
Type of this iterator.
Definition: counter.h:60
iterator_type operator--(int) const
Definition: counter.h:129
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:292
Class used as end iterator (sentinel) for an infinite loop.
Definition: counter.h:243
T const & reference
Type returned by dereference operator.
Definition: counter.h:62
bool operator!=(this_iterator_t const &) const
Never admit this iterator is equal to anything else (except the same).
Definition: counter.h:259
bool operator==(this_iterator_t const &) const
Never admit this iterator is equal to anything else (except the same).
Definition: counter.h:256
count_iterator(value_type count)
Initializes the iterator with the specified loop count.
Definition: counter.h:85
reference operator*() const
Returns the current loop count.
Definition: counter.h:95
T * pointer
Type of this iterator.
Definition: counter.h:63
value_type fCount
Internal counter.
Definition: counter.h:161
iterator_type & operator++()
Increments the loop count of this iterator, which is then returned.
Definition: counter.h:105
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
iterator_type & operator--()
Decrements the loop count of this iterator, which is then returned.
Definition: counter.h:121
std::forward_iterator_tag iterator_category
Definition: counter.h:253
bool operator!=(count_iterator< U > const &other) const
Iterators are equal if their loop counts compare different.
Definition: counter.h:152
count_iterator()=default
Initializes the iterator.
iterator_type operator++(int) const
Definition: counter.h:113
bool operator==(count_iterator< U > const &other) const
Iterators are equal if their loop counts compare equal.
Definition: counter.h:145
std::bidirectional_iterator_tag iterator_category
Type of this iterator.
Definition: counter.h:64