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