37 #ifndef VIGRA_MULTI_ITERATOR_HXX
38 #define VIGRA_MULTI_ITERATOR_HXX
40 #include <sys/types.h>
41 #include "multi_fwd.hxx"
42 #include "iteratortags.hxx"
43 #include "multi_iterator_coupled.hxx"
86 template<
unsigned int N>
87 class MultiCoordinateIterator
88 :
public CoupledScanOrderIterator<N>
91 typedef CoupledScanOrderIterator<N> base_type;
93 typedef typename base_type::shape_type shape_type;
94 typedef typename base_type::difference_type difference_type;
95 typedef MultiCoordinateIterator iterator;
96 typedef std::random_access_iterator_tag iterator_category;
98 typedef typename base_type::value_type handle_type;
99 typedef typename handle_type::value_type value_type;
100 typedef typename handle_type::reference reference;
101 typedef typename handle_type::const_reference const_reference;
102 typedef typename handle_type::pointer pointer;
103 typedef typename handle_type::const_pointer const_pointer;
105 MultiCoordinateIterator()
106 : base_type(handle_type())
109 explicit MultiCoordinateIterator(shape_type
const & shape)
110 : base_type(handle_type(shape))
113 explicit MultiCoordinateIterator(shape_type
const & start, shape_type
const & end)
114 : base_type(handle_type(end))
116 this->restrictToSubarray(start, end);
119 template<
class DirectedTag>
120 explicit MultiCoordinateIterator(GridGraph<N, DirectedTag>
const & g)
121 : base_type(handle_type(g.shape()))
126 reference operator*()
128 return this->
template get<0>();
131 const_reference operator*()
const
133 return this->
template get<0>();
136 operator value_type()
const
143 return &this->
template get<0>();
146 const_pointer operator->()
const
148 return &this->
template get<0>();
153 return *(MultiCoordinateIterator(*
this) += i);
156 MultiCoordinateIterator & operator++()
158 base_type::operator++();
162 MultiCoordinateIterator operator++(
int)
164 MultiCoordinateIterator res(*
this);
171 base_type::operator+=(i);
175 MultiCoordinateIterator & operator+=(
const shape_type &coordOffset)
177 base_type::operator+=(coordOffset);
181 MultiCoordinateIterator & operator--()
183 base_type::operator--();
187 MultiCoordinateIterator operator--(
int)
189 MultiCoordinateIterator res(*
this);
196 return operator+=(-i);
199 MultiCoordinateIterator & operator-=(
const shape_type &coordOffset)
201 return operator+=(-coordOffset);
204 MultiCoordinateIterator getEndIterator()
const
211 return MultiCoordinateIterator(*
this) += d;
216 return MultiCoordinateIterator(*
this) -= d;
219 MultiCoordinateIterator operator+(
const shape_type &coordOffset)
const
221 return MultiCoordinateIterator(*
this) += coordOffset;
224 MultiCoordinateIterator operator-(
const shape_type &coordOffset)
const
226 return MultiCoordinateIterator(*
this) -= coordOffset;
231 return base_type::operator-(other);
235 MultiCoordinateIterator(base_type
const & base)
257 template <
unsigned int N,
class V,
class REFERENCE,
class POINTER>
258 class StridedScanOrderIterator
259 :
public CoupledIteratorType<N, V>::type
262 typedef typename CoupledIteratorType<N, V>::type base_type;
263 typedef typename base_type::value_type handle_type;
265 typedef typename base_type::shape_type shape_type;
266 typedef typename base_type::difference_type difference_type;
267 typedef StridedScanOrderIterator iterator;
268 typedef std::random_access_iterator_tag iterator_category;
270 typedef typename detail::ResolveChunkedMemory<V>::type T;
271 typedef T value_type;
272 typedef REFERENCE reference;
273 typedef T
const & const_reference;
274 typedef POINTER pointer;
275 typedef T
const * const_pointer;
277 StridedScanOrderIterator()
282 explicit StridedScanOrderIterator(MultiArrayView<N, T, S>
const & view)
283 : base_type(createCoupledIterator(view))
286 StridedScanOrderIterator(POINTER p, shape_type
const & shape, shape_type
const & strides)
287 : base_type(createCoupledIterator(MultiArrayView<N, T, StridedArrayTag>(shape, strides, const_cast<T *>(p))))
290 StridedScanOrderIterator(handle_type
const & handle)
294 reference operator*()
296 return this->
template get<1>();
299 const_reference operator*()
const
301 return this->
template get<1>();
306 return &this->
template get<1>();
309 const_pointer operator->()
const
311 return &this->
template get<1>();
316 return *(StridedScanOrderIterator(*
this) += i);
321 return *(StridedScanOrderIterator(*
this) += i);
324 reference operator[](
const shape_type& coordOffset)
326 return *(StridedScanOrderIterator(*
this) += coordOffset);
329 const_reference operator[](
const shape_type& coordOffset)
const
331 return *(StridedScanOrderIterator(*
this) += coordOffset);
334 StridedScanOrderIterator & operator++()
336 base_type::operator++();
340 StridedScanOrderIterator operator++(
int)
342 StridedScanOrderIterator res(*
this);
353 StridedScanOrderIterator &
operator+=(
const shape_type &coordOffset)
359 StridedScanOrderIterator & operator--()
361 base_type::operator--();
365 StridedScanOrderIterator operator--(
int)
367 StridedScanOrderIterator res(*
this);
377 StridedScanOrderIterator &
operator-=(
const shape_type &coordOffset)
382 StridedScanOrderIterator getEndIterator()
const
384 return StridedScanOrderIterator(base_type::getEndIterator());
389 return StridedScanOrderIterator(*
this) += d;
394 return StridedScanOrderIterator(*
this) -= d;
402 StridedScanOrderIterator
operator+(
const shape_type &coordOffset)
const
404 return StridedScanOrderIterator(*
this) += coordOffset;
407 StridedScanOrderIterator
operator-(
const shape_type &coordOffset)
const
409 return StridedScanOrderIterator(*
this) -= coordOffset;
414 return this->scanOrderIndex();
417 StridedScanOrderIterator &
418 restrictToSubarray(shape_type
const & start, shape_type
const & stop)
420 base_type::restrictToSubarray(start, stop);
425 StridedScanOrderIterator(base_type
const & base)
721 template <
class POINTER>
722 struct MultiIteratorStrideTraits
725 typedef const stride_type* stride_array_type;
726 typedef stride_array_type shape_array_type;
727 static stride_array_type shift(stride_array_type s,
unsigned d)
746 template <
class T,
class REFERENCE,
class POINTER>
747 class MultiIterator<1, T, REFERENCE, POINTER>
751 typedef T value_type;
752 typedef REFERENCE reference;
753 typedef const value_type &const_reference;
754 typedef POINTER pointer;
755 typedef const value_type *const_pointer;
756 typedef typename MultiArrayShape<1>::type multi_difference_type;
757 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
758 typedef typename stride_traits::stride_type difference_type;
759 typedef typename stride_traits::stride_array_type difference_array_type;
760 typedef typename stride_traits::shape_array_type shape_array_type;
761 typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
762 typedef std::random_access_iterator_tag iterator_category;
772 MultiIterator (pointer ptr,
773 const difference_array_type &,
774 const shape_array_type &)
788 MultiIterator operator++ (
int)
790 MultiIterator ret = *
this;
795 MultiIterator operator-- (
int)
797 MultiIterator ret = *
this;
808 MultiIterator &
operator+= (multi_difference_type
const & d)
820 MultiIterator &
operator-= (multi_difference_type
const & d)
826 MultiIterator
operator+ (difference_type n)
const
828 MultiIterator ret = *
this;
833 MultiIterator
operator+ (multi_difference_type
const & d)
const
835 MultiIterator ret = *
this;
840 difference_type
operator- (MultiIterator
const & d)
const
842 return (m_ptr - d.m_ptr);
845 MultiIterator
operator- (difference_type n)
const
847 MultiIterator ret = *
this;
852 MultiIterator
operator- (multi_difference_type
const & d)
const
854 MultiIterator ret = *
this;
859 reference operator[] (difference_type n)
const
864 reference operator[] (multi_difference_type
const & d)
const
866 return m_ptr [d[level]];
869 reference operator* ()
const
879 pointer operator->()
const
881 return &(operator*());
884 bool operator!= (
const MultiIterator &rhs)
const
886 return m_ptr != rhs.m_ptr;
889 bool operator== (
const MultiIterator &rhs)
const
891 return m_ptr == rhs.m_ptr;
894 bool operator< (
const MultiIterator &rhs)
const
896 return m_ptr < rhs.m_ptr;
899 bool operator<= (
const MultiIterator &rhs)
const
901 return m_ptr <= rhs.m_ptr;
904 bool operator> (
const MultiIterator &rhs)
const
906 return m_ptr > rhs.m_ptr;
909 bool operator>= (
const MultiIterator &rhs)
const
911 return m_ptr >= rhs.m_ptr;
914 iterator iteratorForDimension(
unsigned int d)
const
916 vigra_precondition(d == 0,
917 "MultiIterator<1>::iteratorForDimension(d): d == 0 required");
918 const difference_type stride = 1;
919 return iterator(m_ptr, &stride, 0);
922 template <
unsigned int K>
923 MultiIterator<K+1, T, REFERENCE, POINTER> &
929 MultiIterator<1, T, REFERENCE, POINTER> &
930 dim0() {
return *
this; }
935 total_stride(
typename multi_difference_type::const_iterator d)
const
948 template <
class T,
class REFERENCE,
class POINTER>
949 class MultiIterator<2, T, REFERENCE, POINTER>
951 :
public MultiIterator<1, T, REFERENCE, POINTER>
956 typedef MultiIterator<1, T, REFERENCE, POINTER>
base_type;
964 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
966 typedef typename stride_traits::stride_array_type difference_array_type;
967 typedef typename stride_traits::shape_array_type shape_array_type;
969 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
iterator;
973 difference_array_type m_stride;
974 shape_array_type m_shape;
981 m_stride (0), m_shape (0)
985 const difference_array_type & stride,
986 const shape_array_type & shape)
987 : base_type (ptr, stride, shape),
988 m_stride (stride), m_shape (shape)
993 this->m_ptr += m_stride [level];
998 this->m_ptr -= m_stride [level];
1017 this->m_ptr += n * m_stride [level];
1023 this->m_ptr += total_stride(d.begin());
1029 this->m_ptr -= n * m_stride [level];
1035 this->m_ptr -= total_stride(d.begin());
1055 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1072 reference
operator[] (difference_type n)
const
1074 return this->m_ptr [n*m_stride [level]];
1077 reference
operator[] (multi_difference_type
const & d)
const
1079 return this->m_ptr [total_stride(d.begin())];
1090 ret += m_shape [level-1];
1096 vigra_precondition(d <= level,
1097 "MultiIterator<N>::iteratorForDimension(d): d < N required");
1098 return iterator(this->m_ptr, stride_traits::shift(m_stride, d), 0);
1101 template <
unsigned int K>
1102 MultiIterator<K+1, T, REFERENCE, POINTER> &
1108 MultiIterator<1, T, REFERENCE, POINTER> &
1109 dim0() {
return *
this; }
1110 MultiIterator<2, T, REFERENCE, POINTER> &
1111 dim1() {
return *
this; }
1116 total_stride(
typename multi_difference_type::const_iterator d)
const
1118 return d[level]*m_stride[level] + base_type::total_stride(d);
1136 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
1139 :
public MultiIterator<N-1, T, REFERENCE, POINTER>
1150 enum { level = N-1 };
1180 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1182 typedef typename stride_traits::stride_array_type difference_array_type;
1183 typedef typename stride_traits::shape_array_type shape_array_type;
1212 const difference_array_type & stride,
1213 const shape_array_type & shape)
1214 : base_type (ptr, stride, shape)
1222 this->m_ptr += this->m_stride [level];
1229 this->m_ptr -= this->m_stride [level];
1255 this->m_ptr += n * this->m_stride [level];
1264 this->m_ptr += total_stride(d.
begin());
1273 this->m_ptr -= n * this->m_stride [level];
1282 this->m_ptr -= total_stride(d.
begin());
1310 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1338 pointer
get ()
const;
1374 return this->m_ptr [n* this->m_stride [level]];
1381 return this->m_ptr [total_stride(d.
begin())];
1417 ret += this->m_shape [level-1];
1439 vigra_precondition(d <= level,
1440 "MultiIterator<N>::iteratorForDimension(d): d < N required");
1441 return iterator(this->m_ptr, stride_traits::shift(this->m_stride, d),0);
1465 template <
unsigned int K>
1473 dim0() {
return *
this; }
1474 MultiIterator<2, T, REFERENCE, POINTER> &
1475 dim1() {
return *
this; }
1476 MultiIterator<3, T, REFERENCE, POINTER> &
1477 dim2() {
return *
this; }
1478 MultiIterator<4, T, REFERENCE, POINTER> &
1479 dim3() {
return *
this; }
1480 MultiIterator<5, T, REFERENCE, POINTER> &
1481 dim4() {
return *
this; }
1486 total_stride(
typename multi_difference_type::const_iterator d)
const
1488 return d[level]*this->m_stride[level] + base_type::total_stride(d);
1506 template <
class T,
class REFERENCE,
class POINTER>
1507 class StridedMultiIterator<1, T, REFERENCE, POINTER>
1517 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1519 typedef typename stride_traits::stride_array_type difference_array_type;
1520 typedef typename stride_traits::shape_array_type shape_array_type;
1521 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
iterator;
1526 difference_type m_stride;
1532 : m_ptr (0), m_stride (0)
1536 const difference_array_type & stride,
1537 const shape_array_type &)
1538 : m_ptr (ptr), m_stride (stride [level])
1567 m_ptr += n * m_stride;
1573 m_ptr += d[level] * m_stride;
1579 m_ptr -= n * m_stride;
1585 m_ptr -= d[level] * m_stride;
1605 return (m_ptr - d.m_ptr) / m_stride;
1622 reference
operator[] (difference_type n)
const
1624 return m_ptr [n*m_stride];
1627 reference
operator[] (multi_difference_type
const & d)
const
1629 return m_ptr [d[level]*m_stride];
1637 pointer
get ()
const
1649 return m_ptr != rhs.m_ptr;
1654 return m_ptr == rhs.m_ptr;
1659 return m_ptr < rhs.m_ptr;
1664 return m_ptr <= rhs.m_ptr;
1669 return m_ptr > rhs.m_ptr;
1674 return m_ptr >= rhs.m_ptr;
1679 vigra_precondition(d == 0,
1680 "StridedMultiIterator<1>::iteratorForDimension(d): d == 0 required");
1681 const difference_type stride = 1;
1682 return iterator(m_ptr, &stride, 0);
1685 template <
unsigned int K>
1686 StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
1692 StridedMultiIterator<1, T, REFERENCE, POINTER> &
1693 dim0() {
return *
this; }
1698 total_stride(
typename multi_difference_type::const_iterator d)
const
1700 return d[level] * m_stride;
1711 template <
class T,
class REFERENCE,
class POINTER>
1712 class StridedMultiIterator<2, T, REFERENCE, POINTER>
1714 :
public StridedMultiIterator<1, T, REFERENCE, POINTER>
1719 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
base_type;
1727 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1729 typedef typename stride_traits::stride_array_type difference_array_type;
1730 typedef typename stride_traits::shape_array_type shape_array_type;
1732 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
iterator;
1736 difference_array_type m_stride;
1737 shape_array_type m_shape;
1744 m_stride (0), m_shape (0)
1748 const difference_array_type & stride,
1749 const shape_array_type & shape)
1750 : base_type (ptr, stride, shape),
1751 m_stride (stride), m_shape (shape)
1756 this->m_ptr += m_stride [level];
1761 this->m_ptr -= m_stride [level];
1780 this->m_ptr += n * m_stride [level];
1786 this->m_ptr += total_stride(d.begin());
1792 this->m_ptr -= n * m_stride [level];
1798 this->m_ptr -= total_stride(d.begin());
1818 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1835 reference
operator[] (difference_type n)
const
1837 return this->m_ptr [n*m_stride [level]];
1840 reference
operator[] (multi_difference_type
const & d)
const
1842 return this->m_ptr [total_stride(d.begin())];
1853 ret += m_shape [level-1];
1859 vigra_precondition(d <= level,
1860 "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
1861 return iterator(this->m_ptr, stride_traits::shift(m_stride, d), 0);
1864 template <
unsigned int K>
1865 StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
1871 StridedMultiIterator<1, T, REFERENCE, POINTER> &
1872 dim0() {
return *
this; }
1873 StridedMultiIterator<2, T, REFERENCE, POINTER> &
1874 dim1() {
return *
this; }
1879 total_stride(
typename multi_difference_type::const_iterator d)
const
1881 return d[level]*m_stride[level] + base_type::total_stride(d);
1899 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
1900 class StridedMultiIterator
1902 :
public StridedMultiIterator<N-1, T, REFERENCE, POINTER>
1913 enum { level = N-1 };
1943 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1945 typedef typename stride_traits::stride_array_type difference_array_type;
1974 const difference_array_type & stride,
1975 const difference_array_type & shape)
1976 : base_type (ptr, stride, shape)
1984 this->m_ptr += this->m_stride [level];
1991 this->m_ptr -= this->m_stride [level];
2017 this->m_ptr += n * this->m_stride [level];
2026 this->m_ptr += total_stride(d.
begin());
2035 this->m_ptr -= n * this->m_stride [level];
2044 this->m_ptr -= total_stride(d.
begin());
2072 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
2100 pointer
get ()
const;
2136 return this->m_ptr [n* this->m_stride [level]];
2143 return this->m_ptr [total_stride(d.
begin())];
2179 ret += this->m_shape [level-1];
2201 vigra_precondition(d <= level,
2202 "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
2203 return iterator(this->m_ptr, stride_traits::shift(this->m_stride, d),0);
2227 template <
unsigned int K>
2235 dim0() {
return *
this; }
2236 StridedMultiIterator<2, T, REFERENCE, POINTER> &
2237 dim1() {
return *
this; }
2238 StridedMultiIterator<3, T, REFERENCE, POINTER> &
2239 dim2() {
return *
this; }
2240 StridedMultiIterator<4, T, REFERENCE, POINTER> &
2241 dim3() {
return *
this; }
2242 StridedMultiIterator<5, T, REFERENCE, POINTER> &
2243 dim4() {
return *
this; }
2248 total_stride(
typename multi_difference_type::const_iterator d)
const
2250 return d[level]*this->m_stride[level] + base_type::total_stride(d);
2261 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
2262 ostream & operator<<(ostream & o, vigra::StridedScanOrderIterator<N, T, REFERENCE, POINTER>
const & i)
2270 #endif // VIGRA_MULTI_ITERATOR_HXX