36 #ifndef MULTI_ITERATOR_COUPLED_HXX
37 #define MULTI_ITERATOR_COUPLED_HXX
39 #include "multi_fwd.hxx"
40 #include "multi_shape.hxx"
41 #include "multi_handle.hxx"
42 #include "metaprogramming.hxx"
56 template <
class Iterator>
57 class CoupledDimensionProxy
61 typedef typename Iterator::value_type value_type;
62 typedef typename Iterator::difference_type difference_type;
63 typedef typename Iterator::reference reference;
64 typedef typename Iterator::const_reference const_reference;
65 typedef typename Iterator::pointer pointer;
66 typedef CoupledDimensionProxy iterator;
67 typedef std::random_access_iterator_tag iterator_category;
69 static const int dimension = Iterator::dimension;
71 CoupledDimensionProxy & operator++()
73 this->incDim(dimension);
77 CoupledDimensionProxy operator++(
int)
79 CoupledDimensionProxy ret(*
this);
80 this->incDim(dimension);
84 CoupledDimensionProxy & operator--()
86 this->decDim(dimension);
90 CoupledDimensionProxy operator--(
int)
92 CoupledDimensionProxy ret(*
this);
93 this->decDim(dimension);
99 this->addDim(dimension, d);
105 this->addDim(dimension, -d);
111 return *(CoupledDimensionProxy(*
this) += d);
116 this->setDim(dimension, d);
122 return this->point(dimension) == d;
127 return this->point(dimension) != d;
132 return this->point(dimension) < d;
137 return this->point(dimension) <= d;
142 return this->point(dimension) > d;
147 return this->point(dimension) >= d;
189 template <
unsigned int N,
192 class CoupledScanOrderIterator
194 :
public CoupledScanOrderIterator<N, HANDLES, DIMENSION-1>
197 typedef CoupledScanOrderIterator<N, HANDLES, DIMENSION-1> base_type;
200 static const int dimension = DIMENSION;
203 typedef CoupledScanOrderIterator iterator;
204 typedef std::random_access_iterator_tag iterator_category;
206 typedef typename base_type::value_type value_type;
214 typedef typename base_type::shape_type shape_type;
215 typedef typename base_type::reference reference;
216 typedef typename base_type::const_reference const_reference;
217 typedef typename base_type::pointer pointer;
218 typedef CoupledDimensionProxy<iterator> dimension_proxy;
226 base_type::operator++();
227 if(this->point()[dimension-1] == this->shape()[dimension-1])
234 CoupledScanOrderIterator operator++(
int)
236 CoupledScanOrderIterator res(*
this);
243 base_type::operator+=(i);
247 CoupledScanOrderIterator & operator+=(
const shape_type &coordOffset)
249 base_type::operator+=(coordOffset);
253 CoupledScanOrderIterator & operator--()
255 base_type::operator--();
256 if(this->point()[dimension-1] == -1)
263 CoupledScanOrderIterator operator--(
int)
265 CoupledScanOrderIterator res(*
this);
272 return operator+=(-i);
275 CoupledScanOrderIterator & operator-=(
const shape_type &coordOffset)
277 return operator+=(-coordOffset);
284 return operator+(
prod(this->shape()) - this->scanOrderIndex());
294 return CoupledScanOrderIterator(*
this) -= d;
297 CoupledScanOrderIterator operator+(
const shape_type &coordOffset)
const
299 return CoupledScanOrderIterator(*
this) += coordOffset;
302 CoupledScanOrderIterator operator-(
const shape_type &coordOffset)
const
304 return CoupledScanOrderIterator(*
this) -= coordOffset;
309 return base_type::operator-(r);
312 CoupledScanOrderIterator &
313 restrictToSubarray(shape_type
const & start, shape_type
const & end)
315 base_type::restrictToSubarray(start, end);
323 template<
unsigned int TARGET_INDEX>
324 typename CoupledHandleCast<TARGET_INDEX, value_type>::type::reference
329 template<
unsigned int TARGET_INDEX>
330 typename CoupledHandleCast<TARGET_INDEX, value_type>::type::const_reference
338 void resetAndIncrement();
339 void resetAndDecrement();
343 this->handles_.template decrement<dimension>(this->shape()[dimension]);
348 this->handles_.template increment<dimension>(this->shape()[dimension]);
352 template <
unsigned int N,
class HANDLES,
int DIMENSION>
353 void CoupledScanOrderIterator<N, HANDLES, DIMENSION>::resetAndIncrement()
356 this->handles_.template increment<dimension>();
359 template <
unsigned int N,
class HANDLES,
int DIMENSION>
360 void CoupledScanOrderIterator<N, HANDLES, DIMENSION>::resetAndDecrement()
362 base_type::inverseReset();
363 this->handles_.template decrement<dimension>();
366 template <
unsigned int N,
class HANDLES>
367 class CoupledScanOrderIterator<N, HANDLES, 0>
371 static const int dimension = 0;
373 typedef CoupledScanOrderIterator<N, HANDLES, 0> self_type;
374 typedef HANDLES value_type;
376 typedef value_type & reference;
377 typedef value_type
const & const_reference;
378 typedef value_type * pointer;
379 typedef typename MultiArrayShape<N>::type shape_type;
380 typedef CoupledScanOrderIterator iterator;
381 typedef std::random_access_iterator_tag iterator_category;
382 typedef CoupledDimensionProxy<iterator> dimension_proxy;
384 template <
unsigned int TARGET_INDEX>
387 typedef typename CoupledHandleCast<TARGET_INDEX, HANDLES>::reference type;
390 template <
unsigned int TARGET_INDEX>
391 struct ConstReference
393 typedef typename CoupledHandleCast<TARGET_INDEX, HANDLES>::const_reference type;
396 explicit CoupledScanOrderIterator(value_type
const & handles = value_type())
398 strides_(detail::defaultStride(handles_.shape()))
401 template <
unsigned int DIM>
402 typename CoupledScanOrderIterator<N, HANDLES, DIM>::dimension_proxy &
405 typedef CoupledScanOrderIterator<N, HANDLES, DIM> Iter;
406 typedef typename Iter::dimension_proxy Proxy;
407 return static_cast<Proxy &
>(
static_cast<Iter &
>(*this));
410 template <
unsigned int DIM>
411 typename CoupledScanOrderIterator<N, HANDLES, DIM>::dimension_proxy
const &
414 typedef CoupledScanOrderIterator<N, HANDLES, DIM> Iter;
415 typedef typename Iter::dimension_proxy Proxy;
416 return static_cast<Proxy
const &
>(
static_cast<Iter
const &
>(*this));
421 handles_.incDim(dim);
422 handles_.incrementIndex(strides_[dim]);
427 handles_.decDim(dim);
428 handles_.decrementIndex(strides_[dim]);
433 handles_.addDim(dim, d);
434 handles_.incrementIndex(d*strides_[dim]);
440 handles_.addDim(dim, d);
441 handles_.incrementIndex(d*strides_[dim]);
444 void resetDim(
int dim)
447 handles_.addDim(dim, d);
448 handles_.incrementIndex(d*strides_[dim]);
451 CoupledScanOrderIterator & operator++()
453 handles_.template increment<dimension>();
454 handles_.incrementIndex();
458 CoupledScanOrderIterator operator++(
int)
460 CoupledScanOrderIterator res(*
this);
468 shape_type coordOffset;
469 detail::ScanOrderToCoordinate<N>::exec(i+scanOrderIndex(), shape(), coordOffset);
470 coordOffset -= point();
471 handles_.add(coordOffset);
472 handles_.scanOrderIndex_ += i;
476 CoupledScanOrderIterator & operator+=(
const shape_type &coordOffset)
478 handles_.add(coordOffset);
479 handles_.scanOrderIndex_ += detail::CoordinateToScanOrder<N>::exec(shape(), coordOffset);
483 CoupledScanOrderIterator & operator--()
485 handles_.template decrement<dimension>();
486 handles_.decrementIndex();
490 CoupledScanOrderIterator operator--(
int)
492 CoupledScanOrderIterator res(*
this);
499 return operator+=(-i);
502 CoupledScanOrderIterator & operator-=(
const shape_type &coordOffset)
504 return operator+=(-coordOffset);
509 return *(CoupledScanOrderIterator(*
this) += i);
512 value_type operator[](
const shape_type& coordOffset)
const
514 return *(CoupledScanOrderIterator(*
this) += coordOffset);
517 CoupledScanOrderIterator
520 return CoupledScanOrderIterator(*
this) += d;
523 CoupledScanOrderIterator
526 return CoupledScanOrderIterator(*
this) -= d;
529 CoupledScanOrderIterator operator+(
const shape_type &coordOffset)
const
531 return CoupledScanOrderIterator(*
this) += coordOffset;
534 CoupledScanOrderIterator operator-(
const shape_type &coordOffset)
const
536 return CoupledScanOrderIterator(*
this) -= coordOffset;
540 operator-(CoupledScanOrderIterator
const & r)
const
542 return scanOrderIndex() - r.scanOrderIndex();
545 bool operator==(CoupledScanOrderIterator
const & r)
const
547 return scanOrderIndex() == r.scanOrderIndex();
550 bool operator!=(CoupledScanOrderIterator
const & r)
const
552 return scanOrderIndex() != r.scanOrderIndex();
555 bool operator<(CoupledScanOrderIterator
const & r)
const
557 return scanOrderIndex() < r.scanOrderIndex();
560 bool operator<=(CoupledScanOrderIterator
const & r)
const
562 return scanOrderIndex() <= r.scanOrderIndex();
565 bool operator>(CoupledScanOrderIterator
const & r)
const
567 return scanOrderIndex() > r.scanOrderIndex();
570 bool operator>=(CoupledScanOrderIterator
const & r)
const
572 return scanOrderIndex() >= r.scanOrderIndex();
577 return handles_.scanOrderIndex() <
prod(shape());
582 return handles_.scanOrderIndex() >=
prod(shape());
587 return handles_.scanOrderIndex();
590 shape_type
const & coord()
const
592 return handles_.point();
600 shape_type
const & point()
const
602 return handles_.point();
610 shape_type
const & shape()
const
612 return handles_.shape();
617 return handles_.shape()[dim];
620 reference operator*()
625 const_reference operator*()
const
630 CoupledScanOrderIterator &
631 restrictToSubarray(shape_type
const & start, shape_type
const & end)
633 operator+=(-point());
634 handles_.restrictToSubarray(start, end);
635 strides_ = detail::defaultStride(shape());
641 return operator+(
prod(shape())-scanOrderIndex());
644 bool atBorder()
const
646 return (handles_.borderType() != 0);
649 unsigned int borderType()
const
651 return handles_.borderType();
654 template<
unsigned int TARGET_INDEX>
655 typename Reference<TARGET_INDEX>::type
658 return vigra::get<TARGET_INDEX>(handles_);
661 template<
unsigned int TARGET_INDEX>
662 typename ConstReference<TARGET_INDEX>::type
665 return vigra::get<TARGET_INDEX>(handles_);
673 const_reference handles()
const
681 handles_.template decrement<dimension>(shape()[dimension]);
686 handles_.template increment<dimension>(shape()[dimension]);
693 template <
unsigned int TARGET_INDEX,
697 typename CoupledScanOrderIterator<N, HANDLES, DIM>::template Reference<TARGET_INDEX>::type
698 get(CoupledScanOrderIterator<N, HANDLES, DIM> & i)
700 return vigra::get<TARGET_INDEX>(*i);
703 template <
unsigned int TARGET_INDEX,
707 typename CoupledScanOrderIterator<N, HANDLES, DIM>::template ConstReference<TARGET_INDEX>::type
708 get(CoupledScanOrderIterator<N, HANDLES, DIM>
const & i)
710 return vigra::get<TARGET_INDEX>(*i);
715 template <
unsigned int N,
class T1=
void,
class T2=
void,
class T3=
void,
class T4=
void,
class T5=
void>
719 typedef typename CoupledHandleType<N, T1, T2, T3, T4, T5>::type
HandleType;
728 template <
unsigned int N,
class T1=
void,
class T2=
void,
class T3=
void,
class T4=
void,
class T5=
void>
739 typedef typename CoupledHandleType<N>::type P0;
742 return IteratorType(P0(shape));
747 template <
unsigned int N1,
class T1,
class S1>
748 typename CoupledIteratorType<N1, T1>::type
751 typedef typename CoupledHandleType<N1, T1>::type P1;
752 typedef typename P1::base_type P0;
755 return IteratorType(P1(m1,
761 template <
unsigned int N1,
class T1,
class S1,
762 unsigned int N2,
class T2,
class S2>
763 typename CoupledIteratorType<N1, T1, T2>::type
767 typedef typename CoupledHandleType<N1, T1, T2>::type P2;
768 typedef typename P2::base_type P1;
769 typedef typename P1::base_type P0;
772 return IteratorType(P2(m2,
779 template <
unsigned int N1,
class T1,
class S1,
780 unsigned int N2,
class T2,
class S2,
781 unsigned int N3,
class T3,
class S3>
782 typename CoupledIteratorType<N1, T1, T2, T3>::type
787 typedef typename CoupledHandleType<N1, T1, T2, T3>::type P3;
788 typedef typename P3::base_type P2;
789 typedef typename P2::base_type P1;
790 typedef typename P1::base_type P0;
793 return IteratorType(P3(m3,
801 template <
unsigned int N1,
class T1,
class S1,
802 unsigned int N2,
class T2,
class S2,
803 unsigned int N3,
class T3,
class S3,
804 unsigned int N4,
class T4,
class S4>
805 typename CoupledIteratorType<N1, T1, T2, T3, T4>::type
811 typedef typename CoupledHandleType<N1, T1, T2, T3, T4>::type P4;
812 typedef typename P4::base_type P3;
813 typedef typename P3::base_type P2;
814 typedef typename P2::base_type P1;
815 typedef typename P1::base_type P0;
818 return IteratorType(P4(m4,
827 template <
unsigned int N1,
class T1,
class S1,
828 unsigned int N2,
class T2,
class S2,
829 unsigned int N3,
class T3,
class S3,
830 unsigned int N4,
class T4,
class S4,
831 unsigned int N5,
class T5,
class S5>
832 typename CoupledIteratorType<N1, T1, T2, T3, T4, T5>::type
839 typedef typename CoupledHandleType<N1, T1, T2, T3, T4, T5>::type P5;
840 typedef typename P5::base_type P4;
841 typedef typename P4::base_type P3;
842 typedef typename P3::base_type P2;
843 typedef typename P2::base_type P1;
844 typedef typename P1::base_type P0;
847 return IteratorType(P5(m5,
852 P0(m1.
shape())))))));
855 template <
unsigned int N,
class A,
class B>
856 CoupledScanOrderIterator<N, typename ZipCoupledHandles<A, B>::type>
857 zip(CoupledScanOrderIterator<N, A>
const & a, CoupledScanOrderIterator<N, B>
const & b)
859 vigra_precondition(a.shape() == b.shape() && a.scanOrderIndex() == b.scanOrderIndex(),
860 "zip(CoupledScanOrderIterator): iterators must have identical shape and position.");
862 typedef typename ZipCoupledHandles<A, B>::type Handle;
863 typedef CoupledScanOrderIterator<N, Handle> IteratorType;
864 return IteratorType(ZipCoupledHandles<A, B>::construct(*a, *b));
873 template <
unsigned int N,
class HANDLES,
int DIMENSION>
874 ostream & operator<<(ostream & o, vigra::CoupledScanOrderIterator<N, HANDLES, DIMENSION>
const & i)
Definition: multi_iterator_coupled.hxx:716
const difference_type & shape() const
Definition: multi_array.hxx:1648
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
FFTWComplex< R > & operator-=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
subtract-assignment
Definition: fftw3.hxx:867
HANDLES value_type
Definition: multi_iterator_coupled.hxx:211
CoupledScanOrderIterator< HandleType::dimensions, HandleType > IteratorType
Definition: multi_iterator_coupled.hxx:722
bool operator<=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less or equal
Definition: fixedpoint.hxx:521
CoupledHandleType< N, T1, T2, T3, T4, T5 >::type HandleType
Definition: multi_iterator_coupled.hxx:719
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
NumericTraits< V >::Promote prod(TinyVectorBase< V, SIZE, D1, D2 > const &l)
product of the vector's elements
Definition: tinyvector.hxx:2097
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
CoupledScanOrderIterator getEndIterator() const
Definition: multi_iterator_coupled.hxx:282
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
Definition: multi_iterator_coupled.hxx:729
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
bool operator<(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less than
Definition: fixedpoint.hxx:512
bool operator>=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater or equal
Definition: fixedpoint.hxx:539
Base class for, and view to, vigra::MultiArray.
Definition: multi_array.hxx:704
Iterate over multiple images simultaneously in scan order.
Definition: multi_fwd.hxx:167
bool operator>(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater
Definition: fixedpoint.hxx:530