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