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