37 #ifndef VIGRA_MULTI_ITERATOR_HXX
38 #define VIGRA_MULTI_ITERATOR_HXX
40 #include <sys/types.h>
41 #include "iteratortags.hxx"
42 #include "multi_iterator_coupled.hxx"
46 template<
unsigned int N,
class DirectedTag>
88 template<
unsigned int N>
96 typedef typename base_type::difference_type difference_type;
98 typedef std::random_access_iterator_tag iterator_category;
100 typedef typename base_type::value_type handle_type;
101 typedef typename handle_type::value_type value_type;
102 typedef typename handle_type::reference reference;
103 typedef typename handle_type::const_reference const_reference;
104 typedef typename handle_type::pointer pointer;
105 typedef typename handle_type::const_pointer const_pointer;
118 this->restrictToSubarray(start, end);
121 template<
class DirectedTag>
128 reference operator*()
130 return this->
template get<0>();
133 const_reference operator*()
const
135 return this->
template get<0>();
138 operator value_type()
const
145 return &this->
template get<0>();
148 const_pointer operator->()
const
150 return &this->
template get<0>();
160 base_type::operator++();
173 base_type::operator+=(i);
179 base_type::operator+=(coordOffset);
185 base_type::operator--();
198 return operator+=(-i);
203 return operator+=(-coordOffset);
233 return base_type::operator-(other);
259 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
267 typedef typename base_type::difference_type difference_type;
269 typedef std::random_access_iterator_tag iterator_category;
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;
290 reference operator*()
292 return this->
template get<1>();
295 const_reference operator*()
const
297 return this->
template get<1>();
302 return &this->
template get<1>();
305 const_pointer operator->()
const
307 return &this->
template get<1>();
322 base_type::operator++();
347 base_type::operator--();
400 return this->scanOrderIndex();
700 template <
class POINTER>
701 struct MultiIteratorStrideTraits
704 typedef const stride_type* stride_array_type;
705 typedef stride_array_type shape_array_type;
706 static stride_array_type shift(stride_array_type s,
unsigned d)
712 template <
unsigned int N,
class T,
class REFERENCE = T &,
class POINTER = T *>
715 template <
unsigned int N,
class T,
class REFERENCE = T &,
class POINTER = T *>
731 template <
class T,
class REFERENCE,
class POINTER>
742 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
744 typedef typename stride_traits::stride_array_type difference_array_type;
745 typedef typename stride_traits::shape_array_type shape_array_type;
758 const difference_array_type &,
759 const shape_array_type &)
827 return (m_ptr - d.m_ptr);
844 reference operator[] (difference_type n)
const
849 reference operator[] (multi_difference_type
const & d)
const
851 return m_ptr [d[level]];
854 reference operator* ()
const
864 pointer operator->()
const
866 return &(operator*());
871 return m_ptr != rhs.m_ptr;
876 return m_ptr == rhs.m_ptr;
881 return m_ptr < rhs.m_ptr;
886 return m_ptr <= rhs.m_ptr;
891 return m_ptr > rhs.m_ptr;
896 return m_ptr >= rhs.m_ptr;
899 iterator iteratorForDimension(
unsigned int d)
const
901 vigra_precondition(d == 0,
902 "MultiIterator<1>::iteratorForDimension(d): d == 0 required");
903 const difference_type stride = 1;
904 return iterator(m_ptr, &stride, 0);
907 template <
unsigned int K>
915 dim0() {
return *
this; }
920 total_stride(
typename multi_difference_type::const_iterator d)
const
933 template <
class T,
class REFERENCE,
class POINTER>
949 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
951 typedef typename stride_traits::stride_array_type difference_array_type;
952 typedef typename stride_traits::shape_array_type shape_array_type;
954 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
iterator;
958 difference_array_type m_stride;
959 shape_array_type m_shape;
966 m_stride (0), m_shape (0)
970 const difference_array_type & stride,
971 const shape_array_type & shape)
973 m_stride (stride), m_shape (shape)
978 this->m_ptr += m_stride [level];
983 this->m_ptr -= m_stride [level];
1002 this->m_ptr += n * m_stride [level];
1008 this->m_ptr += total_stride(d.begin());
1014 this->m_ptr -= n * m_stride [level];
1020 this->m_ptr -= total_stride(d.begin());
1040 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1059 return this->m_ptr [n*m_stride [level]];
1064 return this->m_ptr [total_stride(d.begin())];
1075 ret += m_shape [level-1];
1081 vigra_precondition(d <= level,
1082 "MultiIterator<N>::iteratorForDimension(d): d < N required");
1083 return iterator(this->m_ptr, stride_traits::shift(m_stride, d), 0);
1086 template <
unsigned int K>
1087 MultiIterator<K+1, T, REFERENCE, POINTER> &
1093 MultiIterator<1, T, REFERENCE, POINTER> &
1094 dim0() {
return *
this; }
1095 MultiIterator<2, T, REFERENCE, POINTER> &
1096 dim1() {
return *
this; }
1101 total_stride(
typename multi_difference_type::const_iterator d)
const
1103 return d[level]*m_stride[level] + base_type::total_stride(d);
1121 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
1124 :
public MultiIterator<N-1, T, REFERENCE, POINTER>
1135 enum { level = N-1 };
1165 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1167 typedef typename stride_traits::stride_array_type difference_array_type;
1168 typedef typename stride_traits::shape_array_type shape_array_type;
1197 const difference_array_type & stride,
1198 const shape_array_type & shape)
1207 this->m_ptr += this->m_stride [level];
1214 this->m_ptr -= this->m_stride [level];
1240 this->m_ptr += n * this->m_stride [level];
1249 this->m_ptr += total_stride(d.
begin());
1258 this->m_ptr -= n * this->m_stride [level];
1267 this->m_ptr -= total_stride(d.
begin());
1295 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1359 return this->m_ptr [n* this->m_stride [level]];
1366 return this->m_ptr [total_stride(d.
begin())];
1402 ret += this->m_shape [level-1];
1424 vigra_precondition(d <= level,
1425 "MultiIterator<N>::iteratorForDimension(d): d < N required");
1426 return iterator(this->m_ptr, stride_traits::shift(this->m_stride, d),0);
1450 template <
unsigned int K>
1458 dim0() {
return *
this; }
1459 MultiIterator<2, T, REFERENCE, POINTER> &
1460 dim1() {
return *
this; }
1461 MultiIterator<3, T, REFERENCE, POINTER> &
1462 dim2() {
return *
this; }
1463 MultiIterator<4, T, REFERENCE, POINTER> &
1464 dim3() {
return *
this; }
1465 MultiIterator<5, T, REFERENCE, POINTER> &
1466 dim4() {
return *
this; }
1471 total_stride(
typename multi_difference_type::const_iterator d)
const
1473 return d[level]*this->m_stride[level] + base_type::total_stride(d);
1491 template <
class T,
class REFERENCE,
class POINTER>
1492 class StridedMultiIterator<1, T, REFERENCE, POINTER>
1502 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1504 typedef typename stride_traits::stride_array_type difference_array_type;
1505 typedef typename stride_traits::shape_array_type shape_array_type;
1506 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
iterator;
1517 : m_ptr (0), m_stride (0)
1521 const difference_array_type & stride,
1522 const shape_array_type &)
1523 : m_ptr (ptr), m_stride (stride [level])
1552 m_ptr += n * m_stride;
1558 m_ptr += d[level] * m_stride;
1564 m_ptr -= n * m_stride;
1570 m_ptr -= d[level] * m_stride;
1590 return (m_ptr - d.m_ptr) / m_stride;
1609 return m_ptr [n*m_stride];
1614 return m_ptr [d[level]*m_stride];
1634 return m_ptr != rhs.m_ptr;
1639 return m_ptr == rhs.m_ptr;
1644 return m_ptr < rhs.m_ptr;
1649 return m_ptr <= rhs.m_ptr;
1654 return m_ptr > rhs.m_ptr;
1659 return m_ptr >= rhs.m_ptr;
1664 vigra_precondition(d == 0,
1665 "StridedMultiIterator<1>::iteratorForDimension(d): d == 0 required");
1667 return iterator(m_ptr, &stride, 0);
1670 template <
unsigned int K>
1671 StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
1677 StridedMultiIterator<1, T, REFERENCE, POINTER> &
1678 dim0() {
return *
this; }
1683 total_stride(
typename multi_difference_type::const_iterator d)
const
1685 return d[level] * m_stride;
1696 template <
class T,
class REFERENCE,
class POINTER>
1697 class StridedMultiIterator<2, T, REFERENCE, POINTER>
1699 :
public StridedMultiIterator<1, T, REFERENCE, POINTER>
1704 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
base_type;
1712 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1714 typedef typename stride_traits::stride_array_type difference_array_type;
1715 typedef typename stride_traits::shape_array_type shape_array_type;
1717 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
iterator;
1721 difference_array_type m_stride;
1722 shape_array_type m_shape;
1729 m_stride (0), m_shape (0)
1733 const difference_array_type & stride,
1734 const shape_array_type & shape)
1736 m_stride (stride), m_shape (shape)
1741 this->m_ptr += m_stride [level];
1746 this->m_ptr -= m_stride [level];
1765 this->m_ptr += n * m_stride [level];
1771 this->m_ptr += total_stride(d.begin());
1777 this->m_ptr -= n * m_stride [level];
1783 this->m_ptr -= total_stride(d.begin());
1803 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1822 return this->m_ptr [n*m_stride [level]];
1827 return this->m_ptr [total_stride(d.begin())];
1838 ret += m_shape [level-1];
1844 vigra_precondition(d <= level,
1845 "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
1846 return iterator(this->m_ptr, stride_traits::shift(m_stride, d), 0);
1849 template <
unsigned int K>
1850 StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
1856 StridedMultiIterator<1, T, REFERENCE, POINTER> &
1857 dim0() {
return *
this; }
1858 StridedMultiIterator<2, T, REFERENCE, POINTER> &
1859 dim1() {
return *
this; }
1864 total_stride(
typename multi_difference_type::const_iterator d)
const
1866 return d[level]*m_stride[level] + base_type::total_stride(d);
1884 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
1885 class StridedMultiIterator
1887 :
public StridedMultiIterator<N-1, T, REFERENCE, POINTER>
1898 enum { level = N-1 };
1928 typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1930 typedef typename stride_traits::stride_array_type difference_array_type;
1959 const difference_array_type & stride,
1960 const difference_array_type & shape)
1969 this->m_ptr += this->m_stride [level];
1976 this->m_ptr -= this->m_stride [level];
2002 this->m_ptr += n * this->m_stride [level];
2011 this->m_ptr += total_stride(d.
begin());
2020 this->m_ptr -= n * this->m_stride [level];
2029 this->m_ptr -= total_stride(d.
begin());
2057 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
2121 return this->m_ptr [n* this->m_stride [level]];
2128 return this->m_ptr [total_stride(d.
begin())];
2164 ret += this->m_shape [level-1];
2186 vigra_precondition(d <= level,
2187 "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
2188 return iterator(this->m_ptr, stride_traits::shift(this->m_stride, d),0);
2212 template <
unsigned int K>
2220 dim0() {
return *
this; }
2221 StridedMultiIterator<2, T, REFERENCE, POINTER> &
2222 dim1() {
return *
this; }
2223 StridedMultiIterator<3, T, REFERENCE, POINTER> &
2224 dim2() {
return *
this; }
2225 StridedMultiIterator<4, T, REFERENCE, POINTER> &
2226 dim3() {
return *
this; }
2227 StridedMultiIterator<5, T, REFERENCE, POINTER> &
2228 dim4() {
return *
this; }
2233 total_stride(
typename multi_difference_type::const_iterator d)
const
2235 return d[level]*this->m_stride[level] + base_type::total_stride(d);
2246 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
2247 ostream & operator<<(ostream & o, vigra::StridedScanOrderIterator<N, T, REFERENCE, POINTER>
const & i)
2255 #endif // VIGRA_MULTI_ITERATOR_HXX