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