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])
255 base_type::operator--();
256 if(this->point()[dimension-1] == -1)
284 return operator+(
prod(this->shape()) - this->scanOrderIndex());
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>
356 this->handles_.template increment<dimension>();
359 template <
unsigned int N,
class HANDLES,
int DIMENSION>
362 base_type::inverseReset();
363 this->handles_.template decrement<dimension>();
366 template <
unsigned int N,
class HANDLES>
371 static const int dimension = 0;
374 typedef HANDLES value_type;
376 typedef value_type & reference;
377 typedef value_type
const & const_reference;
378 typedef value_type * pointer;
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;
398 strides_(detail::defaultStride(handles_.shape()))
401 template <
unsigned int DIM>
402 typename CoupledScanOrderIterator<N, HANDLES, DIM>::dimension_proxy &
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 &
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]);
453 handles_.template increment<dimension>();
454 handles_.incrementIndex();
468 shape_type coordOffset;
469 detail::ScanOrderToCoordinate<N>::exec(i+scanOrderIndex(), shape(), coordOffset);
470 coordOffset -= point();
471 handles_.add(coordOffset);
472 handles_.scanOrderIndex_ += i;
478 handles_.add(coordOffset);
479 handles_.scanOrderIndex_ += detail::CoordinateToScanOrder<N>::exec(shape(), coordOffset);
485 handles_.template decrement<dimension>();
486 handles_.decrementIndex();
512 value_type operator[](
const shape_type& coordOffset)
const 542 return scanOrderIndex() - r.scanOrderIndex();
547 return scanOrderIndex() == r.scanOrderIndex();
552 return scanOrderIndex() != r.scanOrderIndex();
557 return scanOrderIndex() < r.scanOrderIndex();
562 return scanOrderIndex() <= r.scanOrderIndex();
567 return scanOrderIndex() > r.scanOrderIndex();
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 631 restrictToSubarray(shape_type
const & start, shape_type
const & end)
634 handles_.restrictToSubarray(start, end);
635 strides_ = detail::defaultStride(shape());
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,
700 return vigra::get<TARGET_INDEX>(*i);
703 template <
unsigned int TARGET_INDEX,
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;
723 typedef IteratorType
type;
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>
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>
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>
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>
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>
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>
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;
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
Diff2D operator-(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:711
Definition: array_vector.hxx:954
Diff2D operator+(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:739
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
Definition: accessor.hxx:43
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
const difference_type & shape() const
Definition: multi_array.hxx:1596
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
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:652
CoupledScanOrderIterator getEndIterator() const
Definition: multi_iterator_coupled.hxx:282
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