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

details vigra/multi_iterator.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 2003 by Gunnar Kedenburg                     */
00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
00005 /*                                                                      */
00006 /*    This file is part of the VIGRA computer vision library.           */
00007 /*    ( Version 1.2.0, Aug 07 2003 )                                    */
00008 /*    You may use, modify, and distribute this software according       */
00009 /*    to the terms stated in the LICENSE file included in               */
00010 /*    the VIGRA distribution.                                           */
00011 /*                                                                      */
00012 /*    The VIGRA Website is                                              */
00013 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
00014 /*    Please direct questions, bug reports, and contributions to        */
00015 /*        koethe@informatik.uni-hamburg.de                              */
00016 /*                                                                      */
00017 /*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
00018 /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
00019 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
00020 /*                                                                      */
00021 /************************************************************************/
00022 
00023 
00024 #ifndef VIGRA_MULTI_ITERATOR_HXX
00025 #define VIGRA_MULTI_ITERATOR_HXX
00026 
00027 #include <sys/types.h>
00028 #include "vigra/tinyvector.hxx"
00029 #include "vigra/iteratortags.hxx"
00030 
00031 namespace vigra {
00032 
00033 
00034 template <unsigned int N, class T, 
00035           class REFERENCE = T &, class POINTER = T *> class MultiIterator;
00036 
00037 /** \page MultiIteratorPage  Multi-dimensional Array Iterators
00038 
00039     General iterators for arrays of arbitrary dimension.
00040 
00041 
00042 <p>
00043 <DL>
00044 <DT>
00045     <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00046     \ref vigra::MultiIterator
00047     <DD> <em>Iterator for unstrided \ref vigra::MultiArrayView</em>
00048 <DT>
00049     <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 
00050     \ref vigra::MultiIteratorBase::type
00051     <DD> <em>Inner class implementing most of the functionality of \ref vigra::MultiIterator</em>
00052 <DT>
00053     <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00054     \ref vigra::StridedMultiIterator
00055     <DD> <em>Iterator for strided \ref vigra::MultiArrayView</em>
00056 <DT>
00057     <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00058     \ref vigra::StridedMultiIteratorBase::type
00059     <DD> <em>Inner class implementing most of the functionality of \ref vigra::StridedMultiIterator</em>
00060 </DL>
00061 </p>
00062 
00063 <p>
00064     The Multidimensional Iterator concept allows navigation on arrays
00065     of arbitrary dimension. It provides two modes of iteration: 
00066     <em>direct traveral</em>, and <em>hierarchical traversal</em>.
00067     In general, hierarchical traversal will be faster, while only 
00068     direct traversal allows for true random access in all dimensions.
00069     Via the <tt>dim<K>()</tt> function, operations applying to a particular
00070     dimension can be used in the direct traversal mode. In contrast,
00071     direct traversal functions should not be used in the hierarchical mode
00072     because the hierarchical functions are only well-defined if the
00073     iterator points to element 0 in all dimensions below its current dimension.
00074     The current dimension of a <tt>MultiIterator&lt;N, ..&gt;</tt> is <tt>N-1</tt>.
00075 </p>
00076 <h3>Gerneral Requirements for MultiIterator</h3>
00077 <p>
00078 <table border=2 cellspacing=0 cellpadding=2 width="100%">
00079 <tr><td>
00080     \htmlonly
00081     <th colspan=2>
00082     \endhtmlonly
00083     Local Types
00084     \htmlonly
00085     </th><th>
00086     \endhtmlonly
00087     Meaning
00088     \htmlonly
00089     </th>
00090     \endhtmlonly
00091 </td></tr>
00092 <tr><td>
00093     \htmlonly
00094     <td colspan=2>
00095     \endhtmlonly
00096     <tt>MultiIterator::value_type</tt></td><td>the underlying arrays's pixel type</td>
00097 </tr>
00098 <tr>
00099     <td>
00100     \htmlonly
00101     <td colspan=2>
00102     \endhtmlonly
00103     <tt>MultiIterator::reference</tt></td>
00104     <td>the iterator's reference type (return type of <TT>*iter</TT>). Will be
00105     <tt>value_type &</tt> for a mutable iterator, and convertible to
00106     <tt>value_type const &</tt> for a const iterator.</td>
00107 </tr>
00108 <tr>
00109     <td>
00110     \htmlonly
00111     <td colspan=2>
00112     \endhtmlonly
00113     <tt>MultiIterator::pointer</tt></td>
00114     <td>the iterator's pointer type (return type of <TT>iter.operator->()</TT>). Will be
00115     <tt>value_type *</tt> for a mutable iterator, and convertible to
00116     <tt>value_type const *</tt> for a const iterator.</td>
00117 </tr>
00118 <tr>
00119     <td>
00120     \htmlonly
00121     <td colspan=2>
00122     \endhtmlonly
00123     <tt>MultiIterator::iterator_category</tt></td>
00124     <td>the iterator tag (<tt>vigra::multi_dimensional_traverser_tag</tt>)</td>
00125 </tr>
00126 <tr><td>
00127     \htmlonly
00128     <th>
00129     \endhtmlonly
00130     Operation
00131     \htmlonly
00132     </th><th>
00133     \endhtmlonly
00134     Result
00135     \htmlonly
00136     </th><th>
00137     \endhtmlonly
00138     Semantics
00139     \htmlonly
00140     </th>
00141     \endhtmlonly
00142 </td></tr>
00143 <tr><td>
00144     \htmlonly
00145     <td colspan=2>
00146     \endhtmlonly
00147     <tt>MultiIterator k;</tt></td><td>default constructor</td>
00148 </tr>
00149 <tr><td>
00150     \htmlonly
00151     <td colspan=2>
00152     \endhtmlonly
00153     <tt>MultiIterator k(i);</tt></td><td>copy constructor</td>
00154 </tr>
00155 <tr>
00156     <td><tt>k = i</tt></td>
00157     <td><tt>MultiIterator &</tt></td><td>assignment</td>
00158 </tr>
00159 <tr>
00160     <td><tt>i == j</tt></td><td><tt>bool</tt></td>
00161     <td>equality (iterators point to the same element)</td>
00162 </tr>
00163 <tr>
00164     <td><tt>i != j</tt></td><td><tt>bool</tt></td>
00165     <td>inequality (iterators don't point to the same element)</td>
00166 </tr>
00167 <tr>
00168     <td><tt>*i</tt></td><td><tt>MultiIterator::reference</tt></td>
00169     <td>access the current element</td>
00170 </tr>
00171 <tr>
00172     <td><tt>i->member()</tt></td><td>depends on operation</td>
00173     <td>call member function of underlying pixel type via <tt>operator-></tt> of iterator</td>
00174 </tr>
00175 </table>
00176 </p>
00177 <h3>Requirements for Direct Traversal</h3>
00178 <p>
00179 <table border=2 cellspacing=0 cellpadding=2 width="100%">
00180 <tr><td>
00181     \htmlonly
00182     <th colspan=2>
00183     \endhtmlonly
00184     Local Types
00185     \htmlonly
00186     </th><th>
00187     \endhtmlonly
00188     Meaning
00189     \htmlonly
00190     </th>
00191     \endhtmlonly
00192 </td></tr>
00193 <tr><td>
00194     \htmlonly
00195     <td colspan=2>
00196     \endhtmlonly
00197     <tt>MultiIterator::multi_difference_type</tt></td>
00198     <td>the iterator's multi-dimensional difference type (<TT>TinyVector&lt;ptrdiff_t, N&gt;</TT>)</td>
00199 </tr>
00200 <tr><td>
00201     \htmlonly
00202     <th>
00203     \endhtmlonly
00204     Operation
00205     \htmlonly
00206     </th><th>
00207     \endhtmlonly
00208     Result
00209     \htmlonly
00210     </th><th>
00211     \endhtmlonly
00212     Semantics
00213     \htmlonly
00214     </th>
00215     \endhtmlonly
00216 </td></tr>
00217 <tr>
00218     <td><tt>i += diff</tt></td><td><tt>MultiIterator &</tt></td>
00219     <td>add offset to current position</td>
00220 </tr>
00221 <tr>
00222     <td><tt>i -= diff</tt></td><td><tt>MultiIterator &</tt></td>
00223     <td>subtract offset from current position</td>
00224 </tr>
00225 <tr>
00226     <td><tt>i + diff</tt></td><td><tt>MultiIterator</tt></td>
00227     <td>create traverser by adding offset</td>
00228 </tr>
00229 <tr>
00230     <td><tt>i - diff</tt></td><td><tt>MultiIterator</tt></td>
00231     <td>create traverser by subtracting offset</td>
00232 </tr>
00233 <tr>
00234     <td><tt>i[diff]</tt></td><td><tt>MultiIterator::reference</tt></td>
00235     <td>access element at offset <tt>diff</tt></td>
00236 </tr>
00237 <tr>
00238     <td><tt>i.dim<K>()</tt></td><td><tt>MultiIterator&lt;K+1, T, ...&gt;</tt></td>
00239     <td>Access the traverser with the current dimension set to K. Typically used to call
00240         navigation functions referring to a particular dimension.<br>
00241         Example (assuming <tt>i, j</tt> are 3-dimensional):<br>
00242         \code
00243         i.dim<0>()++;   // increment dimension 0 
00244         i.dim<1>()++;   // increment dimension 1 
00245         i.dim<2>()++;   // increment dimension 2 
00246         
00247         j += MultiIterator::multi_difference_type(1,1,1);    // same effect
00248         \endcode
00249     </td>
00250 </tr>
00251 <tr><td>
00252     \htmlonly
00253     <td colspan=3>
00254     \endhtmlonly
00255        <tt>i, j</tt> are of type <tt>MultiIterator</tt><br>
00256        <tt>diff</tt> is of type <tt>MultiIterator::multi_difference_type</tt><br>
00257        <tt>K</tt> is an integer compile-time constant
00258     </td>
00259 </tr>
00260 </table>
00261 </p>
00262 <p>
00263 Note that it is impossible to support an <tt>operator-</tt> between two iterators which returns
00264 a <tt>MultiIterator::multi_difference_type</tt> because it is impossible to decide to which
00265 dimension a difference applies. Consider for example, a 2-dimensional iterator <tt>i</tt>, and
00266 let <tt>j = i + multi_difference_type(width, 0)</tt>, <tt>k = i + multi_difference_type(0,1)</tt>, 
00267 where <tt>width</tt> is the array's total width. In general, <tt>j</tt> and <tt>k</tt> point to 
00268 the same memory location, so that the two cases cannot easily be distinguished (it is possible,
00269 but iterator performance will suffer significantly, as is experienced with 
00270 \ref vigra::ImageIterator where differencing is allowed).
00271 </p>
00272 
00273 <h3>Requirements for Hierarchical Traversal</h3>
00274 <p>
00275 <table border=2 cellspacing=0 cellpadding=2 width="100%">
00276 <tr><td>
00277     \htmlonly
00278     <th colspan=2>
00279     \endhtmlonly
00280     Local Types
00281     \htmlonly
00282     </th><th>
00283     \endhtmlonly
00284     Meaning
00285     \htmlonly
00286     </th>
00287     \endhtmlonly
00288 </td></tr>
00289 <tr>
00290     <td>
00291     \htmlonly
00292     <td colspan=2>
00293     \endhtmlonly
00294     <tt>MultiIterator::difference_type</tt></td>
00295     <td>the iterator's difference type (<TT>ptrdiff_t</TT>)</td>
00296 </tr>
00297 <tr>
00298     <td>
00299     \htmlonly
00300     <td colspan=2>
00301     \endhtmlonly
00302     <tt>MultiIterator::next_type</tt></td><td>type of the next iterator
00303        (referring to the next lower dimension) in the hierarchy</td>
00304 </tr>
00305 <tr><td>
00306     \htmlonly
00307     <th>
00308     \endhtmlonly
00309     Operation
00310     \htmlonly
00311     </th><th>
00312     \endhtmlonly
00313     Result
00314     \htmlonly
00315     </th><th>
00316     \endhtmlonly
00317     Semantics
00318     \htmlonly
00319     </th>
00320     \endhtmlonly
00321 </td></tr>
00322 <tr>
00323     <td><tt>++i</tt></td><td><tt>MultiIterator &</tt></td>
00324     <td>pre-increment iterator in its current dimension</td>
00325 </tr>
00326 <tr>
00327     <td><tt>i++</tt></td><td><tt>MultiIterator</tt></td>
00328     <td>post-increment iterator in its current dimension</td>
00329 </tr>
00330 <tr>
00331     <td><tt>--i</tt></td><td><tt>MultiIterator &</tt></td>
00332     <td>pre-decrement iterator in its current dimension</td>
00333 </tr>
00334 <tr>
00335     <td><tt>i--</tt></td><td><tt>MultiIterator</tt></td>
00336     <td>post-decrement iterator in its current dimension</td>
00337 </tr>
00338 <tr>
00339     <td><tt>i += d</tt></td><td><tt>MultiIterator &</tt></td>
00340     <td>add <tt>d</tt> in current dimension</td>
00341 </tr>
00342 <tr>
00343     <td><tt>i -= d</tt></td><td><tt>MultiIterator &</tt></td>
00344     <td>subtract <tt>d</tt> in from dimension</td>
00345 </tr>
00346 <tr>
00347     <td><tt>i + d</tt></td><td><tt>MultiIterator</tt></td>
00348     <td>create new iterator by adding <tt>d</tt> in current dimension</td>
00349 </tr>
00350 <tr>
00351     <td><tt>i - d</tt></td><td><tt>MultiIterator</tt></td>
00352     <td>create new iterator by subtracting <tt>d</tt> in current dimension</td>
00353 </tr>
00354 <tr>
00355     <td><tt>i - j</tt></td><td><tt>difference_type</tt></td>
00356     <td>difference of <tt>i</tt> and <tt>j</tt> in the current dimension<br>
00357     <em>Note:</em> The result of this operation is undefined if the iterator
00358     doesn't point to element 0 in all dimensions below its current dimension.</td>
00359 </tr>
00360 <tr>
00361     <td><tt>i < j</tt></td><td><tt>bool</tt></td>
00362     <td><tt>i - j < 0</tt><br>
00363     <em>Note:</em> The result of this operation is undefined if the iterator
00364     doesn't point to element 0 in all dimensions below its current dimension.</td>
00365 </tr>
00366 <tr>
00367     <td><tt>i[d]</tt></td><td><tt>MultiIterator::reference</tt></td>
00368     <td>access element by adding offset <tt>d</tt> in current dimension</td>
00369 </tr>
00370 <tr>
00371     <td><tt>i.begin()</tt></td><td><tt>next_type</tt></td>
00372     <td>create the hierarchical iterator poiting to the first element in the 
00373     next lower dimension.<br>
00374     <em>Note:</em> The result of this operation is undefined if the iterator
00375     doesn't point to element 0 in all dimensions below its current dimension.<br>
00376     Usage:<br>
00377     \code
00378     MultiIterator<3, int> i3 = ..., end3 = ...;
00379     for(; i3 != end3; ++i3)
00380     {
00381         MultiIterator<3, int>::next_type i2 = i3.begin(), end2 = i3.end();
00382         for(; i2 != end2; ++i2)
00383         {
00384             MultiIterator<3, int>::next_type::next_type i1 = i2.begin(), end1 = i2.end();
00385             for(; i1 != end1; ++i1)
00386             {
00387                 ... // do something with the current element
00388             }
00389         }
00390     }
00391     
00392     \endcode
00393     </td>
00394 </tr>
00395 <tr>
00396     <td><tt>i.end()</tt></td><td><tt>next_type</tt></td>
00397     <td>create the hierarchical iterator poiting to the past-the-end location in the 
00398     next lower dimension.<br>
00399     <em>Note:</em> The result of this operation is undefined if the iterator
00400     doesn't point to element 0 in all dimensions below its current dimension.</td>
00401 </tr>
00402 <tr>
00403     <td>
00404     \htmlonly
00405     <td colspan=3>
00406     \endhtmlonly
00407        <tt>i, j</tt> are of type <tt>MultiIterator</tt><br>
00408        <tt>d</tt> is of type <tt>MultiIterator::difference_type</tt>
00409     </td>
00410 </tr>
00411 </table>
00412 </p>
00413 
00414 */
00415 
00416 /** \addtogroup MultiIteratorGroup  Multi-dimensional Array Iterators
00417 
00418     \brief General iterators for arrays of arbitrary dimension.
00419 */
00420 //@{
00421 
00422 /********************************************************/
00423 /*                                                      */
00424 /*                    MultiIteratorBase                 */
00425 /*                                                      */
00426 /********************************************************/
00427 
00428 /** \brief Enclosing class for \ref vigra::MultiIterator base classes.
00429 
00430 This design is necessary for compilers that do not support partial
00431 specialization (otherwise, MultiIterator could be specialized directly).
00432 
00433 <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/multi_iterator.hxx</a>"
00434 
00435 Namespace: vigra
00436 */
00437 template <unsigned int N>
00438 class MultiIteratorBase
00439 {
00440   public:
00441         /** \brief Base class for \ref vigra::MultiIterator.
00442 
00443         This class implements the multi-iterator by means of the enclosed template 
00444         class <tt>type</tt>. This design is necessary for compilers that do not support partial
00445         specialization (otherwise, MultiIterator could be specialized directly).
00446 
00447         <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/multi_iterator.hxx</a>"
00448 
00449         Namespace: vigra
00450         */
00451     template <class T, class REFERENCE, class POINTER>
00452     class type : public MultiIterator <N-1, T, REFERENCE, POINTER>
00453     {
00454     public:
00455             /** the type of the parent in the inheritance hierarchy.
00456              */
00457         typedef MultiIterator <N-1, T, REFERENCE, POINTER> base_type;
00458 
00459     public:
00460         
00461             /** the iterator's level in the dimension hierarchy
00462              */
00463         enum { level = N-1 };
00464 
00465             /** the iterator's value type
00466              */
00467         typedef T value_type;
00468 
00469             /** reference type (result of operator[] and operator*())
00470              */
00471         typedef REFERENCE reference;
00472 
00473             /** pointer type (result of operator->())
00474              */
00475         typedef POINTER pointer;
00476 
00477             /** difference type (used for offsetting along one axis)
00478              */
00479         typedef ptrdiff_t difference_type;
00480 
00481             /** multi difference type 
00482                 (used for offsetting along all axes simultaneously)
00483              */
00484         typedef TinyVector<difference_type, N> multi_difference_type;
00485 
00486             /** the next type, this is a non-standard typedef denoting the
00487                 type of the multi-iterator with the next-lower dimension.
00488             */
00489         typedef MultiIterator <level, T, REFERENCE, POINTER> next_type;
00490 
00491             /** the iterator tag (image traverser)
00492             */
00493         typedef multi_dimensional_traverser_tag iterator_category;
00494 
00495             
00496         /* use default copy constructor and assignment operator */
00497             
00498             /** default constructor.
00499             */
00500         type ()
00501         {}
00502 
00503             /** construct from pointer, strides (offset of a sample to the
00504                 next) for every dimension, and the shape.
00505             */
00506         type (pointer ptr,
00507               const difference_type *stride,
00508               const difference_type *shape)
00509             : base_type (ptr, stride, shape)
00510         {}
00511 
00512             /** prefix-increment the iterator in it's current dimension
00513              */
00514         void operator++ ()
00515         {
00516             m_ptr += m_stride [level];
00517         }
00518 
00519             /** prefix-decrement the iterator in it's current dimension
00520              */
00521         void operator-- ()
00522         {
00523             m_ptr -= m_stride [level];
00524         }
00525 
00526             /** postfix-increment the iterator in it's current dimension
00527              */
00528         type operator++ (int)
00529         {
00530             type ret = *this;
00531             ++(*this);
00532             return ret;
00533         }
00534 
00535             /** postfix-decrement the iterator in it's current dimension
00536              */
00537         type operator-- (int)
00538         {
00539             type ret = *this;
00540             --(*this);
00541             return ret;
00542         }
00543 
00544             /** increment the iterator in it's current dimension
00545                 by the given value.
00546             */
00547         type & operator+= (difference_type n)
00548         {
00549             m_ptr += n * m_stride [level];
00550             return *this;
00551         }
00552         
00553             /** increment the iterator in all dimensions
00554                 by the given offset.
00555             */
00556         type & operator+= (multi_difference_type const & d)
00557         {
00558             m_ptr += total_stride(d.begin());
00559             return *this;
00560         }
00561 
00562             /** decrement the iterator in it's current dimension
00563                 by the given value.
00564             */
00565         type & operator-= (difference_type n)
00566         {
00567             m_ptr -= n * m_stride [level];
00568             return *this;
00569         }
00570         
00571             /** decrement the iterator in all dimensions
00572                 by the given offset.
00573             */
00574         type & operator-= (multi_difference_type const & d)
00575         {
00576             m_ptr -= total_stride(d.begin());
00577             return *this;
00578         }
00579         
00580             /** difference of two iterators in the current dimension.
00581                 The result of this operation is undefined if the iterator
00582                 doesn't point to element 0 in all dimensions below its current dimension.
00583             */
00584         difference_type operator- (type const & d) const
00585         {
00586             return (d.m_ptr - m_ptr) / m_stride[level];
00587         }
00588 
00589         /* operators *, ->, ==, !=, < inherited */
00590 
00591             /** access the array element at the given offset in 
00592             the current dimension.
00593             */
00594         reference operator[] (difference_type n) const
00595         {
00596             return m_ptr [n* m_stride [level]];
00597         }
00598 
00599             /** access the array element at the given offset.
00600             */
00601         reference operator[] (multi_difference_type const & d) const
00602         {
00603             return m_ptr [total_stride(d.begin())];
00604         }
00605 
00606             /** Return the (N-1)-dimensional multi-iterator that points to 
00607                 the first (N-1)-dimensional subarray of the 
00608                 N-dimensional array this iterator is referring to.
00609                 The result is only valid if this iterator refers to location
00610                 0 in <em>all</em> dimensions below its current dimension N,
00611                 otherwise it is undefined. Usage:
00612                 
00613                 \code
00614                 
00615                 MultiIterator<2, int> outer = ...;  // this iterator
00616                 
00617                 MultiIterator<2, int>::next_type inner = outer.begin();
00618                 for(; inner != outer.end(); ++inner)
00619                 {
00620                     // manipulate current 1D subimage
00621                 }
00622                 \endcode
00623             */
00624         next_type begin () const
00625         {
00626             return *this;
00627         }
00628 
00629             /** Return the (N-1)-dimensional multi-iterator that points beyond 
00630                 the last (N-1)-dimensional subarray of the 
00631                 N-dimensional array this iterator is referring to.
00632                 The result is only valid if this iterator refers to location
00633                 0 in <em>all</em> dimensions below its current dimension N,
00634                 otherwise it is undefined. Usage:
00635             */
00636         next_type end () const
00637         {
00638             next_type ret = *this;
00639             ret += m_shape [level-1];
00640             return ret;
00641         }
00642         
00643       protected:
00644       
00645         difference_type 
00646         total_stride(typename multi_difference_type::const_iterator d) const
00647         {
00648             return d[level]*m_stride[level] + base_type::total_stride(d);
00649         }
00650     };
00651 };
00652 
00653 /********************************************************/
00654 /*                                                      */
00655 /*                      MultiIteratorBase <2>           */
00656 /*                                                      */
00657 /********************************************************/
00658 
00659 //
00660 template <>
00661 class MultiIteratorBase <2>
00662 {
00663   public:
00664     template <class T, class REFERENCE, class POINTER>
00665     class type : public MultiIterator <1, T, REFERENCE, POINTER>
00666     {
00667 
00668     public:
00669 
00670         enum { level = 1 };
00671         typedef MultiIterator <1, T, REFERENCE, POINTER> base_type;
00672         typedef T value_type;
00673         typedef value_type &reference;
00674         typedef const value_type &const_reference;
00675         typedef value_type *pointer;
00676         typedef const value_type *const_pointer;
00677         typedef ptrdiff_t difference_type;
00678         typedef MultiIterator <1, T, REFERENCE, POINTER> next_type;
00679         typedef TinyVector<difference_type, 2> multi_difference_type;
00680         typedef multi_dimensional_traverser_tag iterator_category;
00681 
00682         const difference_type *m_stride;
00683         const difference_type *m_shape;
00684             
00685         /* use default copy constructor and assignment operator */
00686             
00687         type ()
00688             : base_type (),
00689               m_stride (0), m_shape (0)
00690         {}
00691 
00692         type (pointer ptr,
00693               const difference_type *stride,
00694               const difference_type *shape)
00695             : base_type (ptr, stride, shape),
00696               m_stride (stride), m_shape (shape)
00697         {}
00698 
00699         void operator++ ()
00700         {
00701             m_ptr += m_stride [level];
00702         }
00703 
00704         void operator-- ()
00705         {
00706             m_ptr -= m_stride [level];
00707         }
00708 
00709         type operator++ (int)
00710         {
00711             type ret = *this;
00712             ++(*this);
00713             return ret;
00714         }
00715 
00716         type operator-- (int)
00717         {
00718             type ret = *this;
00719             --(*this);
00720             return ret;
00721         }
00722 
00723         type & operator+= (difference_type n)
00724         {
00725             m_ptr += n * m_stride [level];
00726             return *this;
00727         }
00728         
00729         type & operator+= (multi_difference_type const & d)
00730         {
00731             m_ptr += total_stride(d.begin());
00732             return *this;
00733         }
00734 
00735         type  &operator-= (difference_type n)
00736         {
00737             m_ptr -= n * m_stride [level];
00738             return *this;
00739         }
00740         
00741         type & operator-= (multi_difference_type const & d)
00742         {
00743             m_ptr -= total_stride(d.begin());
00744             return *this;
00745         }
00746         
00747         difference_type operator- (type const & d) const
00748         {
00749             return (d.m_ptr - m_ptr) / m_stride[level];
00750         }
00751 
00752         reference operator[] (difference_type n) const
00753         {
00754             return m_ptr [n*m_stride [level]];
00755         }
00756 
00757         reference operator[] (multi_difference_type const & d) const
00758         {
00759             return m_ptr [total_stride(d.begin())];
00760         }
00761 
00762         next_type begin () const
00763         {
00764             return *this;
00765         }
00766 
00767         next_type end () const
00768         {
00769             next_type ret = *this;
00770             ret += m_shape [level-1];
00771             return ret;
00772         }
00773         
00774       protected:
00775       
00776         difference_type 
00777         total_stride(typename multi_difference_type::const_iterator d) const
00778         {
00779             return d[level]*m_stride[level] + base_type::total_stride(d);
00780         }
00781     };
00782 };
00783 
00784 /********************************************************/
00785 /*                                                      */
00786 /*                   MultiIteratorBase <1>              */
00787 /*                                                      */
00788 /********************************************************/
00789 
00790 //
00791 template <>
00792 class MultiIteratorBase <1>
00793 {
00794   public:
00795     template <class T, class REFERENCE, class POINTER>
00796     class type
00797     {
00798       public:
00799         enum { level = 0 };
00800         typedef T value_type;
00801         typedef value_type &reference;
00802         typedef const value_type &const_reference;
00803         typedef value_type *pointer;
00804         typedef const value_type *const_pointer;
00805         typedef ptrdiff_t difference_type;
00806         typedef void next_type;
00807         typedef TinyVector<difference_type, 1> multi_difference_type;
00808         typedef multi_dimensional_traverser_tag iterator_category;
00809 
00810         pointer m_ptr;
00811 
00812             
00813         /* use default copy constructor and assignment operator */
00814             
00815         type ()
00816             : m_ptr (0)
00817         {}
00818         
00819         type (pointer ptr,
00820               const difference_type *,
00821               const difference_type *)
00822             : m_ptr (ptr)
00823         {}
00824 
00825         void operator++ ()
00826         {
00827             ++m_ptr;
00828         }
00829 
00830         void operator-- ()
00831         {
00832             --m_ptr;
00833         }
00834 
00835         type operator++ (int)
00836         {
00837             type ret = *this;
00838             ++(*this);
00839             return ret;
00840         }
00841 
00842         type operator-- (int)
00843         {
00844             type ret = *this;
00845             --(*this);
00846             return ret;
00847         }
00848 
00849         type &operator+= (difference_type n)
00850         {
00851             m_ptr += n;
00852             return *this;
00853         }
00854 
00855         type & operator+= (multi_difference_type const & d)
00856         {
00857             m_ptr += d[level];
00858             return *this;
00859         }
00860 
00861         type &operator-= (difference_type n)
00862         {
00863             m_ptr -= n;
00864             return *this;
00865         }
00866 
00867         type & operator-= (multi_difference_type const & d)
00868         {
00869             m_ptr -= d[level];
00870             return *this;
00871         }
00872 
00873         reference operator* () const
00874         {
00875             return *m_ptr;
00876         }
00877 
00878         pointer operator->() const
00879         {
00880             return &(operator*());
00881         }
00882 
00883         reference operator[] (difference_type n) const
00884         {
00885             return m_ptr [n];
00886         }
00887 
00888         reference operator[] (multi_difference_type const & d) const
00889         {
00890             return m_ptr [d[level]];
00891         }
00892         
00893         difference_type operator- (type const & d) const
00894         {
00895             return (d.m_ptr - m_ptr);
00896         }
00897 
00898         bool operator!= (const type &rhs) const
00899         {
00900             return m_ptr != rhs.m_ptr;
00901         }
00902 
00903         bool operator== (const type &rhs) const
00904         {
00905             return m_ptr == rhs.m_ptr;
00906         }
00907 
00908         bool operator< (const type &rhs) const
00909         {
00910             return m_ptr < rhs.m_ptr;
00911         }
00912         
00913       protected:
00914       
00915         difference_type 
00916         total_stride(typename multi_difference_type::const_iterator d) const
00917         {
00918             return d[level];
00919         }
00920     };
00921 };
00922 
00923 /********************************************************/
00924 /*                                                      */
00925 /*                      MultiIterator                   */
00926 /*                                                      */
00927 /********************************************************/
00928 
00929 /** \brief A multi-dimensional hierarchical iterator to be used with 
00930            \ref vigra::MultiArrayView if it is not strided.
00931 
00932 This class wraps the MultiIteratorBase in a template of arity two.
00933 
00934 <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/multi_iterator.hxx</a>"
00935 
00936 Namespace: vigra
00937 */
00938 template <unsigned int N, class T, class REFERENCE, class POINTER>
00939 class MultiIterator 
00940 : public MultiIteratorBase <N>::template type <T, REFERENCE, POINTER>
00941 {
00942 public:
00943 
00944         /** the type of the parent in the inheritance hierarchy.
00945          */
00946     typedef typename MultiIteratorBase <N>::template type <T, REFERENCE, POINTER> base_type;
00947 
00948         /** the iterator's value type
00949          */
00950     typedef T value_type;
00951 
00952         /** reference type (result of operator[])
00953          */
00954     typedef value_type &reference;
00955 
00956         /** const reference type (result of operator[] const)
00957          */
00958     typedef const value_type &const_reference;
00959 
00960         /** pointer type
00961          */
00962     typedef value_type *pointer;
00963 
00964         /** const pointer type
00965          */
00966     typedef const value_type *const_pointer;
00967 
00968         /** difference type (used for offsetting)
00969          */
00970     typedef ptrdiff_t difference_type;
00971 
00972         /** multi difference type 
00973             (used for offsetting along all axes simultaneously)
00974          */
00975     typedef TinyVector<difference_type, N> multi_difference_type;
00976     
00977         /** the MultiIterator for the next lower dimension.
00978          */
00979     typedef typename base_type::next_type next_type;
00980 
00981         /** the iterator tag (image traverser)
00982         */
00983     typedef multi_dimensional_traverser_tag iterator_category;
00984             
00985     /* use default copy constructor and assignment operator */
00986 
00987         /** default constructor.
00988         */
00989     MultiIterator ()
00990     {}
00991 
00992         /** construct from pointer, strides (offset of a sample to the
00993             next) for every dimension, and the shape.
00994         */
00995     MultiIterator (pointer ptr,
00996                    const difference_type *stride,
00997                    const difference_type *shape)
00998         : base_type (ptr, stride, shape)
00999     {}
01000 
01001         /** addition within current dimension
01002          */
01003     MultiIterator operator+ (difference_type n) const
01004     {
01005         MultiIterator ret = *this;
01006         ret += n;
01007         return ret;
01008     }
01009 
01010         /** addition along all dimensions
01011          */
01012     MultiIterator operator+ (multi_difference_type const & d) const
01013     {
01014         MultiIterator ret = *this;
01015         ret += d;
01016         return ret;
01017     }
01018 
01019         /** subtraction within current dimension
01020          */
01021     MultiIterator operator- (difference_type n) const
01022     {
01023         MultiIterator ret = *this;
01024         ret -= n;
01025         return ret;
01026     }
01027 
01028         /** subtraction along all dimensions
01029          */
01030     MultiIterator operator- (multi_difference_type const & d) const
01031     {
01032         MultiIterator ret = *this;
01033         ret -= d;
01034         return ret;
01035     }
01036 
01037         /** Return the multi-iterator that operates on dimension K in order
01038             to manipulate this dimension directly. Usage:
01039                
01040             \code
01041                 
01042             MultiIterator<3, int> i3 = ...;
01043                 
01044             i3.dim<2>()++;  // increment outer dimension
01045             i3.dim<0>()++;  // increment inner dimension
01046             \endcode
01047         */
01048     template <unsigned int K>
01049     MultiIterator<K+1, T, REFERENCE, POINTER> &
01050     dim()
01051     {
01052         return *this;
01053     }
01054 };
01055 
01056 
01057 template <unsigned int N, class T, class REFERENCE, class POINTER> class StridedMultiIterator;
01058 
01059 /********************************************************/
01060 /*                                                      */
01061 /*               StridedMultiIteratorBase               */
01062 /*                                                      */
01063 /********************************************************/
01064 
01065 /** \brief Encloses the base class for \ref vigra::StridedMultiIterator.
01066 
01067 This design is necessary for compilers that do not support partial
01068 specialization (otherwise, StridedMultiIterator could be specialized directly).
01069 
01070 <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/multi_iterator.hxx</a>"
01071 
01072 Namespace: vigra
01073 */
01074 template <unsigned int N>
01075 class StridedMultiIteratorBase
01076 {
01077   public:
01078         /** \brief Base class for \ref vigra::StridedMultiIterator.
01079 
01080         This class implements the multi-iterator for strided arrays
01081         by means of the enclosed template 
01082         class <tt>type</tt>. This design is necessary for compilers that do not support partial
01083         specialization (otherwise, MultiIterator could be specialized directly).
01084 
01085         <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/multi_iterator.hxx</a>"
01086 
01087         Namespace: vigra
01088         */
01089     template <class T, class REFERENCE, class POINTER>
01090     class type : public StridedMultiIterator <N-1, T, REFERENCE, POINTER>
01091     {
01092     public:
01093 
01094             /** the type of the parent in the inheritance hierarchy.
01095              */
01096         typedef StridedMultiIterator <N-1, T, REFERENCE, POINTER> base_type;
01097 
01098     public:
01099         
01100             /** the iterator's level in the dimension hierarchy
01101              */
01102         enum { level = N-1 };
01103 
01104             /** the iterator's value type
01105              */
01106         typedef T value_type;
01107 
01108             /** reference type (result of operator[])
01109              */
01110         typedef value_type &reference;
01111 
01112             /** const reference type (result of operator[] const)
01113              */
01114         typedef const value_type &const_reference;
01115 
01116             /** pointer type
01117              */
01118         typedef value_type *pointer;
01119 
01120             /** const pointer type
01121              */
01122         typedef const value_type *const_pointer;
01123 
01124             /** difference type (used for offsetting)
01125              */
01126         typedef ptrdiff_t difference_type;
01127 
01128             /** multi difference type 
01129                 (used for offsetting along all axes simultaneously)
01130              */
01131         typedef TinyVector<difference_type, N> multi_difference_type;
01132 
01133             /** the next type, this is a non-standard typedef denoting the
01134                 type of the multi-iterator with the next-lower dimension.
01135             */
01136         typedef StridedMultiIterator <level, T, REFERENCE, POINTER> next_type;
01137 
01138             /** the iterator tag (image traverser)
01139             */
01140         typedef multi_dimensional_traverser_tag iterator_category;
01141             
01142         /* use default copy constructor and assignment operator */
01143             
01144             /** default constructor.
01145             */
01146         type ()
01147         {}
01148 
01149             /** construct from pointer, strides (offset of a sample to the
01150                 next) for every dimension, and the shape.
01151             */
01152         type (pointer ptr,
01153               const difference_type *stride,
01154               const difference_type *shape)
01155             : base_type (ptr, stride, shape)
01156         {}
01157 
01158             /** prefix-increment the iterator in it's current dimension
01159              */
01160         void operator++ ()
01161         {
01162             m_ptr += m_stride [level];
01163         }
01164 
01165             /** prefix-decrement the iterator in it's current dimension
01166              */
01167         void operator-- ()
01168         {
01169             m_ptr -= m_stride [level];
01170         }
01171 
01172             /** postfix-increment the iterator in it's current dimension
01173              */
01174         type operator++ (int)
01175         {
01176             type ret = *this;
01177             ++(*this);
01178             return ret;
01179         }
01180 
01181             /** postfix-decrement the iterator in it's current dimension
01182              */
01183         type operator-- (int)
01184         {
01185             type ret = *this;
01186             --(*this);
01187             return ret;
01188         }
01189 
01190             /** increment the iterator in it's current dimension
01191                 by the given value.
01192             */
01193         type &operator+= (difference_type n)
01194         {
01195             m_ptr += n * m_stride [level];
01196             return *this;
01197         }
01198 
01199             /** increment the iterator in all dimensions
01200                 by the given offset.
01201             */
01202         type & operator+= (multi_difference_type const & d)
01203         {
01204             m_ptr += total_stride(d.begin());
01205             return *this;
01206         }
01207 
01208             /** decrement the iterator in it's current dimension
01209                 by the given value.
01210             */
01211         type &operator-= (difference_type n)
01212         {
01213             m_ptr -= n * m_stride [level];
01214             return *this;
01215         }
01216 
01217             /** decrement the iterator in all dimensions
01218                 by the given offset.
01219             */
01220         type & operator-= (multi_difference_type const & d)
01221         {
01222             m_ptr -= total_stride(d.begin());
01223             return *this;
01224         }
01225         
01226             /** difference of two iterators in the current dimension.
01227                 The result of this operation is undefined if the iterator
01228                 doesn't point to element 0 in all dimensions below its current dimension.
01229             */
01230         difference_type operator- (type const & d) const
01231         {
01232             return (d.m_ptr - m_ptr) / m_stride[level];
01233         }
01234 
01235         /* operators *, ->, ==, !=, < inherited */
01236 
01237             /** access the array element at the given offset
01238                 in the iterator's current dimension.
01239             */
01240         reference operator[] (difference_type n) const
01241         {
01242             return m_ptr [n* m_stride [level]];
01243         }
01244 
01245             /** access the array element at the given offset.
01246             */
01247         reference operator[] (multi_difference_type const & d) const
01248         {
01249             return m_ptr [total_stride(d.begin())];
01250         }
01251         
01252             /** Return the (N-1)-dimensional multi-iterator that points to 
01253                 the first (N-1)-dimensional subarray of the 
01254                 N-dimensional array this iterator is referring to.
01255                 The result is only valid if this iterator refers to location
01256                 0 in <em>all</em> dimensions below its current dimension N,
01257                 otherwise it is undefined. Usage:
01258                 
01259                 \code
01260                 
01261                 MultiIterator<2, int> outer = ...;  // this iterator
01262                 
01263                 MultiIterator<2, int>::next_type inner = outer.begin();
01264                 for(; inner != outer.end(); ++inner)
01265                 {
01266                     // manipulate current 1D subimage
01267                 }
01268                 \endcode
01269             */
01270         next_type begin () const
01271         {
01272             return *this;
01273         }
01274 
01275             /** Return the (N-1)-dimensional multi-iterator that points beyond 
01276                 the last (N-1)-dimensional subarray of the 
01277                 N-dimensional array this iterator is referring to.
01278                 The result is only valid if this iterator refers to location
01279                 0 in <em>all</em> dimensions below its current dimension N,
01280                 otherwise it is undefined. Usage:
01281             */
01282         next_type end () const
01283         {
01284             next_type ret = *this;
01285             ret += m_shape [level-1];
01286             return ret;
01287         }
01288         
01289       protected:
01290       
01291         difference_type 
01292         total_stride(typename multi_difference_type::const_iterator d) const
01293         {
01294             return d[level]*m_stride[level] + base_type::total_stride(d);
01295         }
01296     };
01297 };
01298 
01299 /********************************************************/
01300 /*                                                      */
01301 /*              StridedMultiIteratorBase <2>            */
01302 /*                                                      */
01303 /********************************************************/
01304 
01305 //
01306 template <>
01307 class StridedMultiIteratorBase <2>
01308 {
01309   public:
01310     template <class T, class REFERENCE, class POINTER>
01311     class type : public StridedMultiIterator <1, T, REFERENCE, POINTER>
01312     {
01313     public:
01314         enum { level = 1 };
01315         typedef StridedMultiIterator <1, T, REFERENCE, POINTER> base_type;
01316         typedef T value_type;
01317         typedef value_type &reference;
01318         typedef const value_type &const_reference;
01319         typedef value_type *pointer;
01320         typedef const value_type *const_pointer;
01321         typedef ptrdiff_t difference_type;
01322         typedef TinyVector<difference_type, 2> multi_difference_type;
01323         typedef StridedMultiIterator <1, T, REFERENCE, POINTER> next_type;
01324         typedef multi_dimensional_traverser_tag iterator_category;
01325 
01326         const difference_type *m_stride;
01327         const difference_type *m_shape;
01328             
01329         /* use default copy constructor and assignment operator */
01330             
01331         type ()
01332             : base_type (),
01333               m_stride (0), m_shape (0)
01334         {}
01335 
01336         type (pointer ptr,
01337               const difference_type *stride,
01338               const difference_type *shape)
01339             : base_type (ptr, stride, shape),
01340               m_stride (stride), m_shape (shape)
01341         {}
01342 
01343         void operator++ ()
01344         {
01345             m_ptr += m_stride [level];
01346         }
01347 
01348         void operator-- ()
01349         {
01350             m_ptr -= m_stride [level];
01351         }
01352 
01353         type operator++ (int)
01354         {
01355             type ret = *this;
01356             ++(*this);
01357             return ret;
01358         }
01359 
01360         type operator-- (int)
01361         {
01362             type ret = *this;
01363             --(*this);
01364             return ret;
01365         }
01366 
01367         type &operator+= (int n)
01368         {
01369             m_ptr += n * m_stride [level];
01370             return *this;
01371         }
01372 
01373         type & operator+= (multi_difference_type const & d)
01374         {
01375             m_ptr += total_stride(d.begin());
01376             return *this;
01377         }
01378 
01379         type  &operator-= (difference_type n)
01380         {
01381             m_ptr -= n * m_stride [level];
01382             return *this;
01383         }
01384         
01385         type & operator-= (multi_difference_type const & d)
01386         {
01387             m_ptr -= total_stride(d.begin());
01388             return *this;
01389         }
01390 
01391         reference operator[] (difference_type n) const
01392         {
01393             return m_ptr [n*m_stride [level]];
01394         }
01395         
01396         difference_type operator- (type const & d) const
01397         {
01398             return (d.m_ptr - m_ptr) / m_stride[level];
01399         }
01400 
01401         reference operator[] (multi_difference_type const & d) const
01402         {
01403             return m_ptr [total_stride(d.begin())];
01404         }
01405 
01406         next_type begin () const
01407         {
01408             return *this;
01409         }
01410 
01411         next_type end () const
01412         {
01413             next_type ret = *this;
01414             ret += m_shape [level-1];
01415             return ret;
01416         }
01417 
01418       protected:
01419       
01420         difference_type 
01421         total_stride(typename multi_difference_type::const_iterator d) const
01422         {
01423             return d[level]*m_stride[level] + base_type::total_stride(d);
01424         }
01425     };
01426 };
01427 
01428 /********************************************************/
01429 /*                                                      */
01430 /*               StridedMultiIteratorBase <1>           */
01431 /*                                                      */
01432 /********************************************************/
01433 
01434 //
01435 template <>
01436 class StridedMultiIteratorBase <1>
01437 {
01438   public:
01439     template <class T, class REFERENCE, class POINTER>
01440     class type
01441     {
01442     public:
01443 
01444         enum { level = 0 };
01445         typedef T value_type;
01446         typedef value_type &reference;
01447         typedef const value_type &const_reference;
01448         typedef value_type *pointer;
01449         typedef const value_type *const_pointer;
01450         typedef ptrdiff_t difference_type;
01451         typedef TinyVector<difference_type, 1> multi_difference_type;
01452         typedef void next_type;
01453         typedef multi_dimensional_traverser_tag iterator_category;
01454         
01455         pointer m_ptr;
01456         difference_type m_stride;
01457             
01458         /* use default copy constructor and assignment operator */
01459             
01460         type ()
01461             : m_ptr (0), m_stride (0)
01462         {}
01463 
01464         type (pointer ptr,
01465               const difference_type *stride,
01466               const difference_type *)
01467             : m_ptr (ptr), m_stride (stride [level])
01468         {}
01469 
01470         reference operator* () const
01471         {
01472             return *m_ptr;
01473         }
01474 
01475         pointer operator-> () const
01476         {
01477             return &(operator*());
01478         }
01479 
01480         void operator++ ()
01481         {
01482             m_ptr += m_stride;
01483         }
01484 
01485         void operator-- ()
01486         {
01487             m_ptr -= m_stride;
01488         }
01489 
01490         type operator++ (int)
01491         {
01492             type ret = *this;
01493             ++(*this);
01494             return ret;
01495         }
01496 
01497         type operator-- (int)
01498         {
01499             type ret = *this;
01500             --(*this);
01501             return ret;
01502         }
01503 
01504         type &operator+= (difference_type n)
01505         {
01506             m_ptr += n * m_stride;
01507             return *this;
01508         }
01509 
01510         type & operator+= (multi_difference_type const & d)
01511         {
01512             m_ptr += d[level] * m_stride;
01513             return *this;
01514         }
01515 
01516         type &operator-= (difference_type n)
01517         {
01518             m_ptr -= n * m_stride;
01519             return *this;
01520         }
01521         
01522         type & operator-= (multi_difference_type const & d)
01523         {
01524             m_ptr -= d[level] * m_stride;
01525             return *this;
01526         }
01527         
01528         difference_type operator- (type const & d) const
01529         {
01530             return (d.m_ptr - m_ptr) / m_stride;
01531         }
01532 
01533         reference operator[] (difference_type n) const
01534         {
01535             return m_ptr [n*m_stride];
01536         }
01537 
01538         reference operator[] (multi_difference_type const & d) const
01539         {
01540             return m_ptr [d[level]*m_stride];
01541         }
01542 
01543         bool operator!= (const type &rhs) const
01544         {
01545             return m_ptr != rhs.m_ptr;
01546         }
01547 
01548         bool operator== (const type &rhs) const
01549         {
01550             return m_ptr == rhs.m_ptr;
01551         }
01552 
01553         bool operator< (const type &rhs) const
01554         {
01555             return m_ptr < rhs.m_ptr;
01556         }
01557 
01558       protected:
01559       
01560         difference_type 
01561         total_stride(typename multi_difference_type::const_iterator d) const
01562         {
01563             return d[level]*m_stride;
01564         }
01565     };
01566 };
01567 
01568 /********************************************************/
01569 /*                                                      */
01570 /*                 StridedMultiIterator                 */
01571 /*                                                      */
01572 /********************************************************/
01573 
01574 /** \brief A multi-dimensional hierarchical iterator to be used with 
01575            \ref vigra::MultiArrayView is it is strided.
01576 
01577 This class wraps the StridedMultiIteratorBase in a template of arity two.
01578 
01579 <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/multi_iterator.hxx</a>"
01580 
01581 Namespace: vigra
01582 */
01583 template <unsigned int N, class T, class REFERENCE, class POINTER>
01584 class StridedMultiIterator
01585     : public StridedMultiIteratorBase <N>::template type <T, REFERENCE, POINTER>
01586 {
01587 public:
01588 
01589         /** the type of the parent in the inheritance hierarchy.
01590          */
01591     typedef typename StridedMultiIteratorBase <
01592         N>::template type <T, REFERENCE, POINTER> base_type;
01593 
01594         /** the iterator's value type
01595          */
01596     typedef T value_type;
01597 
01598         /** reference type (result of operator[])
01599          */
01600     typedef value_type &reference;
01601 
01602         /** const reference type (result of operator[] const)
01603          */
01604     typedef const value_type &const_reference;
01605 
01606         /** pointer type
01607          */
01608     typedef value_type *pointer;
01609 
01610         /** const pointer type
01611          */
01612     typedef const value_type *const_pointer;
01613 
01614         /** difference type (used for offsetting)
01615          */
01616     typedef ptrdiff_t difference_type;
01617 
01618         /** multi difference type 
01619             (used for offsetting along all axes simultaneously)
01620          */
01621     typedef TinyVector<difference_type, N> multi_difference_type;
01622     
01623         /** the StridedMultiIterator for the next lower dimension.
01624          */
01625     typedef typename base_type::next_type next_type;
01626 
01627         /** the iterator tag (image traverser)
01628         */
01629     typedef multi_dimensional_traverser_tag iterator_category;
01630             
01631     /* use default copy constructor and assignment operator */
01632 
01633         /** default constructor.
01634         */
01635     StridedMultiIterator ()
01636     {}
01637 
01638         /** construct from pointer, strides (offset of a sample to the
01639             next) for every dimension, and the shape.
01640         */
01641     StridedMultiIterator (T *ptr,
01642                           const difference_type *stride,
01643                           const difference_type *shape)
01644         : base_type (ptr, stride, shape)
01645     {}
01646 
01647         /** addition within current dimension
01648          */
01649     StridedMultiIterator operator+ (difference_type n) const
01650     {
01651         StridedMultiIterator ret = *this;
01652         ret += n;
01653         return ret;
01654     }
01655 
01656         /** addition along all dimensions
01657          */
01658     StridedMultiIterator operator+ (multi_difference_type const & d) const
01659     {
01660         StridedMultiIterator ret = *this;
01661         ret += d;
01662         return ret;
01663     }
01664 
01665         /** subtraction within current dimension
01666          */
01667     StridedMultiIterator operator- (difference_type n) const
01668     {
01669         StridedMultiIterator ret = *this;
01670         ret -= n;
01671         return ret;
01672     }
01673 
01674         /** subtraction along all dimensions
01675          */
01676     StridedMultiIterator operator- (multi_difference_type const & d) const
01677     {
01678         StridedMultiIterator ret = *this;
01679         ret -= d;
01680         return ret;
01681     }
01682 
01683         /** Return the multi-iterator that operates on dimension K in order
01684             to manipulate this dimension directly. Usage:
01685                 
01686             \code
01687             
01688             StridedMultiIterator<3, int> i3 = ...;
01689                 
01690             i3.dim<2>()++;  // increment outer dimension
01691             i3.dim<0>()++;  // increment inner dimension
01692             \endcode
01693         */
01694     template <unsigned int K>
01695     StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
01696     dim()
01697     {
01698         return *this;
01699     }
01700 };
01701 
01702 //@}
01703 
01704 } // namespace vigra
01705 
01706 #endif // VIGRA_MULTI_ITERATOR_HXX

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.2.0 (7 Aug 2003)