Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_ITERATORS_H
00002 #define OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_ITERATORS_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <iterator>
00013
00014 namespace OpenTissue
00015 {
00016 namespace grid
00017 {
00018 namespace detail
00019 {
00020
00022 template <class grid_type_, class reference_type, class pointer_type>
00023 class Iterator
00024 : public std::iterator< std::random_access_iterator_tag, typename grid_type_::value_type >
00025 {
00026 public:
00027
00028 typedef grid_type_ grid_type;
00029 typedef typename grid_type::math_types math_types;
00030
00031 private:
00032
00033 typedef OpenTissue::grid::detail::Iterator<grid_type, reference_type, pointer_type> self_type;
00034
00035 protected:
00036
00037 typedef typename grid_type::index_vector index_vector;
00038 grid_type * m_grid;
00039 pointer_type m_pos;
00040
00041 public:
00042
00043
00044 grid_type & get_grid() { return *m_grid; }
00045 grid_type const & get_grid() const { return *m_grid; }
00046
00047 pointer_type const & get_pointer() const { return m_pos; }
00048 pointer_type & get_pointer() { return m_pos; }
00049
00050 public:
00051
00052 Iterator()
00053 : m_grid( 0 )
00054 , m_pos( 0 )
00055 {}
00056
00057 Iterator( grid_type * grid, pointer_type pos )
00058 : m_grid( grid )
00059 , m_pos( pos )
00060 {}
00061
00062 reference_type operator*()
00063 {
00064 return * m_pos;
00065 }
00066
00067 self_type operator++( int )
00068 {
00069 self_type tmp = *this;
00070 m_pos++;
00071 return tmp;
00072 }
00073
00074 self_type &operator++()
00075 {
00076 m_pos++;
00077 return *this;
00078 }
00079
00080 void operator+=( size_t m )
00081 {
00082 m_pos += m;
00083 }
00084
00085 self_type operator+ ( size_t m )
00086 {
00087 self_type tmp = *this;
00088 tmp.m_pos += m;
00089 return tmp;
00090 }
00091
00092 self_type operator- ( size_t m )
00093 {
00094 self_type tmp = *this;
00095 tmp.m_pos -= m;
00096 return tmp;
00097 }
00098
00099 self_type operator--( int )
00100 {
00101 self_type tmp = *this;
00102 m_pos--;
00103 return tmp;
00104 }
00105
00106 self_type &operator--()
00107 {
00108 m_pos--;
00109 return *this;
00110 }
00111
00112 void operator-=( size_t m ) { m_pos -= m; }
00113 int operator- ( self_type const & other ) const { return m_pos -other.m_pos; }
00114 bool operator< ( self_type const & other ) const { return m_pos < other.m_pos; }
00115 bool operator<=( self_type const & other ) const { return m_pos <= other.m_pos; }
00116 bool operator> ( self_type const & other ) const { return m_pos > other.m_pos; }
00117 bool operator>=( self_type const & other ) const { return m_pos >= other.m_pos; }
00118
00119
00120 index_vector compute_index() const
00121 {
00122 int offset = m_pos - m_grid->data();
00123 index_vector res;
00124 res(2) = offset / ( m_grid->J() * m_grid->I() );
00125 offset = offset % ( m_grid->J() * m_grid->I() );
00126 res(1) = offset / m_grid->I();
00127 res(0) = offset % m_grid->I();
00128 return res;
00129 }
00130
00131 void operator+=( index_vector const & idx )
00132 {
00133 m_pos += idx(0) + m_grid->I() * idx(1) + m_grid->I() * m_grid->J() * idx(2);
00134 }
00135
00136 self_type const & operator=( index_vector const & idx )
00137 {
00138 m_pos = m_grid->data() + idx(0) + m_grid->I() * idx(1) + m_grid->I() * m_grid->J() * idx(2);
00139 return *this;
00140 }
00141
00142 bool operator!=( self_type const & other )
00143 {
00144 return m_pos != other.m_pos;
00145 }
00146
00147 bool operator==( self_type const & other )
00148 {
00149 return m_pos == other.m_pos;
00150 }
00151 };
00152
00153
00155
00156 template <class grid_type, class reference_type, class pointer_type>
00157 class IndexIterator
00158 : public OpenTissue::grid::detail::Iterator<grid_type, reference_type, pointer_type>
00159 {
00160 public:
00161
00162 typedef typename grid_type::math_types math_types;
00163
00164 protected:
00165
00166 typedef typename math_types::vector3_type vector3_type;
00167 typedef typename math_types::index_vector3_type index_vector;
00168
00169 private:
00170
00171 typedef OpenTissue::grid::detail::Iterator<grid_type, reference_type, pointer_type> base_type;
00172 typedef OpenTissue::grid::detail::IndexIterator<grid_type, reference_type, pointer_type> self_type;
00173
00174
00175 size_t m_i;
00176 size_t m_j;
00177 size_t m_k;
00178
00179 static size_t const m_out_of_bounds = 0u - 1u;
00180
00181 void update_indices()
00182 {
00183 index_vector v = this->compute_index();
00184 m_i = v(0);
00185 m_j = v(1);
00186 m_k = v(2);
00187 }
00188
00189 public:
00190
00191 IndexIterator()
00192 : base_type()
00193 , m_i(0)
00194 , m_j(0)
00195 , m_k(0)
00196 {}
00197
00198 IndexIterator( base_type const& other )
00199 : base_type( other )
00200 {
00201 operator=( other );
00202 }
00203
00204 IndexIterator( grid_type * grid, pointer_type pos )
00205 : base_type( grid, pos )
00206 {
00207
00208 if ( this->m_pos != this->m_grid->data() )
00209 {
00210 base_type::operator=( base_type( this->m_grid, this->m_pos ).compute_index() );
00211 }
00212 }
00213
00214 public:
00215
00216 size_t const& i() const { return m_i; }
00217 size_t const& j() const { return m_j; }
00218 size_t const& k() const { return m_k; }
00219
00220 index_vector get_index() const
00221 {
00222 return index_vector( m_i, m_j, m_k );
00223 }
00224
00225 vector3_type get_coord() const
00226 {
00227 return vector3_type(
00228 m_i * this->m_grid->dx() + this->m_grid->min_coord( 0 )
00229 , m_j * this->m_grid->dy() + this->m_grid->min_coord( 1 )
00230 , m_k * this->m_grid->dz() + this->m_grid->min_coord( 2 )
00231 );
00232 }
00233
00234 public:
00235
00236 self_type operator++( int )
00237 {
00238 self_type tmp = *this;
00239 ++( *this );
00240 return tmp;
00241 }
00242
00243 self_type &operator++()
00244 {
00245 ++this->m_pos;
00246 ++m_i;
00247 if ( m_i >= this->m_grid->I() )
00248 {
00249 m_i = 0u;
00250 ++m_j;
00251 if ( m_j >= this->m_grid->J() )
00252 {
00253 m_j = 0u;
00254 ++m_k;
00255 }
00256 }
00257 return *this;
00258 }
00259
00260 self_type operator--( int )
00261 {
00262 self_type tmp = *this;
00263 --( *this );
00264 return tmp;
00265 }
00266
00267 self_type &operator--()
00268 {
00269 --this->m_pos;
00270 --m_i;
00271 if ( m_i == m_out_of_bounds )
00272 {
00273 m_i = this->m_grid->I() - 1;
00274 --m_j;
00275 if ( m_j == m_out_of_bounds )
00276 {
00277 m_j = this->m_grid->J() - 1;
00278 --m_k;
00279 }
00280 }
00281 return *this;
00282 }
00283
00284
00285 self_type const & operator=( index_vector const& idx )
00286 {
00287 m_i = idx(0);
00288 m_j = idx(1);
00289 m_k = idx(2);
00290 this->m_pos = &( *this->m_grid ) ( idx );
00291 return *this;
00292 }
00293
00294 void operator+=( size_t m )
00295 {
00296 this->m_pos += m;
00297 update_indices();
00298 }
00299
00300 void operator-=( size_t m )
00301 {
00302 this->m_pos -= m;
00303 update_indices();
00304 }
00305
00306 self_type operator+ ( size_t m )
00307 {
00308 self_type tmp = *this;
00309 tmp.m_pos += m;
00310 tmp.update_indices();
00311 return tmp;
00312 }
00313
00314 self_type operator- ( size_t m )
00315 {
00316 self_type tmp = *this;
00317 tmp.m_pos -= m;
00318 tmp.update_indices();
00319 return tmp;
00320 }
00321
00322 self_type const & operator= ( base_type const & other )
00323 {
00324 this->m_grid = const_cast<grid_type*>( &( other.get_grid() ) );
00325 this->m_pos = other.get_pointer();
00326 if ( this->m_pos == this->m_grid->data() )
00327 {
00328 m_i = 0u;
00329 m_j = 0u;
00330 m_k = 0u;
00331 }
00332 else
00333 {
00334 update_indices();
00335 }
00336 return *this;
00337 }
00338
00339 };
00340
00341 }
00342 }
00343 }
00344
00345
00346 #endif