[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
vigra/multi_iterator.hxx | ![]() |
---|
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<N, ..></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<ptrdiff_t, N></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<K+1, T, ...></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) |
html generated using doxygen and Python
|