00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00035 #ifndef SCYTHE_MATRIX_FORWARD_ITERATOR_H
00036 #define SCYTHE_MATRIX_FORWARD_ITERATOR_H
00037
00038 #include <iterator>
00039
00040 #ifdef SCYTHE_COMPILE_DIRECT
00041 #include "defs.h"
00042 #include "error.h"
00043 #include "matrix.h"
00044 #else
00045 #include "scythestat/defs.h"
00046 #include "scythestat/error.h"
00047 #include "scythestat/matrix.h"
00048 #endif
00049
00050 namespace scythe {
00051
00052 namespace {
00053 typedef unsigned int uint;
00054 }
00055
00056
00057 template <typename T_type, matrix_order ORDER, matrix_style STYLE>
00058 class Matrix;
00059
00074 template <typename T_type, matrix_order ORDER, matrix_order M_ORDER,
00075 matrix_style M_STYLE>
00076 class const_matrix_forward_iterator
00077 : public std::iterator<std::forward_iterator_tag, T_type>
00078 {
00079 public:
00080
00081 typedef const_matrix_forward_iterator<T_type, ORDER,
00082 M_ORDER, M_STYLE> self;
00083
00084
00085 typedef typename std::iterator_traits<self>::value_type
00086 value_type;
00087 typedef typename std::iterator_traits<self>::iterator_category
00088 iterator_category;
00089 typedef typename std::iterator_traits<self>::difference_type
00090 difference_type;
00091 typedef typename std::iterator_traits<self>::pointer pointer;
00092 typedef typename std::iterator_traits<self>::reference reference;
00093
00094
00095
00096
00097
00098 const_matrix_forward_iterator ()
00099 {}
00100
00101
00102 const_matrix_forward_iterator
00103 (const Matrix<value_type, M_ORDER, M_STYLE> &M)
00104 : pos_ (M.getArray()),
00105 matrix_ (&M)
00106 {
00107 SCYTHE_CHECK_30 (pos_ == 0, scythe_null_error,
00108 "Requesting iterator to NULL matrix");
00109
00110
00111
00112
00113
00114
00115
00116
00117 if (M_STYLE != Concrete || M_ORDER != ORDER) {
00118 offset_ = 0;
00119
00120 if (ORDER == Col) {
00121 lead_length_ = M.rows();
00122 lead_inc_ = M.rowstride();
00123 trail_inc_ = M.colstride();
00124 } else {
00125 lead_length_ = M.cols();
00126 lead_inc_ = M.colstride();
00127 trail_inc_ = M.rowstride();
00128 }
00129 jump_ = trail_inc_ + (1 - lead_length_) * lead_inc_;
00130 vend_ = pos_ + (lead_length_ - 1) * lead_inc_;
00131 }
00132 #if SCYTHE_DEBUG > 2
00133 size_ = M.size();
00134 start_ = pos_;
00135 #endif
00136 }
00137
00138
00139 const_matrix_forward_iterator (const self &mi)
00140 : pos_ (mi.pos_),
00141 matrix_ (mi.matrix_)
00142 {
00143 if (M_STYLE != Concrete || M_ORDER != ORDER) {
00144 offset_ = mi.offset_;
00145 lead_length_ = mi.lead_length_;
00146 lead_inc_ = mi.lead_inc_;
00147 trail_inc_ = mi.trail_inc_;
00148 vend_ = mi.vend_;
00149 jump_ = mi.jump_;
00150 }
00151 #if SCYTHE_DEBUG > 2
00152 size_ = mi.size_;
00153 start_ = mi.start_;
00154 #endif
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 inline self& set_end ()
00164 {
00165 if (M_STYLE == Concrete && ORDER == M_ORDER) {
00166 pos_ = matrix_->getArray() + matrix_->size();
00167 } else {
00168 offset_ = matrix_->size();
00169 }
00170
00171 return *this;
00172 }
00173
00174
00175
00176
00177 unsigned int get_index () const
00178 {
00179 return offset_;
00180 }
00181
00182
00183
00184 inline self& operator= (const self& mi)
00185 {
00186 pos_ = mi.pos_;
00187 matrix_ = mi.matrix_;
00188
00189 if (M_STYLE != Concrete || M_ORDER != ORDER) {
00190 offset_ = mi.offset_;
00191 lead_length_ = mi.lead_length_;
00192 lead_inc_ = mi.lead_inc_;
00193 trail_inc_ = mi.trail_inc_;
00194 vend_ = mi.vend_;
00195 jump_ = mi.jump_;
00196 }
00197 #if SCYTHE_DEBUG > 2
00198 size_ = mi.size_;
00199 start_ = mi.start_;
00200 #endif
00201
00202 return *this;
00203 }
00204
00205 inline const reference operator* () const
00206 {
00207 SCYTHE_ITER_CHECK_BOUNDS();
00208 return *pos_;
00209 }
00210
00211 inline const pointer operator-> () const
00212 {
00213 SCYTHE_ITER_CHECK_BOUNDS();
00214 return pos_;
00215 }
00216
00217 inline self& operator++ ()
00218 {
00219 if (M_STYLE == Concrete && ORDER == M_ORDER)
00220 ++pos_;
00221 else {
00222 if (pos_ == vend_) {
00223 vend_ += trail_inc_;
00224 pos_ += jump_;
00225 } else {
00226 pos_ += lead_inc_;
00227 }
00228 ++offset_;
00229 }
00230
00231 return *this;
00232 }
00233
00234 inline self operator++ (int)
00235 {
00236 self tmp = *this;
00237 ++(*this);
00238 return tmp;
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 inline bool operator== (const self& x) const
00255 {
00256 if (M_STYLE == Concrete && ORDER == M_ORDER) {
00257 return pos_ == x.pos_;
00258 } else {
00259 return offset_ == x.offset_;
00260 }
00261 }
00262
00263
00264
00265
00266
00267 inline bool operator!= (const self &x) const
00268 {
00269 return !(*this == x);
00270 }
00271
00272 protected:
00273
00274
00275 T_type* pos_;
00276 T_type *vend_;
00277
00278 uint offset_;
00279
00280
00281 int lead_length_;
00282 int lead_inc_;
00283 int trail_inc_;
00284 int jump_;
00285
00286
00287
00288
00289 const Matrix<T_type, M_ORDER, M_STYLE>* matrix_;
00290
00291 #if SCYTHE_DEBUG > 2
00292 uint size_;
00293 T_type* start_;
00294 #endif
00295 };
00296
00310 template <typename T_type, matrix_order ORDER, matrix_order M_ORDER,
00311 matrix_style M_STYLE>
00312 class matrix_forward_iterator
00313 : public const_matrix_forward_iterator<T_type, ORDER,
00314 M_ORDER, M_STYLE>
00315 {
00316
00317 typedef matrix_forward_iterator<T_type, ORDER, M_ORDER,
00318 M_STYLE> self;
00319 typedef const_matrix_forward_iterator<T_type, ORDER,
00320 M_ORDER, M_STYLE> Base;
00321
00322 public:
00323
00324 typedef typename std::iterator_traits<Base>::value_type
00325 value_type;
00326 typedef typename std::iterator_traits<Base>::iterator_category
00327 iterator_category;
00328 typedef typename std::iterator_traits<Base>::difference_type
00329 difference_type;
00330 typedef typename std::iterator_traits<Base>::pointer pointer;
00331 typedef typename std::iterator_traits<Base>::reference reference;
00332
00333
00334
00335
00336
00337 matrix_forward_iterator ()
00338 : Base ()
00339 {}
00340
00341
00342 matrix_forward_iterator (const Matrix<value_type, M_ORDER,
00343 M_STYLE> &M)
00344 : Base(M)
00345 {}
00346
00347
00348 matrix_forward_iterator (const self &mi)
00349 : Base (mi)
00350 {}
00351
00352
00353 inline self& set_end ()
00354 {
00355 Base::set_end();
00356 return *this;
00357 }
00358
00359
00360
00361
00362
00363 inline self& operator= (const self& mi)
00364 {
00365 pos_ = mi.pos_;
00366 matrix_ = mi.matrix_;
00367
00368 if (M_STYLE != Concrete || M_ORDER != ORDER) {
00369 offset_ = mi.offset_;
00370 lead_length_ = mi.lead_length_;
00371 lead_inc_ = mi.lead_inc_;
00372 trail_inc_ = mi.trail_inc_;
00373 vend_ = mi.vend_;
00374 jump_ = mi.jump_;
00375 }
00376 #if SCYTHE_DEBUG > 2
00377 size_ = mi.size_;
00378 start_ = mi.start_;
00379 #endif
00380
00381 return *this;
00382 }
00383
00384 inline reference operator* () const
00385 {
00386 SCYTHE_ITER_CHECK_BOUNDS();
00387 return *pos_;
00388 }
00389
00390 inline pointer operator-> () const
00391 {
00392 SCYTHE_ITER_CHECK_BOUNDS();
00393 return pos_;
00394 }
00395
00396 inline self& operator++ ()
00397 {
00398 Base::operator++();
00399 return *this;
00400 }
00401
00402 inline self operator++ (int)
00403 {
00404 self tmp = *this;
00405 ++(*this);
00406 return tmp;
00407 }
00408
00409 private:
00410
00411 using Base::pos_;
00412 using Base::vend_;
00413 using Base::offset_;
00414 using Base::lead_length_;
00415 using Base::lead_inc_;
00416 using Base::trail_inc_;
00417 using Base::jump_;
00418 using Base::matrix_;
00419 #if SCYTHE_DEBUG > 2
00420 using Base::size_;
00421 using Base::start_;
00422 #endif
00423 };
00424
00425 }
00426
00427 #endif