[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

multi_iterator.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2003-2012 by Gunnar Kedenburg and Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* ( Version 1.3.0, Sep 10 2004 ) */
7 /* The VIGRA Website is */
8 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
9 /* Please direct questions, bug reports, and contributions to */
10 /* ullrich.koethe@iwr.uni-heidelberg.de or */
11 /* vigra@informatik.uni-hamburg.de */
12 /* */
13 /* Permission is hereby granted, free of charge, to any person */
14 /* obtaining a copy of this software and associated documentation */
15 /* files (the "Software"), to deal in the Software without */
16 /* restriction, including without limitation the rights to use, */
17 /* copy, modify, merge, publish, distribute, sublicense, and/or */
18 /* sell copies of the Software, and to permit persons to whom the */
19 /* Software is furnished to do so, subject to the following */
20 /* conditions: */
21 /* */
22 /* The above copyright notice and this permission notice shall be */
23 /* included in all copies or substantial portions of the */
24 /* Software. */
25 /* */
26 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
27 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
28 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
29 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
30 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
31 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
32 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
33 /* OTHER DEALINGS IN THE SOFTWARE. */
34 /* */
35 /************************************************************************/
36 
37 #ifndef VIGRA_MULTI_ITERATOR_HXX
38 #define VIGRA_MULTI_ITERATOR_HXX
39 
40 #include <sys/types.h>
41 #include "multi_fwd.hxx"
42 #include "iteratortags.hxx"
43 #include "multi_iterator_coupled.hxx"
44 
45 namespace vigra {
46 
47 /** \addtogroup MultiIteratorGroup
48 */
49 //@{
50 
51  /** \brief Iterate over a virtual array where each element contains its coordinate.
52 
53  MultiCoordinateIterator behaves like a read-only random access iterator.
54  It moves accross the given region of interest in scan-order (with the first
55  index changing most rapidly), and dereferencing the iterator returns the
56  coordinate (i.e. multi-dimensional index) of the current array element.
57  The functionality is thus similar to a meshgrid in Matlab or numpy.
58 
59  Internally, it is just a wrapper of a \ref CoupledScanOrderIterator that
60  has been created without any array and whose reference type is not a
61  \ref CoupledHandle, but the coordinate itself.
62 
63  The iterator supports all functions listed in the STL documentation for
64  <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterators</a>.
65 
66  <b>Usage:</b>
67 
68  <b>\#include</b> <vigra/multi_iterator.hxx><br/>
69  Namespace: vigra
70 
71  \code
72  MultiCoordinateIterator<3> i(Shape3(3,2,1)), end = i.getEndIterator();
73 
74  for(; i != end; ++i)
75  std::cout << *i << "\n";
76 
77  // Output:
78  // (0, 0, 0)
79  // (1, 0, 0)
80  // (2, 0, 0)
81  // (0, 1, 0)
82  // (1, 1, 0)
83  // (2, 1, 0)
84  \endcode
85  */
86 template<unsigned int N>
87 class MultiCoordinateIterator
88  : public CoupledScanOrderIterator<N>
89 {
90  public:
91  typedef CoupledScanOrderIterator<N> base_type;
92 
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;
97 
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;
104 
105  MultiCoordinateIterator()
106  : base_type(handle_type())
107  {}
108 
109  explicit MultiCoordinateIterator(shape_type const & shape)
110  : base_type(handle_type(shape))
111  {}
112 
113  explicit MultiCoordinateIterator(shape_type const & start, shape_type const & end)
114  : base_type(handle_type(end))
115  {
116  this->restrictToSubarray(start, end);
117  }
118 
119  template<class DirectedTag>
120  explicit MultiCoordinateIterator(GridGraph<N, DirectedTag> const & g)
121  : base_type(handle_type(g.shape()))
122  {}
123 
124 
125  template<class DirectedTag>
126  explicit MultiCoordinateIterator(GridGraph<N, DirectedTag> const & g, const typename GridGraph<N, DirectedTag>::Node & node)
127  : base_type(handle_type(g.shape()))
128  {
129  if( isInside(g,node))
130  (*this)+=node;
131  else
132  *this=this->getEndIterator();
133  }
134 
135 
136 
137  // dereferencing the iterator yields the coordinate object
138  // (used as vertex_descriptor)
139  reference operator*()
140  {
141  return this->template get<0>();
142  }
143 
144  const_reference operator*() const
145  {
146  return this->template get<0>();
147  }
148 
149  operator value_type() const
150  {
151  return *(*this);
152  }
153 
154  pointer operator->()
155  {
156  return &this->template get<0>();
157  }
158 
159  const_pointer operator->() const
160  {
161  return &this->template get<0>();
162  }
163 
164  value_type operator[](MultiArrayIndex i) const
165  {
166  return *(MultiCoordinateIterator(*this) += i);
167  }
168 
169  MultiCoordinateIterator & operator++()
170  {
171  base_type::operator++();
172  return *this;
173  }
174 
175  MultiCoordinateIterator operator++(int)
176  {
177  MultiCoordinateIterator res(*this);
178  ++*this;
179  return res;
180  }
181 
182  MultiCoordinateIterator & operator+=(MultiArrayIndex i)
183  {
184  base_type::operator+=(i);
185  return *this;
186  }
187 
188  MultiCoordinateIterator & operator+=(const shape_type &coordOffset)
189  {
190  base_type::operator+=(coordOffset);
191  return *this;
192  }
193 
194  MultiCoordinateIterator & operator--()
195  {
196  base_type::operator--();
197  return *this;
198  }
199 
200  MultiCoordinateIterator operator--(int)
201  {
202  MultiCoordinateIterator res(*this);
203  --*this;
204  return res;
205  }
206 
207  MultiCoordinateIterator & operator-=(MultiArrayIndex i)
208  {
209  return operator+=(-i);
210  }
211 
212  MultiCoordinateIterator & operator-=(const shape_type &coordOffset)
213  {
214  return operator+=(-coordOffset);
215  }
216 
217  MultiCoordinateIterator getEndIterator() const
218  {
219  return MultiCoordinateIterator(base_type::getEndIterator());
220  }
221 
222  MultiCoordinateIterator operator+(MultiArrayIndex d) const
223  {
224  return MultiCoordinateIterator(*this) += d;
225  }
226 
227  MultiCoordinateIterator operator-(MultiArrayIndex d) const
228  {
229  return MultiCoordinateIterator(*this) -= d;
230  }
231 
232  MultiCoordinateIterator operator+(const shape_type &coordOffset) const
233  {
234  return MultiCoordinateIterator(*this) += coordOffset;
235  }
236 
237  MultiCoordinateIterator operator-(const shape_type &coordOffset) const
238  {
239  return MultiCoordinateIterator(*this) -= coordOffset;
240  }
241 
242  MultiArrayIndex operator-(const MultiCoordinateIterator & other) const
243  {
244  return base_type::operator-(other);
245  }
246 
247  protected:
248  MultiCoordinateIterator(base_type const & base)
249  : base_type(base)
250  {}
251 };
252 
253  /** \brief Sequential iterator for MultiArrayView.
254 
255  This iterator provides STL-compatible random access iterator functionality for arbitrary
256  \ref MultiArrayView instances, regardless of their shapes and strides. The
257  class uses an implementation that minimizes speed penalties that could result from
258  non-trivial strides. The <i>scan-order</i> is defined such that dimensions are iterated
259  from front to back (first to last).
260 
261  You normally construct instances of this class by calling \ref MultiArrayView::begin()
262  and \ref MultiArrayView::end().
263 
264  The iterator supports all functions listed in the STL documentation for
265  <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterators</a>.
266 
267  <b>\#include</b> <vigra/multi_iterator.hxx><br/>
268  Namespace: vigra
269  */
270 template <unsigned int N, class V, class REFERENCE, class POINTER>
271 class StridedScanOrderIterator
272  : public CoupledIteratorType<N, V>::type
273 {
274  public:
275  typedef typename CoupledIteratorType<N, V>::type base_type;
276  typedef typename base_type::value_type handle_type;
277 
278  typedef typename base_type::shape_type shape_type;
279  typedef typename base_type::difference_type difference_type;
280  typedef StridedScanOrderIterator iterator;
281  typedef std::random_access_iterator_tag iterator_category;
282 
283  typedef typename detail::ResolveChunkedMemory<V>::type T;
284  typedef T value_type;
285  typedef REFERENCE reference;
286  typedef T const & const_reference;
287  typedef POINTER pointer;
288  typedef T const * const_pointer;
289 
290  StridedScanOrderIterator()
291  : base_type()
292  {}
293 
294  template <class S>
295  explicit StridedScanOrderIterator(MultiArrayView<N, T, S> const & view)
296  : base_type(createCoupledIterator(view))
297  {}
298 
299  StridedScanOrderIterator(POINTER p, shape_type const & shape, shape_type const & strides)
300  : base_type(createCoupledIterator(MultiArrayView<N, T, StridedArrayTag>(shape, strides, const_cast<T *>(p))))
301  {}
302 
303  StridedScanOrderIterator(handle_type const & handle)
304  : base_type(handle)
305  {}
306 
307  reference operator*()
308  {
309  return this->template get<1>();
310  }
311 
312  const_reference operator*() const
313  {
314  return this->template get<1>();
315  }
316 
317  pointer operator->()
318  {
319  return &this->template get<1>();
320  }
321 
322  const_pointer operator->() const
323  {
324  return &this->template get<1>();
325  }
326 
327  reference operator[](MultiArrayIndex i)
328  {
329  return *(StridedScanOrderIterator(*this) += i);
330  }
331 
332  const_reference operator[](MultiArrayIndex i) const
333  {
334  return *(StridedScanOrderIterator(*this) += i);
335  }
336 
337  reference operator[](const shape_type& coordOffset)
338  {
339  return *(StridedScanOrderIterator(*this) += coordOffset);
340  }
341 
342  const_reference operator[](const shape_type& coordOffset) const
343  {
344  return *(StridedScanOrderIterator(*this) += coordOffset);
345  }
346 
347  StridedScanOrderIterator & operator++()
348  {
349  base_type::operator++();
350  return *this;
351  }
352 
353  StridedScanOrderIterator operator++(int)
354  {
355  StridedScanOrderIterator res(*this);
356  ++*this;
357  return res;
358  }
359 
360  StridedScanOrderIterator & operator+=(MultiArrayIndex i)
361  {
363  return *this;
364  }
365 
366  StridedScanOrderIterator & operator+=(const shape_type &coordOffset)
367  {
368  base_type::operator+=(coordOffset);
369  return *this;
370  }
371 
372  StridedScanOrderIterator & operator--()
373  {
374  base_type::operator--();
375  return *this;
376  }
377 
378  StridedScanOrderIterator operator--(int)
379  {
380  StridedScanOrderIterator res(*this);
381  --*this;
382  return res;
383  }
384 
385  StridedScanOrderIterator & operator-=(MultiArrayIndex i)
386  {
387  return operator+=(-i);
388  }
389 
390  StridedScanOrderIterator & operator-=(const shape_type &coordOffset)
391  {
392  return operator+=(-coordOffset);
393  }
394 
395  StridedScanOrderIterator getEndIterator() const
396  {
397  return StridedScanOrderIterator(base_type::getEndIterator());
398  }
399 
400  StridedScanOrderIterator operator+(MultiArrayIndex d) const
401  {
402  return StridedScanOrderIterator(*this) += d;
403  }
404 
405  StridedScanOrderIterator operator-(MultiArrayIndex d) const
406  {
407  return StridedScanOrderIterator(*this) -= d;
408  }
409 
410  MultiArrayIndex operator-(StridedScanOrderIterator const & other) const
411  {
412  return base_type::operator-(other);
413  }
414 
415  StridedScanOrderIterator operator+(const shape_type &coordOffset) const
416  {
417  return StridedScanOrderIterator(*this) += coordOffset;
418  }
419 
420  StridedScanOrderIterator operator-(const shape_type &coordOffset) const
421  {
422  return StridedScanOrderIterator(*this) -= coordOffset;
423  }
424 
425  MultiArrayIndex index() const
426  {
427  return this->scanOrderIndex();
428  }
429 
430  StridedScanOrderIterator &
431  restrictToSubarray(shape_type const & start, shape_type const & stop)
432  {
433  base_type::restrictToSubarray(start, stop);
434  return *this;
435  }
436 
437  protected:
438  StridedScanOrderIterator(base_type const & base)
439  : base_type(base)
440  {}
441 };
442 
443 //@}
444 
445 /** \page MultiIteratorPage Multi-dimensional Array Iterators
446 
447 General iterators for arrays of arbitrary dimension.
448 
449 <p>
450 <UL style="list-style-image:url(documents/bullet.gif)">
451 <LI> \ref vigra::MultiArrayShape
452  <BR>&nbsp;&nbsp;&nbsp;<em>Difference type for \ref vigra::MultiArrayView or \ref vigra::MultiIterator</em>
453 <LI> \ref vigra::MultiIterator
454  <BR>&nbsp;&nbsp;&nbsp;<em>Iterator for unstrided \ref vigra::MultiArrayView</em>
455 <LI> \ref vigra::StridedMultiIterator
456  <BR>&nbsp;&nbsp;&nbsp;<em>Iterator for strided \ref vigra::MultiArrayView</em>
457 <LI> \ref vigra::StridedScanOrderIterator
458  <BR>&nbsp;&nbsp;&nbsp;<em>STL-compatible random access iterator for \ref vigra::MultiArrayView</em>
459 <LI> \ref vigra::CoupledScanOrderIterator
460  <BR>&nbsp;&nbsp;&nbsp;<em>Iterate over multiple images simultaneously in scan order</em>
461 </UL>
462 </p>
463 
464 <p>
465  The Multidimensional Iterator concept allows navigation on arrays
466  of arbitrary dimension. It provides two modes of iteration:
467  <em>direct traversal</em>, and <em>hierarchical traversal</em>.
468  In general, hierarchical traversal will be faster, while only
469  direct traversal allows for true random access in all dimensions.
470  Via the <tt>dim<K>()</tt> function, operations applying to a particular
471  dimension can be used in the direct traversal mode. In contrast,
472  direct traversal functions should not be used in the hierarchical mode
473  because the hierarchical functions are only well-defined if the
474  iterator points to element 0 in all dimensions below its current dimension.
475  The current dimension of a <tt>MultiIterator<N, ...></tt> is <tt>N-1</tt>.
476 </p>
477 <h3>General Requirements for MultiIterator</h3>
478 <p>
479 <table border=2 cellspacing=0 cellpadding=2 width="100%">
480 <tr><th colspan=2>
481  Local Types
482  </th><th>
483  Meaning
484  </th>
485 </tr>
486 <tr><td colspan=2>
487  <tt>MultiIterator::value_type</tt></td><td>the underlying arrays's pixel type</td>
488 </tr>
489 <tr><td colspan=2>
490  <tt>MultiIterator::reference</tt></td>
491  <td>the iterator's reference type (return type of <TT>*iter</TT>). Will be
492  <tt>value_type &</tt> for a mutable iterator, and convertible to
493  <tt>value_type const &</tt> for a const iterator.</td>
494 </tr>
495 <tr><td colspan=2>
496  <tt>MultiIterator::pointer</tt></td>
497  <td>the iterator's pointer type (return type of <TT>iter.operator->()</TT>). Will be
498  <tt>value_type *</tt> for a mutable iterator, and convertible to
499  <tt>value_type const *</tt> for a const iterator.</td>
500 </tr>
501 <tr><td colspan=2>
502  <tt>MultiIterator::iterator_category</tt></td>
503  <td>the iterator tag (<tt>vigra::multi_dimensional_traverser_tag</tt>)</td>
504 </tr>
505 <tr><th>
506  Operation
507  </th><th>
508  Result
509  </th><th>
510  Semantics
511  </th>
512 </tr>
513 <tr><td colspan=2>
514  <tt>MultiIterator k;</tt></td><td>default constructor</td>
515 </tr>
516 <tr><td colspan=2>
517  <tt>MultiIterator k(i);</tt></td><td>copy constructor</td>
518 </tr>
519 <tr>
520  <td><tt>k = i</tt></td>
521  <td><tt>MultiIterator &</tt></td><td>assignment</td>
522 </tr>
523 <tr>
524  <td><tt>i == j</tt></td><td><tt>bool</tt></td>
525  <td>equality (iterators point to the same element)</td>
526 </tr>
527 <tr>
528  <td><tt>i != j</tt></td><td><tt>bool</tt></td>
529  <td>inequality (iterators don't point to the same element)</td>
530 </tr>
531 <tr>
532  <td><tt>*i</tt></td><td><tt>MultiIterator::reference</tt></td>
533  <td>access the current element</td>
534 </tr>
535 <tr>
536  <td><tt>i->member()</tt></td><td>depends on operation</td>
537  <td>call member function of underlying pixel type via <tt>operator-></tt> of iterator</td>
538 </tr>
539 </table>
540 </p>
541 <h3>Requirements for Direct Traversal</h3>
542 <p>
543 <table border=2 cellspacing=0 cellpadding=2 width="100%">
544 <tr><th colspan=2>
545  Local Types
546  </th><th>
547  Meaning
548  </th>
549 </tr>
550 <tr><td colspan=2>
551  <tt>MultiIterator::multi_difference_type</tt></td>
552  <td>the iterator's multi-dimensional difference type (<TT>TinyVector<MultiArrayIndex, N></TT>)</td>
553 </tr>
554 <tr><th>
555  Operation
556  </th><th>
557  Result
558  </th><th>
559  Semantics
560  </th>
561 </tr>
562 <tr>
563  <td><tt>i += diff</tt></td><td><tt>MultiIterator &</tt></td>
564  <td>add offset to current position</td>
565 </tr>
566 <tr>
567  <td><tt>i -= diff</tt></td><td><tt>MultiIterator &</tt></td>
568  <td>subtract offset from current position</td>
569 </tr>
570 <tr>
571  <td><tt>i + diff</tt></td><td><tt>MultiIterator</tt></td>
572  <td>create traverser by adding offset</td>
573 </tr>
574 <tr>
575  <td><tt>i - diff</tt></td><td><tt>MultiIterator</tt></td>
576  <td>create traverser by subtracting offset</td>
577 </tr>
578 <tr>
579  <td><tt>i[diff]</tt></td><td><tt>MultiIterator::reference</tt></td>
580  <td>access element at offset <tt>diff</tt></td>
581 </tr>
582 <tr>
583  <td><tt>i.dim<K>()</tt></td><td><tt>MultiIterator<K+1, T, ...></tt></td>
584  <td>Access the traverser with the current dimension set to K. Typically used to call
585  navigation functions referring to a particular dimension.<br>
586  Example (assuming <tt>i, j</tt> are 3-dimensional):<br>
587  \code
588  i.dim<0>()++; // increment dimension 0
589  i.dim<1>()++; // increment dimension 1
590  i.dim<2>()++; // increment dimension 2
591 
592  j += MultiIterator::multi_difference_type(1,1,1); // same effect
593  \endcode
594  </td>
595 </tr>
596 <tr><td colspan=3>
597  <tt>i, j</tt> are of type <tt>MultiIterator</tt><br>
598  <tt>diff</tt> is of type <tt>MultiIterator::multi_difference_type</tt><br>
599  <tt>K</tt> is an integer compile-time constant
600  </td>
601 </tr>
602 </table>
603 </p>
604 <p>
605 Note that it is impossible to support an <tt>operator-</tt> between two iterators which returns
606 a <tt>MultiIterator::multi_difference_type</tt> because it is impossible to decide to which
607 dimension a difference applies. Consider for example, a 2-dimensional iterator <tt>i</tt>, and
608 let <tt>j = i + multi_difference_type(width, 0)</tt>, <tt>k = i + multi_difference_type(0,1)</tt>,
609 where <tt>width</tt> is the array's total width. In general, <tt>j</tt> and <tt>k</tt> point to
610 the same memory location, so that the two cases cannot easily be distinguished (it is possible,
611 but iterator performance will suffer significantly, as is experienced with
612 \ref vigra::ImageIterator where differencing is allowed).
613 </p>
614 
615 <h3>Requirements for Hierarchical Traversal</h3>
616 <p>
617 <table border=2 cellspacing=0 cellpadding=2 width="100%">
618 <tr><th colspan=2>
619  Local Types
620  </th><th>
621  Meaning
622  </th>
623 </tr>
624 <tr><td colspan=2>
625  <tt>MultiIterator::difference_type</tt></td>
626  <td>the iterator's difference type (<TT>MultiArrayIndex</TT>)</td>
627 </tr>
628 <tr><td colspan=2>
629  <tt>MultiIterator::next_type</tt></td><td>type of the next iterator
630  (referring to the next lower dimension) in the hierarchy</td>
631 </tr>
632 <tr><th>
633  Operation
634  </th><th>
635  Result
636  </th><th>
637  Semantics
638  </th>
639 </tr>
640 <tr>
641  <td><tt>++i</tt></td><td><tt>MultiIterator &</tt></td>
642  <td>pre-increment iterator in its current dimension</td>
643 </tr>
644 <tr>
645  <td><tt>i++</tt></td><td><tt>MultiIterator</tt></td>
646  <td>post-increment iterator in its current dimension</td>
647 </tr>
648 <tr>
649  <td><tt>--i</tt></td><td><tt>MultiIterator &</tt></td>
650  <td>pre-decrement iterator in its current dimension</td>
651 </tr>
652 <tr>
653  <td><tt>i--</tt></td><td><tt>MultiIterator</tt></td>
654  <td>post-decrement iterator in its current dimension</td>
655 </tr>
656 <tr>
657  <td><tt>i += d</tt></td><td><tt>MultiIterator &</tt></td>
658  <td>add <tt>d</tt> in current dimension</td>
659 </tr>
660 <tr>
661  <td><tt>i -= d</tt></td><td><tt>MultiIterator &</tt></td>
662  <td>subtract <tt>d</tt> in from dimension</td>
663 </tr>
664 <tr>
665  <td><tt>i + d</tt></td><td><tt>MultiIterator</tt></td>
666  <td>create new iterator by adding <tt>d</tt> in current dimension</td>
667 </tr>
668 <tr>
669  <td><tt>i - d</tt></td><td><tt>MultiIterator</tt></td>
670  <td>create new iterator by subtracting <tt>d</tt> in current dimension</td>
671 </tr>
672 <tr>
673  <td><tt>i - j</tt></td><td><tt>difference_type</tt></td>
674  <td>difference of <tt>i</tt> and <tt>j</tt> in the current dimension<br>
675  <em>Note:</em> The result of this operation is undefined if the iterator
676  doesn't point to element 0 in all dimensions below its current dimension.</td>
677 </tr>
678 <tr>
679  <td><tt>i < j</tt></td><td><tt>bool</tt></td>
680  <td><tt>i - j < 0</tt><br>
681  <em>Note:</em> The result of this operation is undefined if the iterator
682  doesn't point to element 0 in all dimensions below its current dimension.</td>
683 </tr>
684 <tr>
685  <td><tt>i[d]</tt></td><td><tt>MultiIterator::reference</tt></td>
686  <td>access element by adding offset <tt>d</tt> in current dimension</td>
687 </tr>
688 <tr>
689  <td><tt>i.begin()</tt></td><td><tt>next_type</tt></td>
690  <td>create the hierarchical iterator pointing to the first element in the
691  next lower dimension.<br>
692  <em>Note:</em> The result of this operation is undefined if the iterator
693  doesn't point to element 0 in all dimensions below its current dimension.<br>
694  Usage:<br>
695  \code
696  MultiIterator<3, int> i3 = ..., end3 = ...;
697  for(; i3 != end3; ++i3)
698  {
699  MultiIterator<3, int>::next_type i2 = i3.begin(), end2 = i3.end();
700  for(; i2 != end2; ++i2)
701  {
702  MultiIterator<3, int>::next_type::next_type i1 = i2.begin(), end1 = i2.end();
703  for(; i1 != end1; ++i1)
704  {
705  ... // do something with the current element
706  }
707  }
708  }
709 
710  \endcode
711  </td>
712 </tr>
713 <tr>
714  <td><tt>i.end()</tt></td><td><tt>next_type</tt></td>
715  <td>create the hierarchical iterator pointing to the past-the-end location in the
716  next lower dimension.<br>
717  <em>Note:</em> The result of this operation is undefined if the iterator
718  doesn't point to element 0 in all dimensions below its current dimension.</td>
719 </tr>
720 <tr><td colspan=3>
721  <tt>i, j</tt> are of type <tt>MultiIterator</tt><br>
722  <tt>d</tt> is of type <tt>MultiIterator::difference_type</tt>
723  </td>
724 </tr>
725 </table>
726 </p>
727 
728 */
729 
730 /** \addtogroup MultiIteratorGroup
731 */
732 //@{
733 
734 template <class POINTER>
735 struct MultiIteratorStrideTraits
736 {
737  typedef MultiArrayIndex stride_type;
738  typedef const stride_type* stride_array_type;
739  typedef stride_array_type shape_array_type;
740  static stride_array_type shift(stride_array_type s, unsigned d)
741  {
742  return s + d;
743  }
744 };
745 
746 /********************************************************/
747 /* */
748 /* MultiIterator */
749 /* */
750 /********************************************************/
751 
752 /********************************************************/
753 /* */
754 /* MultiIterator<1> */
755 /* */
756 /********************************************************/
757 
758 //
759 template <class T, class REFERENCE, class POINTER>
760 class MultiIterator<1, T, REFERENCE, POINTER>
761 {
762  public:
763  enum { level = 0 };
764  typedef T value_type;
765  typedef REFERENCE reference;
766  typedef const value_type &const_reference;
767  typedef POINTER pointer;
768  typedef const value_type *const_pointer;
769  typedef typename MultiArrayShape<1>::type multi_difference_type;
770  typedef MultiIteratorStrideTraits<POINTER> stride_traits;
771  typedef typename stride_traits::stride_type difference_type;
772  typedef typename stride_traits::stride_array_type difference_array_type;
773  typedef typename stride_traits::shape_array_type shape_array_type;
774  typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
775  typedef std::random_access_iterator_tag iterator_category;
776 
777  protected:
778  pointer m_ptr;
779 
780  public:
781  MultiIterator ()
782  : m_ptr (0)
783  {}
784 
785  MultiIterator (pointer ptr,
786  const difference_array_type &,
787  const shape_array_type &)
788  : m_ptr (ptr)
789  {}
790 
791  void operator++ ()
792  {
793  ++m_ptr;
794  }
795 
796  void operator-- ()
797  {
798  --m_ptr;
799  }
800 
801  MultiIterator operator++ (int)
802  {
803  MultiIterator ret = *this;
804  ++(*this);
805  return ret;
806  }
807 
808  MultiIterator operator-- (int)
809  {
810  MultiIterator ret = *this;
811  --(*this);
812  return ret;
813  }
814 
815  MultiIterator &operator+= (difference_type n)
816  {
817  m_ptr += n;
818  return *this;
819  }
820 
821  MultiIterator & operator+= (multi_difference_type const & d)
822  {
823  m_ptr += d[level];
824  return *this;
825  }
826 
827  MultiIterator &operator-= (difference_type n)
828  {
829  m_ptr -= n;
830  return *this;
831  }
832 
833  MultiIterator & operator-= (multi_difference_type const & d)
834  {
835  m_ptr -= d[level];
836  return *this;
837  }
838 
839  MultiIterator operator+ (difference_type n) const
840  {
841  MultiIterator ret = *this;
842  ret += n;
843  return ret;
844  }
845 
846  MultiIterator operator+ (multi_difference_type const & d) const
847  {
848  MultiIterator ret = *this;
849  ret += d;
850  return ret;
851  }
852 
853  difference_type operator- (MultiIterator const & d) const
854  {
855  return (m_ptr - d.m_ptr);
856  }
857 
858  MultiIterator operator- (difference_type n) const
859  {
860  MultiIterator ret = *this;
861  ret -= n;
862  return ret;
863  }
864 
865  MultiIterator operator- (multi_difference_type const & d) const
866  {
867  MultiIterator ret = *this;
868  ret -= d;
869  return ret;
870  }
871 
872  reference operator[] (difference_type n) const
873  {
874  return m_ptr [n];
875  }
876 
877  reference operator[] (multi_difference_type const & d) const
878  {
879  return m_ptr [d[level]];
880  }
881 
882  reference operator* () const
883  {
884  return *m_ptr;
885  }
886 
887  pointer get () const
888  {
889  return m_ptr;
890  }
891 
892  pointer operator->() const
893  {
894  return &(operator*());
895  }
896 
897  bool operator!= (const MultiIterator &rhs) const
898  {
899  return m_ptr != rhs.m_ptr;
900  }
901 
902  bool operator== (const MultiIterator &rhs) const
903  {
904  return m_ptr == rhs.m_ptr;
905  }
906 
907  bool operator< (const MultiIterator &rhs) const
908  {
909  return m_ptr < rhs.m_ptr;
910  }
911 
912  bool operator<= (const MultiIterator &rhs) const
913  {
914  return m_ptr <= rhs.m_ptr;
915  }
916 
917  bool operator> (const MultiIterator &rhs) const
918  {
919  return m_ptr > rhs.m_ptr;
920  }
921 
922  bool operator>= (const MultiIterator &rhs) const
923  {
924  return m_ptr >= rhs.m_ptr;
925  }
926 
927  iterator iteratorForDimension(unsigned int d) const
928  {
929  vigra_precondition(d == 0,
930  "MultiIterator<1>::iteratorForDimension(d): d == 0 required");
931  const difference_type stride = 1;
932  return iterator(m_ptr, &stride, 0);
933  }
934 
935  template <unsigned int K>
936  MultiIterator<K+1, T, REFERENCE, POINTER> &
937  dim()
938  {
939  return *this;
940  }
941 
942  MultiIterator<1, T, REFERENCE, POINTER> &
943  dim0() { return *this; }
944 
945  protected:
946 
947  difference_type
948  total_stride(typename multi_difference_type::const_iterator d) const
949  {
950  return d[level];
951  }
952 };
953 
954 /********************************************************/
955 /* */
956 /* MultiIterator<2> */
957 /* */
958 /********************************************************/
959 
960 //
961 template <class T, class REFERENCE, class POINTER>
962 class MultiIterator<2, T, REFERENCE, POINTER>
963 #ifndef DOXYGEN // doxygen doesn't understand this inheritance
964 : public MultiIterator<1, T, REFERENCE, POINTER>
965 #endif
966 {
967  public:
968 
969  typedef MultiIterator<1, T, REFERENCE, POINTER> base_type;
970  enum { level = 1 };
971  typedef T value_type;
972  typedef REFERENCE reference;
973  typedef const value_type &const_reference;
974  typedef POINTER pointer;
975  typedef const value_type *const_pointer;
977  typedef MultiIteratorStrideTraits<POINTER> stride_traits;
978  typedef typename stride_traits::stride_type difference_type;
979  typedef typename stride_traits::stride_array_type difference_array_type;
980  typedef typename stride_traits::shape_array_type shape_array_type;
981  typedef base_type next_type;
982  typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
983  typedef multi_dimensional_traverser_tag iterator_category;
984 
985  protected:
986  difference_array_type m_stride;
987  shape_array_type m_shape;
988 
989  public:
990  /* use default copy constructor and assignment operator */
991 
992  MultiIterator ()
993  : base_type (),
994  m_stride (0), m_shape (0)
995  {}
996 
997  MultiIterator (pointer ptr,
998  const difference_array_type & stride,
999  const shape_array_type & shape)
1000  : base_type (ptr, stride, shape),
1001  m_stride (stride), m_shape (shape)
1002  {}
1003 
1004  void operator++ ()
1005  {
1006  this->m_ptr += m_stride [level];
1007  }
1008 
1009  void operator-- ()
1010  {
1011  this->m_ptr -= m_stride [level];
1012  }
1013 
1015  {
1016  MultiIterator ret = *this;
1017  ++(*this);
1018  return ret;
1019  }
1020 
1022  {
1023  MultiIterator ret = *this;
1024  --(*this);
1025  return ret;
1026  }
1027 
1028  MultiIterator & operator+= (difference_type n)
1029  {
1030  this->m_ptr += n * m_stride [level];
1031  return *this;
1032  }
1033 
1034  MultiIterator & operator+= (multi_difference_type const & d)
1035  {
1036  this->m_ptr += total_stride(d.begin());
1037  return *this;
1038  }
1039 
1040  MultiIterator &operator-= (difference_type n)
1041  {
1042  this->m_ptr -= n * m_stride [level];
1043  return *this;
1044  }
1045 
1046  MultiIterator & operator-= (multi_difference_type const & d)
1047  {
1048  this->m_ptr -= total_stride(d.begin());
1049  return *this;
1050  }
1051 
1052  MultiIterator operator+ (difference_type n) const
1053  {
1054  MultiIterator ret = *this;
1055  ret += n;
1056  return ret;
1057  }
1058 
1059  MultiIterator operator+ (multi_difference_type const & d) const
1060  {
1061  MultiIterator ret = *this;
1062  ret += d;
1063  return ret;
1064  }
1065 
1066  difference_type operator- (MultiIterator const & d) const
1067  {
1068  return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1069  }
1070 
1071  MultiIterator operator- (difference_type n) const
1072  {
1073  MultiIterator ret = *this;
1074  ret -= n;
1075  return ret;
1076  }
1077 
1078  MultiIterator operator- (multi_difference_type const & d) const
1079  {
1080  MultiIterator ret = *this;
1081  ret -= d;
1082  return ret;
1083  }
1084 
1085  reference operator[] (difference_type n) const
1086  {
1087  return this->m_ptr [n*m_stride [level]];
1088  }
1089 
1090  reference operator[] (multi_difference_type const & d) const
1091  {
1092  return this->m_ptr [total_stride(d.begin())];
1093  }
1094 
1095  next_type begin () const
1096  {
1097  return *this;
1098  }
1099 
1100  next_type end () const
1101  {
1102  next_type ret = *this;
1103  ret += m_shape [level-1];
1104  return ret;
1105  }
1106 
1107  iterator iteratorForDimension(unsigned int d) const
1108  {
1109  vigra_precondition(d <= level,
1110  "MultiIterator<N>::iteratorForDimension(d): d < N required");
1111  return iterator(this->m_ptr, stride_traits::shift(m_stride, d), 0);
1112  }
1113 
1114  template <unsigned int K>
1115  MultiIterator<K+1, T, REFERENCE, POINTER> &
1116  dim()
1117  {
1118  return *this;
1119  }
1120 
1121  MultiIterator<1, T, REFERENCE, POINTER> &
1122  dim0() { return *this; }
1123  MultiIterator<2, T, REFERENCE, POINTER> &
1124  dim1() { return *this; }
1125 
1126  protected:
1127 
1128  difference_type
1129  total_stride(typename multi_difference_type::const_iterator d) const
1130  {
1131  return d[level]*m_stride[level] + base_type::total_stride(d);
1132  }
1133 };
1134 
1135 /********************************************************/
1136 /* */
1137 /* MultiIterator<N> */
1138 /* */
1139 /********************************************************/
1140 
1141 /** \brief A multi-dimensional hierarchical iterator to be used with
1142  \ref vigra::MultiArrayView if it is not strided.
1143 
1144  See \ref MultiIteratorPage for further documentation.
1145 
1146  <b>\#include</b> <vigra/multi_iterator.hxx> <br>
1147  Namespace: vigra
1148 */
1149 template <unsigned int N, class T, class REFERENCE, class POINTER>
1150 class MultiIterator
1151 #ifndef DOXYGEN // doxygen doesn't understand this inheritance
1152 : public MultiIterator<N-1, T, REFERENCE, POINTER>
1153 #endif
1154 {
1155 public:
1156 
1157  /** the type of the parent in the inheritance hierarchy.
1158  */
1159  typedef MultiIterator<N-1, T, REFERENCE, POINTER> base_type;
1160 
1161  /** the iterator's level in the dimension hierarchy
1162  */
1163  enum { level = N-1 };
1164 
1165  /** the iterator's value type
1166  */
1167  typedef T value_type;
1168 
1169  /** reference type (result of operator[])
1170  */
1171  typedef REFERENCE reference;
1172 
1173  /** const reference type (result of operator[] const)
1174  */
1175  typedef const value_type &const_reference;
1176 
1177  /** pointer type
1178  */
1179  typedef POINTER pointer;
1180 
1181  /** const pointer type
1182  */
1183  typedef const value_type *const_pointer;
1184 
1185  /** multi difference type
1186  (used for offsetting along all axes simultaneously)
1187  */
1189 
1190  /** difference type (used for offsetting)
1191  */
1192 #ifndef DOXYGEN
1193  typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1194  typedef typename stride_traits::stride_type difference_type;
1195  typedef typename stride_traits::stride_array_type difference_array_type;
1196  typedef typename stride_traits::shape_array_type shape_array_type;
1197 #else
1199 #endif
1200 
1201  /** the MultiIterator for the next lower dimension.
1202  */
1203  typedef base_type next_type;
1204 
1205  /** the 1-dimensional iterator for this iterator hierarchy
1206  (result of iteratorForDimension()).
1207  */
1209 
1210  /** the iterator tag (image traverser)
1211  */
1212  typedef multi_dimensional_traverser_tag iterator_category;
1213 
1214  /* use default copy constructor and assignment operator */
1215 
1216  /** default constructor.
1217  */
1219  {}
1220 
1221  /** construct from pointer, strides (offset of a sample to the
1222  next) for every dimension, and the shape.
1223  */
1224  MultiIterator (pointer ptr,
1225  const difference_array_type & stride,
1226  const shape_array_type & shape)
1227  : base_type (ptr, stride, shape)
1228  {}
1229 
1230 
1231  /** prefix-increment the iterator in its current dimension
1232  */
1234  {
1235  this->m_ptr += this->m_stride [level];
1236  }
1237 
1238  /** prefix-decrement the iterator in its current dimension
1239  */
1241  {
1242  this->m_ptr -= this->m_stride [level];
1243  }
1244 
1245  /** postfix-increment the iterator in its current dimension
1246  */
1248  {
1249  MultiIterator ret = *this;
1250  ++(*this);
1251  return ret;
1252  }
1253 
1254  /** postfix-decrement the iterator in its current dimension
1255  */
1257  {
1258  MultiIterator ret = *this;
1259  --(*this);
1260  return ret;
1261  }
1262 
1263  /** increment the iterator in its current dimension
1264  by the given value.
1265  */
1266  MultiIterator & operator+= (difference_type n)
1267  {
1268  this->m_ptr += n * this->m_stride [level];
1269  return *this;
1270  }
1271 
1272  /** increment the iterator in all dimensions
1273  by the given offset.
1274  */
1275  MultiIterator & operator+= (multi_difference_type const & d)
1276  {
1277  this->m_ptr += total_stride(d.begin());
1278  return *this;
1279  }
1280 
1281  /** decrement the iterator in its current dimension
1282  by the given value.
1283  */
1284  MultiIterator & operator-= (difference_type n)
1285  {
1286  this->m_ptr -= n * this->m_stride [level];
1287  return *this;
1288  }
1289 
1290  /** decrement the iterator in all dimensions
1291  by the given offset.
1292  */
1293  MultiIterator & operator-= (multi_difference_type const & d)
1294  {
1295  this->m_ptr -= total_stride(d.begin());
1296  return *this;
1297  }
1298 
1299  /** addition within current dimension
1300  */
1301  MultiIterator operator+ (difference_type n) const
1302  {
1303  MultiIterator ret = *this;
1304  ret += n;
1305  return ret;
1306  }
1307 
1308  /** addition along all dimensions
1309  */
1310  MultiIterator operator+ (multi_difference_type const & d) const
1311  {
1312  MultiIterator ret = *this;
1313  ret += d;
1314  return ret;
1315  }
1316 
1317  /** difference of two iterators in the current dimension.
1318  The result of this operation is undefined if the iterator
1319  doesn't point to element 0 in all dimensions below its current dimension.
1320  */
1321  difference_type operator- (MultiIterator const & d) const
1322  {
1323  return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1324  }
1325 
1326  /** subtraction within current dimension
1327  */
1328  MultiIterator operator- (difference_type n) const
1329  {
1330  MultiIterator ret = *this;
1331  ret -= n;
1332  return ret;
1333  }
1334 
1335  /** subtraction along all dimensions
1336  */
1337  MultiIterator operator- (multi_difference_type const & d) const
1338  {
1339  MultiIterator ret = *this;
1340  ret -= d;
1341  return ret;
1342  }
1343 
1344 #ifdef DOXYGEN /* documentation only: operators *, ->, ==, !=, <, <=, >, >= are inherited */
1345  /** derefenrence item
1346  */
1347  reference operator* () const;
1348 
1349  /** get address of current item
1350  */
1351  pointer get () const;
1352 
1353  /** call method of current item
1354  */
1355  pointer operator->() const;
1356 
1357  /** inequality. True if iterators reference different items.
1358  */
1359  bool operator!= (const MultiIterator &rhs) const;
1360 
1361  /** equality. True if iterators reference the same items.
1362  */
1363  bool operator== (const MultiIterator &rhs) const;
1364 
1365  /** less than.
1366  */
1367  bool operator< (const MultiIterator &rhs) const;
1368 
1369  /** less or equal.
1370  */
1371  bool operator<= (const MultiIterator &rhs) const;
1372 
1373  /** greater than.
1374  */
1375  bool operator> (const MultiIterator &rhs) const;
1376 
1377  /** greater or equal.
1378  */
1379  bool operator>= (const MultiIterator &rhs) const;
1380 #endif
1381 
1382  /** access the array element at the given offset in
1383  the current dimension.
1384  */
1385  reference operator[] (difference_type n) const
1386  {
1387  return this->m_ptr [n* this->m_stride [level]];
1388  }
1389 
1390  /** access the array element at the given offset.
1391  */
1392  reference operator[] (multi_difference_type const & d) const
1393  {
1394  return this->m_ptr [total_stride(d.begin())];
1395  }
1396 
1397  /** Return the (N-1)-dimensional multi-iterator that points to
1398  the first (N-1)-dimensional subarray of the
1399  N-dimensional array this iterator is referring to.
1400  The result is only valid if this iterator refers to location
1401  0 in <em>all</em> dimensions below its current dimension N,
1402  otherwise it is undefined. Usage:
1403 
1404  \code
1405 
1406  MultiIterator<2, int> outer = ...; // this iterator
1407 
1408  MultiIterator<2, int>::next_type inner = outer.begin();
1409  for(; inner != outer.end(); ++inner)
1410  {
1411  // manipulate current 1D subimage
1412  }
1413  \endcode
1414  */
1415  next_type begin () const
1416  {
1417  return *this;
1418  }
1419 
1420  /** Return the (N-1)-dimensional multi-iterator that points beyond
1421  the last (N-1)-dimensional subarray of the
1422  N-dimensional array this iterator is referring to.
1423  The result is only valid if this iterator refers to location
1424  0 in <em>all</em> dimensions below its current dimension N,
1425  otherwise it is undefined.
1426  */
1427  next_type end () const
1428  {
1429  next_type ret = *this;
1430  ret += this->m_shape [level-1];
1431  return ret;
1432  }
1433 
1434  /** Get a 1-dimensional, STL-compatible iterator for the
1435  given dimension, pointing to the current element of <TT>this</TT>.
1436  Usage:
1437 
1438  \code
1439 
1440  MultiIterator<3, int> outer = ...; // this iterator
1441 
1442  MultiIterator<3, int>::iterator i = outer.iteratorForDimension(1);
1443  MultiIterator<3, int>::iterator end = i + height;
1444  for(; i != end; ++i)
1445  {
1446  // go down the current column starting at the location of 'outer'
1447  }
1448  \endcode
1449  */
1450  iterator iteratorForDimension(unsigned int d) const
1451  {
1452  vigra_precondition(d <= level,
1453  "MultiIterator<N>::iteratorForDimension(d): d < N required");
1454  return iterator(this->m_ptr, stride_traits::shift(this->m_stride, d),0);
1455  }
1456  /** Return the multi-iterator that operates on dimension K in order
1457  to manipulate this dimension directly. Usage:
1458 
1459  \code
1460 
1461  MultiIterator<3, int> i3 = ...;
1462 
1463  i3.template dim<2>()++; // increment outer dimension
1464  i3.template dim<0>()++; // increment inner dimension
1465  \endcode
1466 
1467  For convenience, the same functionality is also available
1468  as <tt>dim0()</tt>, <tt>dim1()</tt> etc. up to <tt>dim4()</tt>:
1469 
1470  \code
1471 
1472  MultiIterator<3, int> i3 = ...;
1473 
1474  i3.dim2()++; // increment outer dimension
1475  i3.dim0()++; // increment inner dimension
1476  \endcode
1477  */
1478  template <unsigned int K>
1481  {
1482  return *this;
1483  }
1484 
1486  dim0() { return *this; }
1487  MultiIterator<2, T, REFERENCE, POINTER> &
1488  dim1() { return *this; }
1489  MultiIterator<3, T, REFERENCE, POINTER> &
1490  dim2() { return *this; }
1491  MultiIterator<4, T, REFERENCE, POINTER> &
1492  dim3() { return *this; }
1493  MultiIterator<5, T, REFERENCE, POINTER> &
1494  dim4() { return *this; }
1495 
1496  protected:
1497 
1498  difference_type
1499  total_stride(typename multi_difference_type::const_iterator d) const
1500  {
1501  return d[level]*this->m_stride[level] + base_type::total_stride(d);
1502  }
1503 
1504 };
1505 
1506 /********************************************************/
1507 /* */
1508 /* StridedMultiIterator */
1509 /* */
1510 /********************************************************/
1511 
1512 /********************************************************/
1513 /* */
1514 /* StridedMultiIterator<1> */
1515 /* */
1516 /********************************************************/
1517 
1518 //
1519 template <class T, class REFERENCE, class POINTER>
1520 class StridedMultiIterator<1, T, REFERENCE, POINTER>
1521 {
1522  public:
1523  enum { level = 0 };
1524  typedef T value_type;
1525  typedef REFERENCE reference;
1526  typedef const value_type &const_reference;
1527  typedef POINTER pointer;
1528  typedef const value_type *const_pointer;
1529  typedef typename MultiArrayShape<1>::type multi_difference_type;
1530  typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1531  typedef typename stride_traits::stride_type difference_type;
1532  typedef typename stride_traits::stride_array_type difference_array_type;
1533  typedef typename stride_traits::shape_array_type shape_array_type;
1534  typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
1535  typedef std::random_access_iterator_tag iterator_category;
1536 
1537  protected:
1538  pointer m_ptr;
1539  difference_type m_stride;
1540 
1541  /* use default copy constructor and assignment operator */
1542 
1543  public:
1545  : m_ptr (0), m_stride (0)
1546  {}
1547 
1548  StridedMultiIterator (pointer ptr,
1549  const difference_array_type & stride,
1550  const shape_array_type &)
1551  : m_ptr (ptr), m_stride (stride [level])
1552  {}
1553 
1554  void operator++ ()
1555  {
1556  m_ptr += m_stride;
1557  }
1558 
1559  void operator-- ()
1560  {
1561  m_ptr -= m_stride;
1562  }
1563 
1565  {
1566  StridedMultiIterator ret = *this;
1567  ++(*this);
1568  return ret;
1569  }
1570 
1572  {
1573  StridedMultiIterator ret = *this;
1574  --(*this);
1575  return ret;
1576  }
1577 
1578  StridedMultiIterator &operator+= (difference_type n)
1579  {
1580  m_ptr += n * m_stride;
1581  return *this;
1582  }
1583 
1584  StridedMultiIterator & operator+= (multi_difference_type const & d)
1585  {
1586  m_ptr += d[level] * m_stride;
1587  return *this;
1588  }
1589 
1590  StridedMultiIterator &operator-= (difference_type n)
1591  {
1592  m_ptr -= n * m_stride;
1593  return *this;
1594  }
1595 
1596  StridedMultiIterator & operator-= (multi_difference_type const & d)
1597  {
1598  m_ptr -= d[level] * m_stride;
1599  return *this;
1600  }
1601 
1602  StridedMultiIterator operator+ (difference_type n) const
1603  {
1604  StridedMultiIterator ret = *this;
1605  ret += n;
1606  return ret;
1607  }
1608 
1609  StridedMultiIterator operator+ (multi_difference_type const & d) const
1610  {
1611  StridedMultiIterator ret = *this;
1612  ret += d;
1613  return ret;
1614  }
1615 
1616  difference_type operator- (StridedMultiIterator const & d) const
1617  {
1618  return (m_ptr - d.m_ptr) / m_stride;
1619  }
1620 
1621  StridedMultiIterator operator- (difference_type n) const
1622  {
1623  StridedMultiIterator ret = *this;
1624  ret -= n;
1625  return ret;
1626  }
1627 
1628  StridedMultiIterator operator- (multi_difference_type const & d) const
1629  {
1630  StridedMultiIterator ret = *this;
1631  ret -= d;
1632  return ret;
1633  }
1634 
1635  reference operator[] (difference_type n) const
1636  {
1637  return m_ptr [n*m_stride];
1638  }
1639 
1640  reference operator[] (multi_difference_type const & d) const
1641  {
1642  return m_ptr [d[level]*m_stride];
1643  }
1644 
1645  reference operator* () const
1646  {
1647  return *m_ptr;
1648  }
1649 
1650  pointer get () const
1651  {
1652  return m_ptr;
1653  }
1654 
1655  pointer operator->() const
1656  {
1657  return &(operator*());
1658  }
1659 
1660  bool operator!= (const StridedMultiIterator &rhs) const
1661  {
1662  return m_ptr != rhs.m_ptr;
1663  }
1664 
1665  bool operator== (const StridedMultiIterator &rhs) const
1666  {
1667  return m_ptr == rhs.m_ptr;
1668  }
1669 
1670  bool operator< (const StridedMultiIterator &rhs) const
1671  {
1672  return m_ptr < rhs.m_ptr;
1673  }
1674 
1675  bool operator<= (const StridedMultiIterator &rhs) const
1676  {
1677  return m_ptr <= rhs.m_ptr;
1678  }
1679 
1680  bool operator> (const StridedMultiIterator &rhs) const
1681  {
1682  return m_ptr > rhs.m_ptr;
1683  }
1684 
1685  bool operator>= (const StridedMultiIterator &rhs) const
1686  {
1687  return m_ptr >= rhs.m_ptr;
1688  }
1689 
1690  iterator iteratorForDimension(unsigned int d) const
1691  {
1692  vigra_precondition(d == 0,
1693  "StridedMultiIterator<1>::iteratorForDimension(d): d == 0 required");
1694  const difference_type stride = 1;
1695  return iterator(m_ptr, &stride, 0);
1696  }
1697 
1698  template <unsigned int K>
1699  StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
1700  dim()
1701  {
1702  return *this;
1703  }
1704 
1705  StridedMultiIterator<1, T, REFERENCE, POINTER> &
1706  dim0() { return *this; }
1707 
1708  protected:
1709 
1710  difference_type
1711  total_stride(typename multi_difference_type::const_iterator d) const
1712  {
1713  return d[level] * m_stride;
1714  }
1715 };
1716 
1717 /********************************************************/
1718 /* */
1719 /* StridedMultiIterator<2> */
1720 /* */
1721 /********************************************************/
1722 
1723 //
1724 template <class T, class REFERENCE, class POINTER>
1725 class StridedMultiIterator<2, T, REFERENCE, POINTER>
1726 #ifndef DOXYGEN // doxygen doesn't understand this inheritance
1727 : public StridedMultiIterator<1, T, REFERENCE, POINTER>
1728 #endif
1729 {
1730  public:
1731 
1732  typedef StridedMultiIterator<1, T, REFERENCE, POINTER> base_type;
1733  enum { level = 1 };
1734  typedef T value_type;
1735  typedef REFERENCE reference;
1736  typedef const value_type &const_reference;
1737  typedef POINTER pointer;
1738  typedef const value_type *const_pointer;
1740  typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1741  typedef typename stride_traits::stride_type difference_type;
1742  typedef typename stride_traits::stride_array_type difference_array_type;
1743  typedef typename stride_traits::shape_array_type shape_array_type;
1744  typedef base_type next_type;
1745  typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
1746  typedef multi_dimensional_traverser_tag iterator_category;
1747 
1748  protected:
1749  difference_array_type m_stride;
1750  shape_array_type m_shape;
1751 
1752  public:
1753  /* use default copy constructor and assignment operator */
1754 
1756  : base_type (),
1757  m_stride (0), m_shape (0)
1758  {}
1759 
1760  StridedMultiIterator (pointer ptr,
1761  const difference_array_type & stride,
1762  const shape_array_type & shape)
1763  : base_type (ptr, stride, shape),
1764  m_stride (stride), m_shape (shape)
1765  {}
1766 
1767  void operator++ ()
1768  {
1769  this->m_ptr += m_stride [level];
1770  }
1771 
1772  void operator-- ()
1773  {
1774  this->m_ptr -= m_stride [level];
1775  }
1776 
1778  {
1779  StridedMultiIterator ret = *this;
1780  ++(*this);
1781  return ret;
1782  }
1783 
1785  {
1786  StridedMultiIterator ret = *this;
1787  --(*this);
1788  return ret;
1789  }
1790 
1791  StridedMultiIterator & operator+= (difference_type n)
1792  {
1793  this->m_ptr += n * m_stride [level];
1794  return *this;
1795  }
1796 
1797  StridedMultiIterator & operator+= (multi_difference_type const & d)
1798  {
1799  this->m_ptr += total_stride(d.begin());
1800  return *this;
1801  }
1802 
1803  StridedMultiIterator &operator-= (difference_type n)
1804  {
1805  this->m_ptr -= n * m_stride [level];
1806  return *this;
1807  }
1808 
1809  StridedMultiIterator & operator-= (multi_difference_type const & d)
1810  {
1811  this->m_ptr -= total_stride(d.begin());
1812  return *this;
1813  }
1814 
1815  StridedMultiIterator operator+ (difference_type n) const
1816  {
1817  StridedMultiIterator ret = *this;
1818  ret += n;
1819  return ret;
1820  }
1821 
1822  StridedMultiIterator operator+ (multi_difference_type const & d) const
1823  {
1824  StridedMultiIterator ret = *this;
1825  ret += d;
1826  return ret;
1827  }
1828 
1829  difference_type operator- (StridedMultiIterator const & d) const
1830  {
1831  return (this->m_ptr - d.m_ptr) / this->m_stride[level];
1832  }
1833 
1834  StridedMultiIterator operator- (difference_type n) const
1835  {
1836  StridedMultiIterator ret = *this;
1837  ret -= n;
1838  return ret;
1839  }
1840 
1841  StridedMultiIterator operator- (multi_difference_type const & d) const
1842  {
1843  StridedMultiIterator ret = *this;
1844  ret -= d;
1845  return ret;
1846  }
1847 
1848  reference operator[] (difference_type n) const
1849  {
1850  return this->m_ptr [n*m_stride [level]];
1851  }
1852 
1853  reference operator[] (multi_difference_type const & d) const
1854  {
1855  return this->m_ptr [total_stride(d.begin())];
1856  }
1857 
1858  next_type begin () const
1859  {
1860  return *this;
1861  }
1862 
1863  next_type end () const
1864  {
1865  next_type ret = *this;
1866  ret += m_shape [level-1];
1867  return ret;
1868  }
1869 
1870  iterator iteratorForDimension(unsigned int d) const
1871  {
1872  vigra_precondition(d <= level,
1873  "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
1874  return iterator(this->m_ptr, stride_traits::shift(m_stride, d), 0);
1875  }
1876 
1877  template <unsigned int K>
1878  StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
1879  dim()
1880  {
1881  return *this;
1882  }
1883 
1884  StridedMultiIterator<1, T, REFERENCE, POINTER> &
1885  dim0() { return *this; }
1886  StridedMultiIterator<2, T, REFERENCE, POINTER> &
1887  dim1() { return *this; }
1888 
1889  protected:
1890 
1891  difference_type
1892  total_stride(typename multi_difference_type::const_iterator d) const
1893  {
1894  return d[level]*m_stride[level] + base_type::total_stride(d);
1895  }
1896 };
1897 
1898 /********************************************************/
1899 /* */
1900 /* StridedMultiIterator<N> */
1901 /* */
1902 /********************************************************/
1903 
1904 /** \brief A multi-dimensional hierarchical iterator to be used with
1905  \ref vigra::MultiArrayView if it is not strided.
1906 
1907  See \ref MultiIteratorPage for further documentation.
1908 
1909  <b>\#include</b> <vigra/multi_iterator.hxx> <br>
1910  Namespace: vigra
1911 */
1912 template <unsigned int N, class T, class REFERENCE, class POINTER>
1913 class StridedMultiIterator
1914 #ifndef DOXYGEN // doxygen doesn't understand this inheritance
1915 : public StridedMultiIterator<N-1, T, REFERENCE, POINTER>
1916 #endif
1917 {
1918 public:
1919 
1920  /** the type of the parent in the inheritance hierarchy.
1921  */
1922  typedef StridedMultiIterator<N-1, T, REFERENCE, POINTER> base_type;
1923 
1924  /** the iterator's level in the dimension hierarchy
1925  */
1926  enum { level = N-1 };
1927 
1928  /** the iterator's value type
1929  */
1930  typedef T value_type;
1931 
1932  /** reference type (result of operator[])
1933  */
1934  typedef REFERENCE reference;
1935 
1936  /** const reference type (result of operator[] const)
1937  */
1938  typedef const value_type &const_reference;
1939 
1940  /** pointer type
1941  */
1942  typedef POINTER pointer;
1943 
1944  /** const pointer type
1945  */
1946  typedef const value_type *const_pointer;
1947 
1948  /** multi difference type
1949  (used for offsetting along all axes simultaneously)
1950  */
1952 
1953  /** difference type (used for offsetting)
1954  */
1955 #ifndef DOXYGEN
1956  typedef MultiIteratorStrideTraits<POINTER> stride_traits;
1957  typedef typename stride_traits::stride_type difference_type;
1958  typedef typename stride_traits::stride_array_type difference_array_type;
1959 #else
1961 #endif
1962 
1963  /** the StridedMultiIterator for the next lower dimension.
1964  */
1965  typedef base_type next_type;
1966 
1967  /** the 1-dimensional iterator for this iterator hierarchy
1968  (result of iteratorForDimension()).
1969  */
1971 
1972  /** the iterator tag (image traverser)
1973  */
1974  typedef multi_dimensional_traverser_tag iterator_category;
1975 
1976  /* use default copy constructor and assignment operator */
1977 
1978  /** default constructor.
1979  */
1981  {}
1982 
1983  /** construct from pointer, strides (offset of a sample to the
1984  next) for every dimension, and the shape.
1985  */
1986  StridedMultiIterator (pointer ptr,
1987  const difference_array_type & stride,
1988  const difference_array_type & shape)
1989  : base_type (ptr, stride, shape)
1990  {}
1991 
1992 
1993  /** prefix-increment the iterator in its current dimension
1994  */
1996  {
1997  this->m_ptr += this->m_stride [level];
1998  }
1999 
2000  /** prefix-decrement the iterator in its current dimension
2001  */
2003  {
2004  this->m_ptr -= this->m_stride [level];
2005  }
2006 
2007  /** postfix-increment the iterator in its current dimension
2008  */
2010  {
2011  StridedMultiIterator ret = *this;
2012  ++(*this);
2013  return ret;
2014  }
2015 
2016  /** postfix-decrement the iterator in its current dimension
2017  */
2019  {
2020  StridedMultiIterator ret = *this;
2021  --(*this);
2022  return ret;
2023  }
2024 
2025  /** increment the iterator in its current dimension
2026  by the given value.
2027  */
2028  StridedMultiIterator & operator+= (difference_type n)
2029  {
2030  this->m_ptr += n * this->m_stride [level];
2031  return *this;
2032  }
2033 
2034  /** increment the iterator in all dimensions
2035  by the given offset.
2036  */
2037  StridedMultiIterator & operator+= (multi_difference_type const & d)
2038  {
2039  this->m_ptr += total_stride(d.begin());
2040  return *this;
2041  }
2042 
2043  /** decrement the iterator in its current dimension
2044  by the given value.
2045  */
2046  StridedMultiIterator & operator-= (difference_type n)
2047  {
2048  this->m_ptr -= n * this->m_stride [level];
2049  return *this;
2050  }
2051 
2052  /** decrement the iterator in all dimensions
2053  by the given offset.
2054  */
2055  StridedMultiIterator & operator-= (multi_difference_type const & d)
2056  {
2057  this->m_ptr -= total_stride(d.begin());
2058  return *this;
2059  }
2060 
2061  /** addition within current dimension
2062  */
2063  StridedMultiIterator operator+ (difference_type n) const
2064  {
2065  StridedMultiIterator ret = *this;
2066  ret += n;
2067  return ret;
2068  }
2069 
2070  /** addition along all dimensions
2071  */
2072  StridedMultiIterator operator+ (multi_difference_type const & d) const
2073  {
2074  StridedMultiIterator ret = *this;
2075  ret += d;
2076  return ret;
2077  }
2078 
2079  /** difference of two iterators in the current dimension.
2080  The result of this operation is undefined if the iterator
2081  doesn't point to element 0 in all dimensions below its current dimension.
2082  */
2083  difference_type operator- (StridedMultiIterator const & d) const
2084  {
2085  return (this->m_ptr - d.m_ptr) / this->m_stride[level];
2086  }
2087 
2088  /** subtraction within current dimension
2089  */
2090  StridedMultiIterator operator- (difference_type n) const
2091  {
2092  StridedMultiIterator ret = *this;
2093  ret -= n;
2094  return ret;
2095  }
2096 
2097  /** subtraction along all dimensions
2098  */
2099  StridedMultiIterator operator- (multi_difference_type const & d) const
2100  {
2101  StridedMultiIterator ret = *this;
2102  ret -= d;
2103  return ret;
2104  }
2105 
2106 #ifdef DOXYGEN /* documentation only: operators *, ->, ==, !=, <, <=, >, >= are inherited */
2107  /** derefenrence item
2108  */
2109  reference operator* () const;
2110 
2111  /** get address of current item
2112  */
2113  pointer get () const;
2114 
2115  /** call method of current item
2116  */
2117  pointer operator->() const;
2118 
2119  /** inequality. True if iterators reference different items.
2120  */
2121  bool operator!= (const StridedMultiIterator &rhs) const;
2122 
2123  /** equality. True if iterators reference the same items.
2124  */
2125  bool operator== (const StridedMultiIterator &rhs) const;
2126 
2127  /** less than.
2128  */
2129  bool operator< (const StridedMultiIterator &rhs) const;
2130 
2131  /** less or equal.
2132  */
2133  bool operator<= (const StridedMultiIterator &rhs) const;
2134 
2135  /** greater than.
2136  */
2137  bool operator> (const StridedMultiIterator &rhs) const;
2138 
2139  /** greater or equal.
2140  */
2141  bool operator>= (const StridedMultiIterator &rhs) const;
2142 #endif
2143 
2144  /** access the array element at the given offset in
2145  the current dimension.
2146  */
2147  reference operator[] (difference_type n) const
2148  {
2149  return this->m_ptr [n* this->m_stride [level]];
2150  }
2151 
2152  /** access the array element at the given offset.
2153  */
2154  reference operator[] (multi_difference_type const & d) const
2155  {
2156  return this->m_ptr [total_stride(d.begin())];
2157  }
2158 
2159  /** Return the (N-1)-dimensional multi-iterator that points to
2160  the first (N-1)-dimensional subarray of the
2161  N-dimensional array this iterator is referring to.
2162  The result is only valid if this iterator refers to location
2163  0 in <em>all</em> dimensions below its current dimension N,
2164  otherwise it is undefined. Usage:
2165 
2166  \code
2167 
2168  StridedMultiIterator<2, int> outer = ...; // this iterator
2169 
2170  StridedMultiIterator<2, int>::next_type inner = outer.begin();
2171  for(; inner != outer.end(); ++inner)
2172  {
2173  // manipulate current 1D subimage
2174  }
2175  \endcode
2176  */
2177  next_type begin () const
2178  {
2179  return *this;
2180  }
2181 
2182  /** Return the (N-1)-dimensional multi-iterator that points beyond
2183  the last (N-1)-dimensional subarray of the
2184  N-dimensional array this iterator is referring to.
2185  The result is only valid if this iterator refers to location
2186  0 in <em>all</em> dimensions below its current dimension N,
2187  otherwise it is undefined.
2188  */
2189  next_type end () const
2190  {
2191  next_type ret = *this;
2192  ret += this->m_shape [level-1];
2193  return ret;
2194  }
2195 
2196  /** Get a 1-dimensional, STL-compatible iterator for the
2197  given dimension, pointing to the current element of <TT>this</TT>.
2198  Usage:
2199 
2200  \code
2201 
2202  StridedMultiIterator<3, int> outer = ...; // this iterator
2203 
2204  StridedMultiIterator<3, int>::iterator i = outer.iteratorForDimension(1);
2205  StridedMultiIterator<3, int>::iterator end = i + height;
2206  for(; i != end; ++i)
2207  {
2208  // go down the current column starting at the location of 'outer'
2209  }
2210  \endcode
2211  */
2212  iterator iteratorForDimension(unsigned int d) const
2213  {
2214  vigra_precondition(d <= level,
2215  "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
2216  return iterator(this->m_ptr, stride_traits::shift(this->m_stride, d),0);
2217  }
2218  /** Return the multi-iterator that operates on dimension K in order
2219  to manipulate this dimension directly. Usage:
2220 
2221  \code
2222 
2223  StridedMultiIterator<3, int> i3 = ...;
2224 
2225  i3.template dim<2>()++; // increment outer dimension
2226  i3.template dim<0>()++; // increment inner dimension
2227  \endcode
2228 
2229  For convenience, the same functionality is also available
2230  as <tt>dim0()</tt>, <tt>dim1()</tt> etc. up to <tt>dim4()</tt>:
2231 
2232  \code
2233 
2234  StridedMultiIterator<3, int> i3 = ...;
2235 
2236  i3.dim2()++; // increment outer dimension
2237  i3.dim0()++; // increment inner dimension
2238  \endcode
2239  */
2240  template <unsigned int K>
2243  {
2244  return *this;
2245  }
2246 
2248  dim0() { return *this; }
2249  StridedMultiIterator<2, T, REFERENCE, POINTER> &
2250  dim1() { return *this; }
2251  StridedMultiIterator<3, T, REFERENCE, POINTER> &
2252  dim2() { return *this; }
2253  StridedMultiIterator<4, T, REFERENCE, POINTER> &
2254  dim3() { return *this; }
2255  StridedMultiIterator<5, T, REFERENCE, POINTER> &
2256  dim4() { return *this; }
2257 
2258  protected:
2259 
2260  difference_type
2261  total_stride(typename multi_difference_type::const_iterator d) const
2262  {
2263  return d[level]*this->m_stride[level] + base_type::total_stride(d);
2264  }
2265 
2266 };
2267 
2268 //@}
2269 
2270 } // namespace vigra
2271 
2272 namespace std {
2273 
2274  // output the current coordinate of the iterator
2275  // (note: this also works when the iterator is an end-iterator)
2276 template <unsigned int N, class T, class REFERENCE, class POINTER>
2277 ostream & operator<<(ostream & o, vigra::StridedScanOrderIterator<N, T, REFERENCE, POINTER> const & i)
2278 {
2279  o << i.point();
2280  return o;
2281 }
2282 
2283 } // namespace std
2284 
2285 #endif // VIGRA_MULTI_ITERATOR_HXX
StridedMultiIterator< 1, T, REFERENCE, POINTER > iterator
Definition: multi_iterator.hxx:1208
reference operator*() const
reference operator[](difference_type n) const
Definition: multi_iterator.hxx:2147
bool operator<(const MultiIterator &rhs) const
POINTER pointer
Definition: multi_iterator.hxx:1942
Diff2D operator-(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:711
StridedMultiIterator()
Definition: multi_iterator.hxx:1980
next_type end() const
Definition: multi_iterator.hxx:2189
A multi-dimensional hierarchical iterator to be used with vigra::MultiArrayView if it is not strided...
Definition: multi_fwd.hxx:148
pointer operator->() const
StridedMultiIterator & operator+=(difference_type n)
Definition: multi_iterator.hxx:2028
MultiIterator operator+(difference_type n) const
Definition: multi_iterator.hxx:1301
bool operator>(const StridedMultiIterator &rhs) const
bool operator>=(const StridedMultiIterator &rhs) const
MultiIterator & operator-=(difference_type n)
Definition: multi_iterator.hxx:1284
const value_type & const_reference
Definition: multi_iterator.hxx:1938
multi_dimensional_traverser_tag iterator_category
Definition: multi_iterator.hxx:1974
Diff2D operator+(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:739
POINTER pointer
Definition: multi_iterator.hxx:1179
StridedMultiIterator< K+1, T, REFERENCE, POINTER > & dim()
Definition: multi_iterator.hxx:2242
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
StridedMultiIterator & operator-=(difference_type n)
Definition: multi_iterator.hxx:2046
bool operator<=(const MultiIterator &rhs) const
MultiIterator< N-1, T, REFERENCE, POINTER > base_type
Definition: multi_iterator.hxx:1159
FFTWComplex< R > & operator-=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
subtract-assignment
Definition: fftw3.hxx:867
iterator iteratorForDimension(unsigned int d) const
Definition: multi_iterator.hxx:1450
void operator++()
Definition: multi_iterator.hxx:1995
StridedMultiIterator(pointer ptr, const difference_array_type &stride, const difference_array_type &shape)
Definition: multi_iterator.hxx:1986
MultiArrayIndex difference_type
Definition: multi_iterator.hxx:1960
REFERENCE reference
Definition: multi_iterator.hxx:1934
base_type next_type
Definition: multi_iterator.hxx:1965
bool operator<=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less or equal
Definition: fixedpoint.hxx:521
MultiIterator(pointer ptr, const difference_array_type &stride, const shape_array_type &shape)
Definition: multi_iterator.hxx:1224
REFERENCE reference
Definition: multi_iterator.hxx:1171
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
StridedMultiIterator operator+(difference_type n) const
Definition: multi_iterator.hxx:2063
MultiIterator()
Definition: multi_iterator.hxx:1218
T value_type
Definition: multi_iterator.hxx:1167
next_type begin() const
Definition: multi_iterator.hxx:2177
MultiIterator< K+1, T, REFERENCE, POINTER > & dim()
Definition: multi_iterator.hxx:1480
StridedMultiIterator< 1, T, REFERENCE, POINTER > iterator
Definition: multi_iterator.hxx:1970
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
MultiArrayIndex difference_type
Definition: multi_iterator.hxx:1198
CoupledScanOrderIterator getEndIterator() const
Definition: multi_iterator_coupled.hxx:282
iterator begin()
Definition: tinyvector.hxx:861
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
MultiIterator & operator+=(difference_type n)
Definition: multi_iterator.hxx:1266
bool operator<=(const StridedMultiIterator &rhs) const
TinyVector< MultiArrayIndex, N > type
Definition: multi_shape.hxx:272
bool operator!=(const MultiIterator &rhs) const
difference_type operator-(MultiIterator const &d) const
Definition: multi_iterator.hxx:1321
A multi-dimensional hierarchical iterator to be used with vigra::MultiArrayView if it is not strided...
Definition: multi_fwd.hxx:153
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
const value_type & const_reference
Definition: multi_iterator.hxx:1175
bool operator>=(const MultiIterator &rhs) const
bool operator==(const MultiIterator &rhs) const
const value_type * const_pointer
Definition: multi_iterator.hxx:1183
bool operator<(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less than
Definition: fixedpoint.hxx:512
void operator--()
Definition: multi_iterator.hxx:1240
bool operator>=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater or equal
Definition: fixedpoint.hxx:539
multi_dimensional_traverser_tag iterator_category
Definition: multi_iterator.hxx:1212
void operator--()
Definition: multi_iterator.hxx:2002
iterator iteratorForDimension(unsigned int d) const
Definition: multi_iterator.hxx:2212
StridedMultiIterator< N-1, T, REFERENCE, POINTER > base_type
Definition: multi_iterator.hxx:1922
pointer operator->() const
void operator++()
Definition: multi_iterator.hxx:1233
bool operator==(const StridedMultiIterator &rhs) const
reference operator[](difference_type n) const
Definition: multi_iterator.hxx:1385
next_type end() const
Definition: multi_iterator.hxx:1427
bool operator>(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater
Definition: fixedpoint.hxx:530
MultiArrayShape< N >::type multi_difference_type
Definition: multi_iterator.hxx:1188
bool operator>(const MultiIterator &rhs) const
T value_type
Definition: multi_iterator.hxx:1930
next_type begin() const
Definition: multi_iterator.hxx:1415
bool operator<(const StridedMultiIterator &rhs) const
bool operator!=(const StridedMultiIterator &rhs) const
MultiArrayShape< N >::type multi_difference_type
Definition: multi_iterator.hxx:1951
base_type next_type
Definition: multi_iterator.hxx:1203
reference operator*() const
difference_type operator-(StridedMultiIterator const &d) const
Definition: multi_iterator.hxx:2083
const value_type * const_pointer
Definition: multi_iterator.hxx:1946

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)