[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
vigra/navigator.hxx | ![]() |
---|
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 2004 by Ullrich Koethe */ 00004 /* Cognitive Systems Group, University of Hamburg, Germany */ 00005 /* */ 00006 /* This file is part of the VIGRA computer vision library. */ 00007 /* ( Version 1.5.0, Dec 07 2006 ) */ 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 /* koethe@informatik.uni-hamburg.de or */ 00012 /* vigra@kogs1.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 #ifndef VIGRA_NAVIGATOR_HXX 00039 #define VIGRA_NAVIGATOR_HXX 00040 00041 namespace vigra { 00042 00043 /********************************************************/ 00044 /* */ 00045 /* MultiArrayNavigator */ 00046 /* */ 00047 /********************************************************/ 00048 00049 /** \brief A navigator that provides acces to the 1D subranges of an 00050 n-dimensional range given by a \ref vigra::MultiIterator and an nD shape. 00051 00052 Normally, the innermost loop of an iteration extends over the innermost 00053 dimension of a given array. Sometimes, however, it is necessary to have 00054 some other dimension in the inner loop. For example, instead of iterating over 00055 the rows, the inner loop should extend over the columns. The class MultiArrayNavigator 00056 encapsulates the necessary functionality. Given an arbitrary dimensional 00057 array (represented by a vigra::MultiIterator/shape pair), and the desired 00058 inner loop dimension <TT>d</TT>, it moves the encapsulated iterator to all possible 00059 starting points of 1D subsets along the given dimension (e.g. all columns). By calling 00060 <TT>begin()</TT> and <TT>end()</TT>, one can then obtain an STL-compatible 1-dimensional 00061 iterator for the current subset. 00062 00063 The template parameters specify the embedded iterator type and its dimension. 00064 00065 <b>Usage:</b> 00066 00067 <b>\#include</b> "<a href="navigator_8hxx-source.html">vigra/navigator.hxx</a>" 00068 00069 Namespace: vigra 00070 00071 \code 00072 typedef vigra::MultiArray<3, int> Array; 00073 00074 Array a(Array::size_type(X, Y, Z)); 00075 00076 typedef vigra::MultiArrayNavigator<Array::traverser, 3> Navigator; 00077 00078 for(int d=0; d<3; ++d) 00079 { 00080 // create Navigator for dimension d 00081 Navigator nav(a.traverser_begin(), a.shape(), d); 00082 00083 // outer loop: move navigator to all starting points 00084 // of 1D subsets that run parallel to coordinate axis d 00085 for(; nav.hasMore(); ++nav) 00086 { 00087 // inner loop: linear iteration over current subset 00088 // d == {0, 1, 2}: interate along {x, y, z}-axis respectively 00089 Navigator::iterator i = nav.begin(), end = nav.end(); 00090 for(; i != end; ++i) 00091 // do something 00092 } 00093 } 00094 \endcode 00095 */ 00096 template <class MULTI_ITERATOR, unsigned int N> 00097 class MultiArrayNavigator 00098 #ifndef DOXYGEN // doxygen doesn't understand this inheritance 00099 : public MultiArrayNavigator<MULTI_ITERATOR, N-1> 00100 #endif 00101 { 00102 typedef MultiArrayNavigator<MULTI_ITERATOR, N-1> base_type; 00103 00104 public: 00105 enum { level = N-1 }; 00106 00107 /** The required shape type for the given iterator type. 00108 */ 00109 typedef typename MULTI_ITERATOR::multi_difference_type shape_type; 00110 00111 /** The iterator type for the inner loop (result of begin() and end()). 00112 */ 00113 typedef typename MULTI_ITERATOR::iterator iterator; 00114 00115 /** Construct navigator for multi-dimensional iterator <TT>i</TT>, array shape <TT>shape</TT> 00116 and inner loop dimension <TT>inner_dimension</TT>. 00117 */ 00118 MultiArrayNavigator(MULTI_ITERATOR const & i, shape_type const & shape, unsigned int inner_dimension) 00119 : base_type(i, shape, inner_dimension), 00120 i_(i), 00121 end_(i) 00122 { 00123 if(inner_dimension != level) 00124 end_.template dim<level>() += shape[level]; 00125 } 00126 00127 /** Advance to next starting location. 00128 */ 00129 void operator++() 00130 { 00131 base_type::operator++(); 00132 if(base_type::atEnd() && i_ < end_) // this tests implicitly inner_dimension_ != level 00133 { 00134 ++i_.template dim<level>(); 00135 if(i_ < end_) 00136 base_type::reset(i_); 00137 } 00138 } 00139 00140 /** Advance to next starting location. 00141 */ 00142 void operator++(int) 00143 { 00144 ++*this; 00145 } 00146 00147 /** true if there are more elements. 00148 */ 00149 bool hasMore() const 00150 { 00151 return this->inner_dimension_ == level ? 00152 base_type::hasMore() : 00153 i_ < end_; 00154 } 00155 00156 /** true if iterator is exhausted. 00157 */ 00158 bool atEnd() const 00159 { 00160 return this->inner_dimension_ == level ? 00161 base_type::atEnd() : 00162 !( i_ < end_); 00163 } 00164 00165 protected: 00166 void reset(MULTI_ITERATOR const & i) 00167 { 00168 end_ = i_ = i; 00169 if(this->inner_dimension_ != level) 00170 end_.template dim<level>() += this->shape_[level]; 00171 base_type::reset(i); 00172 } 00173 00174 MULTI_ITERATOR i_, end_; 00175 }; 00176 00177 template <class MULTI_ITERATOR> 00178 class MultiArrayNavigator<MULTI_ITERATOR, 1> 00179 { 00180 public: 00181 enum { level = 0 }; 00182 typedef typename MULTI_ITERATOR::multi_difference_type shape_type; 00183 typedef typename MULTI_ITERATOR::iterator iterator; 00184 00185 MultiArrayNavigator(MULTI_ITERATOR const & i, shape_type const & shape, unsigned int inner_dimension) 00186 : shape_(shape), 00187 inner_dimension_(inner_dimension), 00188 i_(i), 00189 end_(i) 00190 { 00191 if(inner_dimension != level) 00192 end_.template dim<level>() += shape[level]; 00193 } 00194 00195 void operator++() 00196 { 00197 ++i_.template dim<level>(); 00198 } 00199 00200 void operator++(int) 00201 { 00202 ++*this; 00203 } 00204 00205 iterator begin() const 00206 { 00207 return i_.iteratorForDimension(inner_dimension_); 00208 } 00209 00210 iterator end() const 00211 { 00212 return begin() + shape_[inner_dimension_]; 00213 } 00214 00215 bool hasMore() const 00216 { 00217 return i_ < end_; 00218 } 00219 00220 bool atEnd() const 00221 { 00222 return !( i_ < end_); 00223 } 00224 00225 protected: 00226 void reset(MULTI_ITERATOR const & i) 00227 { 00228 end_ = i_ = i; 00229 if(inner_dimension_ != level) 00230 end_.template dim<level>() += shape_[level]; 00231 } 00232 00233 shape_type shape_; 00234 unsigned int inner_dimension_; 00235 MULTI_ITERATOR i_, end_; 00236 }; 00237 00238 } // namespace vigra 00239 00240 #endif /* VIGRA_NAVIGATOR_HXX */
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|