00001 #ifndef BALL_LINALG_ELEMENTROWITERATOR_H
00002 #define BALL_LINALG_ELEMENTROWITERATOR_H
00003
00004 #ifndef BALL_LINALG_MATRIX_iH
00005 # include <BALL/MATHS/LINALG/matrix.ih>
00006 #endif
00007
00008 #ifndef BALL_CONCEPT_RANDOMACCESSITERATOR_H
00009 #include <BALL/CONCEPT/randomAccessIterator.h>
00010 #endif
00011
00012 namespace BALL {
00013
00014
00015 template <class valuetype, class mtraits>
00016 class Matrix;
00017
00018
00019 template <class valuetype, class mtraits=StandardTraits>
00020 class ElementRowIteratorTraits
00021 {
00024 typedef valuetype ValueType;
00025
00028 typedef valuetype* PointerType;
00029
00032 typedef int IteratorPosition;
00033
00036 typedef int Distance;
00037
00040 typedef int Index;
00041
00042 friend class Matrix<valuetype, mtraits>;
00043 public:
00044
00045 virtual ~ElementRowIteratorTraits()
00046 {
00047 }
00048
00049 ElementRowIteratorTraits()
00050 : bound_(0),
00051 position_(0)
00052 {
00053 }
00054
00055 ElementRowIteratorTraits(const Matrix<valuetype, mtraits>& matrix)
00056 : bound_(const_cast<Matrix<valuetype, mtraits>*>(&matrix)),
00057 position_(0)
00058 {
00059 }
00060
00061 ElementRowIteratorTraits(const ElementRowIteratorTraits& traits)
00062 : bound_(traits.bound_),
00063 position_(traits.position_)
00064 {
00065 }
00066
00067 ElementRowIteratorTraits& operator = (const ElementRowIteratorTraits& traits)
00068 {
00069 bound_ = traits.bound_;
00070 position_ = traits.position_;
00071
00072 return *this;
00073 }
00074
00075 Matrix<valuetype, mtraits>* getContainer()
00076 {
00077 return bound_;
00078 }
00079
00080 const Matrix<valuetype, mtraits>* getContainer() const
00081 {
00082 return bound_;
00083 }
00084
00085 bool isSingular() const
00086 {
00087 return (bound_ == 0);
00088 }
00089
00090 IteratorPosition& getPosition()
00091 {
00092 return position_;
00093 }
00094
00095 const IteratorPosition& getPosition() const
00096 {
00097 return position_;
00098 }
00099
00100 bool operator == (const ElementRowIteratorTraits& traits) const
00101 {
00102 return (position_ == traits.position_);
00103 }
00104
00105 bool operator != (const ElementRowIteratorTraits& traits) const
00106 {
00107 return (position_ != traits.position_);
00108 }
00109
00110 bool operator < (const ElementRowIteratorTraits& traits) const
00111 {
00112 return (position_ < traits.position_);
00113 }
00114
00115 Distance getDistance(const ElementRowIteratorTraits& traits) const
00116 {
00117 return (Distance)(position_ - traits.position_);
00118 }
00119
00120 bool isValid() const
00121 {
00122 return ((bound_ != 0) && (position_ >= 0) && (position_ < (int)bound_->data_.size()));
00123 }
00124
00125 void invalidate()
00126 {
00127 bound_ = 0;
00128 position_ = -1;
00129 }
00130
00131 void toBegin()
00132 {
00133 position_ = 0;
00134 }
00135
00136 bool isBegin() const
00137 {
00138 return ( position_ == 0 );
00139 }
00140
00141 void toEnd()
00142 {
00143 position_ = bound_->data_.size();
00144 }
00145
00146 bool isEnd() const
00147 {
00148 return ( position_ == (int)bound_->data_.size());
00149 }
00150
00151 ValueType& getData()
00152 {
00153 return (*bound_)[position_];
00154 }
00155
00156 const ValueType& getData() const
00157 {
00158 return (*bound_)[position_];
00159 }
00160
00161 void forward()
00162 {
00163 if (bound_->row_major_)
00164 {
00165 position_++;
00166 }
00167 else
00168 {
00169 if ((uint)(position_+1) == bound_->data_.size())
00170 {
00171 position_++;
00172 return;
00173 }
00174 position_ += bound_->n_;
00175 if ((uint)position_ >= bound_->data_.size())
00176 position_ = (position_ % bound_->m_) + 1;
00177 }
00178 }
00179
00180 friend std::ostream& operator << (std::ostream& s, const ElementRowIteratorTraits& traits)
00181 {
00182 return (s << traits.position_ << ' ');
00183 }
00184
00185 void dump(std::ostream& s) const
00186 {
00187 s << position_ << std::endl;
00188 }
00189
00190 void toRBegin()
00191 {
00192 position_ = bound_->data_.size() - 1;
00193 }
00194
00195 bool isRBegin() const
00196 {
00197 return (position_ == bound_->data_.size() - 1);
00198 }
00199
00200 void toREnd()
00201 {
00202 position_ = -1;
00203 }
00204
00205 bool isREnd() const
00206 {
00207 return (position_ <= -1);
00208 }
00209
00210 void backward()
00211 {
00212 if (bound_->row_major_)
00213 {
00214 position_--;
00215 }
00216 else
00217 {
00218 if (position_ == 0)
00219 {
00220 position_--;
00221 return;
00222 }
00223 position_ -= bound_->n_;
00224 if (position_ < 0)
00225 position_ = (int)(bound_->data_.size()) - 1 + position_;
00226 }
00227 }
00228
00229 void backward(Distance distance)
00230 {
00231 if (bound_->row_major_)
00232 {
00233 position_ -= distance;
00234 }
00235 else
00236 {
00237 for (int i=0; i<distance; i++)
00238 {
00239 if (position_ == 0)
00240 {
00241 position_--;
00242 return;
00243 }
00244 position_ -= bound_->n_;
00245 if (position_ < 0)
00246 position_ = (int)(bound_->data_.size()) - 1 + position_;
00247 }
00248 }
00249 }
00250
00251 void forward(Distance distance)
00252 {
00253 if (bound_->row_major_)
00254 {
00255 position_ += distance;
00256 }
00257 else
00258 {
00259 for (int i=0; i<distance; i++)
00260 {
00261 if ((uint)(position_+1) == bound_->data_.size())
00262 {
00263 position_++;
00264 return;
00265 }
00266 position_ += bound_->n_;
00267 if ((uint)position_ >= bound_->data_.size())
00268 position_ = (position_ % bound_->m_) + 1;
00269 }
00270 }
00271 }
00272
00273 ValueType& getData(Index index)
00274 {
00275 return (*bound_)[index];
00276 }
00277
00278 const ValueType& getData(Index index) const
00279 {
00280 return (*bound_)[index];
00281 }
00282
00283
00284 protected:
00285
00286 Matrix<valuetype, mtraits>* bound_;
00287 IteratorPosition position_;
00288 };
00289
00290
00291 }
00292
00293 #endif