38 #ifndef VIGRA_MULTI_ITERATOR_HXX
39 #define VIGRA_MULTI_ITERATOR_HXX
41 #include <sys/types.h>
42 #include "tinyvector.hxx"
43 #include "iteratortags.hxx"
48 template <
unsigned int N,
class T,
49 class REFERENCE = T &,
class POINTER = T *>
class MultiIterator;
50 template <
unsigned int N,
class T,
51 class REFERENCE = T &,
class POINTER = T *>
class StridedMultiIterator;
349 template <
unsigned int N>
365 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
375 template <
class T,
class REFERENCE,
class POINTER>
387 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
iterator;
468 return (m_ptr - d.m_ptr);
492 return m_ptr [d[level]];
512 return m_ptr != rhs.m_ptr;
517 return m_ptr == rhs.m_ptr;
522 return m_ptr < rhs.m_ptr;
527 return m_ptr <= rhs.m_ptr;
532 return m_ptr > rhs.m_ptr;
537 return m_ptr >= rhs.m_ptr;
542 vigra_precondition(d == 0,
543 "MultiIterator<1>::iteratorForDimension(d): d == 0 required");
548 template <
unsigned int K>
549 MultiIterator<K+1, T, REFERENCE, POINTER> &
555 MultiIterator<1, T, REFERENCE, POINTER> &
556 dim0() {
return *
this; }
574 template <
class T,
class REFERENCE,
class POINTER>
575 class MultiIterator<2, T, REFERENCE, POINTER>
576 :
public MultiIterator<1, T, REFERENCE, POINTER>
580 typedef MultiIterator<1, T, REFERENCE, POINTER>
base_type;
590 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
iterator;
602 m_stride (0), m_shape (0)
609 m_stride (stride), m_shape (shape)
614 this->m_ptr += m_stride [level];
619 this->m_ptr -= m_stride [level];
638 this->m_ptr += n * m_stride [level];
644 this->m_ptr += total_stride(d.begin());
650 this->m_ptr -= n * m_stride [level];
656 this->m_ptr -= total_stride(d.begin());
676 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
695 return this->m_ptr [n*m_stride [level]];
700 return this->m_ptr [total_stride(d.begin())];
711 ret += m_shape [level-1];
717 vigra_precondition(d <= level,
718 "MultiIterator<N>::iteratorForDimension(d): d < N required");
719 return iterator(this->m_ptr, &m_stride [d], 0);
722 template <
unsigned int K>
723 MultiIterator<K+1, T, REFERENCE, POINTER> &
729 MultiIterator<1, T, REFERENCE, POINTER> &
730 dim0() {
return *
this; }
731 MultiIterator<2, T, REFERENCE, POINTER> &
732 dim1() {
return *
this; }
739 return d[level]*m_stride[level] + base_type::total_stride(d);
758 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
770 enum { level = N-1 };
835 this->m_ptr += this->m_stride [level];
842 this->m_ptr -= this->m_stride [level];
868 this->m_ptr += n * this->m_stride [level];
877 this->m_ptr += total_stride(d.
begin());
886 this->m_ptr -= n * this->m_stride [level];
895 this->m_ptr -= total_stride(d.
begin());
923 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
987 return this->m_ptr [n* this->m_stride [level]];
994 return this->m_ptr [total_stride(d.
begin())];
1030 ret += this->m_shape [level-1];
1052 vigra_precondition(d <= level,
1053 "MultiIterator<N>::iteratorForDimension(d): d < N required");
1054 return iterator(this->m_ptr, &this->m_stride [d], 0);
1078 template <
unsigned int K>
1086 dim0() {
return *
this; }
1087 MultiIterator<2, T, REFERENCE, POINTER> &
1088 dim1() {
return *
this; }
1089 MultiIterator<3, T, REFERENCE, POINTER> &
1090 dim2() {
return *
this; }
1091 MultiIterator<4, T, REFERENCE, POINTER> &
1092 dim3() {
return *
this; }
1093 MultiIterator<5, T, REFERENCE, POINTER> &
1094 dim4() {
return *
this; }
1101 return d[level]*this->m_stride[level] + base_type::total_stride(d);
1112 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
1113 class StridedMultiIterator;
1122 template <
class T,
class REFERENCE,
class POINTER>
1123 class StridedMultiIterator<1, T, REFERENCE, POINTER>
1134 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
iterator;
1145 : m_ptr (0), m_stride (0)
1151 : m_ptr (ptr), m_stride (stride [level])
1180 m_ptr += n * m_stride;
1186 m_ptr += d[level] * m_stride;
1192 m_ptr -= n * m_stride;
1198 m_ptr -= d[level] * m_stride;
1218 return (m_ptr - d.m_ptr) / m_stride;
1237 return m_ptr [n*m_stride];
1242 return m_ptr [d[level]*m_stride];
1262 return m_ptr != rhs.m_ptr;
1267 return m_ptr == rhs.m_ptr;
1272 return m_ptr < rhs.m_ptr;
1277 return m_ptr <= rhs.m_ptr;
1282 return m_ptr > rhs.m_ptr;
1287 return m_ptr >= rhs.m_ptr;
1292 vigra_precondition(d == 0,
1293 "StridedMultiIterator<1>::iteratorForDimension(d): d == 0 required");
1295 return iterator(m_ptr, &stride, 0);
1298 template <
unsigned int K>
1299 StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
1305 StridedMultiIterator<1, T, REFERENCE, POINTER> &
1306 dim0() {
return *
this; }
1313 return d[level] * m_stride;
1324 template <
class T,
class REFERENCE,
class POINTER>
1325 class StridedMultiIterator<2, T, REFERENCE, POINTER>
1326 :
public StridedMultiIterator<1, T, REFERENCE, POINTER>
1330 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
base_type;
1340 typedef StridedMultiIterator<1, T, REFERENCE, POINTER>
iterator;
1352 m_stride (0), m_shape (0)
1359 m_stride (stride), m_shape (shape)
1364 this->m_ptr += m_stride [level];
1369 this->m_ptr -= m_stride [level];
1388 this->m_ptr += n * m_stride [level];
1394 this->m_ptr += total_stride(d.begin());
1400 this->m_ptr -= n * m_stride [level];
1406 this->m_ptr -= total_stride(d.begin());
1426 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1445 return this->m_ptr [n*m_stride [level]];
1450 return this->m_ptr [total_stride(d.begin())];
1461 ret += m_shape [level-1];
1467 vigra_precondition(d <= level,
1468 "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
1469 return iterator(this->m_ptr, &m_stride [d], 0);
1472 template <
unsigned int K>
1473 StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
1479 StridedMultiIterator<1, T, REFERENCE, POINTER> &
1480 dim0() {
return *
this; }
1481 StridedMultiIterator<2, T, REFERENCE, POINTER> &
1482 dim1() {
return *
this; }
1489 return d[level]*m_stride[level] + base_type::total_stride(d);
1508 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
1520 enum { level = N-1 };
1585 this->m_ptr += this->m_stride [level];
1592 this->m_ptr -= this->m_stride [level];
1618 this->m_ptr += n * this->m_stride [level];
1627 this->m_ptr += total_stride(d.
begin());
1636 this->m_ptr -= n * this->m_stride [level];
1645 this->m_ptr -= total_stride(d.
begin());
1673 return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1737 return this->m_ptr [n* this->m_stride [level]];
1744 return this->m_ptr [total_stride(d.
begin())];
1780 ret += this->m_shape [level-1];
1802 vigra_precondition(d <= level,
1803 "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
1804 return iterator(this->m_ptr, &this->m_stride [d], 0);
1828 template <
unsigned int K>
1836 dim0() {
return *
this; }
1837 StridedMultiIterator<2, T, REFERENCE, POINTER> &
1838 dim1() {
return *
this; }
1839 StridedMultiIterator<3, T, REFERENCE, POINTER> &
1840 dim2() {
return *
this; }
1841 StridedMultiIterator<4, T, REFERENCE, POINTER> &
1842 dim3() {
return *
this; }
1843 StridedMultiIterator<5, T, REFERENCE, POINTER> &
1844 dim4() {
return *
this; }
1851 return d[level]*this->m_stride[level] + base_type::total_stride(d);
1860 #endif // VIGRA_MULTI_ITERATOR_HXX