36#ifndef VIGRA_COUNTING_ITERATOR_HXX
37#define VIGRA_COUNTING_ITERATOR_HXX
45#include "tinyvector.hxx"
51template <
class T,
bool is_
float=false>
52struct 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);
95 ? (std::ptrdiff_t)std::ceil(diff)
96 : (std::ptrdiff_t)std::
floor(diff);
101struct 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()));
242template<
class T = std::ptrdiff_t>
243class CountingIterator
246 typedef std::random_access_iterator_tag iterator_category;
247 typedef T value_type;
248 typedef std::ptrdiff_t difference_type;
249 typedef T
const* pointer;
258 CountingIterator(T begin, T end)
263 vigra_precondition(begin <= end,
264 "CountingIterator(): begin must be less or equal to end.");
267 CountingIterator(T begin, T end, T step)
272 vigra_precondition(step != 0,
273 "CountingIterator(): step must be non-zero.");
274 vigra_precondition((step > 0 && begin <= end) || (step < 0 && begin >= end),
275 "CountingIterator(): sign mismatch between step and (end-begin).");
278 CountingIterator(CountingIterator
const & other, ReverseCopyTag)
281 , step_(-other.step_)
286 CountingIterator begin()
const
291 CountingIterator end()
const
295 T end = begin_ + step_*Compare::distance(begin_, end_, step_);
296 return CountingIterator(end, end, step_);
301 return Compare::greater_equal(begin_, end_, step_);
304 CountingIterator& operator++() {begin_ += step_;
return *
this;}
305 CountingIterator operator++(
int) {CountingIterator tmp(*
this); ++(*this);
return tmp;}
306 CountingIterator& operator--() {begin_ -= step_;
return *
this;}
307 CountingIterator operator--(
int) {CountingIterator tmp(*
this); --(*this);
return tmp;}
309 CountingIterator& operator+=(std::ptrdiff_t n)
315 CountingIterator operator+(std::ptrdiff_t n)
const
317 return CountingIterator(*
this) += n;
320 CountingIterator& operator-=(std::ptrdiff_t n)
326 CountingIterator operator-(std::ptrdiff_t n)
const
328 return CountingIterator(*
this) -= n;
331 std::ptrdiff_t operator-(
const CountingIterator& other)
const
333 return Compare::distance(other.begin_, begin_, step_);
336 bool operator<(CountingIterator
const & other)
const
338 return Compare::less(begin_, other.begin_, step_);
341 bool operator<=(CountingIterator
const & other)
const
343 return Compare::less_equal(begin_, other.begin_, step_);
346 bool operator>(CountingIterator
const & other)
const
348 return Compare::greater(begin_, other.begin_, step_);
351 bool operator>=(CountingIterator
const & other)
const
353 return Compare::greater_equal(begin_, other.begin_, step_);
356 bool operator==(
const CountingIterator& other)
const
358 return Compare::equal(begin_, other.begin_, step_);
361 bool operator!=(
const CountingIterator& other)
const
363 return Compare::not_equal(begin_, other.begin_, step_);
366 T operator[](std::ptrdiff_t n)
const {
367 return begin_ + n*step_;
370 T operator*()
const {
374 T
const * operator->()
const{
380 typedef detail::CountingIteratorCompare<T, std::is_floating_point<T>::value> Compare;
382 T begin_, end_, step_;
386template <
class T1,
class T2,
class T3>
388range(T1 begin, T2 end, T3 step)
393template <
class T1,
class T2>
394inline CountingIterator<T1>
395range(T1 begin, T2 end)
397 return CountingIterator<T1>(begin, end, 1);
412struct std::iterator_traits<typename
vigra::CountingIterator<T>>
414 typedef typename vigra::CountingIterator<T>::iterator_category iterator_category;
415 typedef typename vigra::CountingIterator<T>::value_type value_type;
416 typedef typename vigra::CountingIterator<T>::difference_type difference_type;
417 typedef typename vigra::CountingIterator<T>::pointer pointer;
418 typedef typename vigra::CountingIterator<T>::reference reference;
Iterator that counts upwards or downwards with a given step size.
Definition counting_iterator.hxx:244
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition fixedpoint.hxx:667