36 #ifndef VIGRA_COUNTING_ITERATOR_HXX
37 #define VIGRA_COUNTING_ITERATOR_HXX
43 #include <type_traits>
45 #include "tinyvector.hxx"
51 template <
class T,
bool is_
float=false>
52 struct CountingIteratorCompare
55 static bool equal(T left, T right, T )
59 static bool not_equal(T left, T right, T )
63 static bool less(T left, T right, T step)
71 static bool less_equal(T left, T right, T step)
77 static bool greater(T left, T right, T step)
83 static bool greater_equal(T left, T right, T step)
91 static std::ptrdiff_t distance(T from, T to, T step)
93 const double diff = (double(to) - double(from)) /
double(step);
101 struct CountingIteratorCompare<T, true>
103 typedef std::numeric_limits<T> limit;
107 static bool equal(T left, T right, T step)
109 return std::fabs(right-left) <= 0.5*std::fabs(step);
111 static bool not_equal(T left, T right, T step)
113 return std::fabs(right-left) > 0.5*std::fabs(step);
115 static bool less(T left, T right, T step)
118 ? right - left > 0.5*step
119 : right - left < 0.5*step;
121 static bool less_equal(T left, T right, T step)
124 ? left - right < 0.5*step
125 : left - right > 0.5*step;
127 static bool greater(T left, T right, T step)
130 ? left - right > 0.5*step
131 : left - right < 0.5*step;
133 static bool greater_equal(T left, T right, T step)
136 ? right - left < 0.5*step
137 : right - left > 0.5*step;
141 static std::ptrdiff_t distance(T from, T to, T step)
143 const double diff = (double(to) - double(from)) /
double(step);
145 ? (std::ptrdiff_t)
std::ceil(diff*(1.0-2.0*limit::epsilon()))
146 : (std::ptrdiff_t)
std::floor(diff*(1.0-2.0*limit::epsilon()));
242 template<
class T = std::ptrdiff_t>
244 :
public std::iterator<std::random_access_iterator_tag,
245 T, std::ptrdiff_t, T const *, T>
259 vigra_precondition(begin <= end,
260 "CountingIterator(): begin must be less or equal to end.");
268 vigra_precondition(step != 0,
269 "CountingIterator(): step must be non-zero.");
270 vigra_precondition((step > 0 && begin <= end) || (step < 0 && begin >= end),
271 "CountingIterator(): sign mismatch between step and (end-begin).");
277 , step_(-other.step_)
291 T end = begin_ + step_*Compare::distance(begin_, end_, step_);
297 return Compare::greater_equal(begin_, end_, step_);
329 return Compare::distance(other.begin_, begin_, step_);
334 return Compare::less(begin_, other.begin_, step_);
339 return Compare::less_equal(begin_, other.begin_, step_);
344 return Compare::greater(begin_, other.begin_, step_);
349 return Compare::greater_equal(begin_, other.begin_, step_);
354 return Compare::equal(begin_, other.begin_, step_);
359 return Compare::not_equal(begin_, other.begin_, step_);
362 T operator[](std::ptrdiff_t n)
const {
363 return begin_ + n*step_;
366 T operator*()
const {
370 T
const * operator->()
const{
376 typedef detail::CountingIteratorCompare<T, std::is_floating_point<T>::value> Compare;
378 T begin_, end_, step_;
382 template <
class T1,
class T2,
class T3>
384 range(T1 begin, T2 end, T3 step)
389 template <
class T1,
class T2>
390 inline CountingIterator<T1>
391 range(T1 begin, T2 end)
393 return CountingIterator<T1>(begin, end, 1);
397 inline CountingIterator<T>
400 return CountingIterator<T>(0, end, 1);
Iterator that counts upwards or downwards with a given step size.
Definition: counting_iterator.hxx:243
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up.
Definition: fixedpoint.hxx:675
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition: fixedpoint.hxx:667