00001 #ifndef BALL_LINALG_BIDIRECTIONALITERATOR_H
00002 #define BALL_LINALG_BIDIRECTIONALITERATOR_H
00003
00004 #ifndef BALL_LINALG_FORWARDITERATOR_H
00005 # include <BALL/MATHS/LINALG/forwardIterator.h>
00006 #endif
00007
00008 namespace BALL
00009 {
00010
00015
00018 template <typename Container, typename DataType, typename Position, typename Traits>
00019 class ConstBidirectionalIterator
00020 : public ConstForwardIterator<Container, DataType, Position, Traits>
00021 {
00022 public:
00023
00027
00029 typedef std::bidirectional_iterator_tag iterator_category;
00030
00031 typedef ConstForwardIterator<Container, DataType, Position, Traits> Base;
00033
00037
00039 ConstBidirectionalIterator() {}
00040
00042 ConstBidirectionalIterator(const ConstBidirectionalIterator& iterator)
00043 : Base(iterator)
00044 {
00045 }
00046
00048 ~ConstBidirectionalIterator() {}
00050
00054
00058 void toBegin();
00059
00061 bool isBegin() const { return Base::getTraits().isBegin(); }
00062
00066 void toEnd();
00067
00069 bool isEnd() const { return Base::getTraits().isEnd(); }
00070
00074 void toRBegin();
00075
00077 bool isRBegin() const { return Base::getTraits().isRBegin(); }
00078
00082 void toREnd();
00083
00085 bool isREnd() const { return Base::getTraits().isREnd(); }
00086
00090 ConstBidirectionalIterator& operator ++ ();
00091
00095 ConstBidirectionalIterator operator ++ (int);
00096
00100 ConstBidirectionalIterator& operator -- ();
00101
00105 ConstBidirectionalIterator operator -- (int);
00106
00110 static ConstBidirectionalIterator begin(const Container& container);
00111
00115 static ConstBidirectionalIterator end(const Container& container);
00116
00120 static ConstBidirectionalIterator rbegin(const Container& container);
00121
00125 static ConstBidirectionalIterator rend(const Container& container);
00127
00128 protected:
00129
00131 ConstBidirectionalIterator(const Container& container)
00132 : Base(container)
00133 {
00134 }
00135 };
00137
00138 template <typename Container, typename DataType, typename Position, typename Traits>
00139 void ConstBidirectionalIterator<Container, DataType, Position, Traits>::toBegin()
00140 {
00141 if (Base::getTraits().isSingular())
00142 {
00143 Exception::SingularIterator e;
00144 throw(e);
00145 }
00146 Base::getTraits().toBegin();
00147 }
00148
00149 template <typename Container, typename DataType, typename Position, typename Traits>
00150 void ConstBidirectionalIterator<Container, DataType, Position, Traits>::toEnd()
00151 {
00152 if (Base::getTraits().isSingular())
00153 {
00154 Exception::SingularIterator e;
00155 throw(e);
00156 }
00157 Base::getTraits().toEnd();
00158 }
00159
00160 template <typename Container, typename DataType, typename Position, typename Traits>
00161 void ConstBidirectionalIterator<Container, DataType, Position, Traits>::toRBegin()
00162 {
00163 if (Base::getTraits().isSingular())
00164 {
00165 Exception::SingularIterator e;
00166 throw(e);
00167 }
00168 Base::getTraits().toRBegin();
00169 }
00170
00171 template <typename Container, typename DataType, typename Position, typename Traits>
00172 void ConstBidirectionalIterator<Container, DataType, Position, Traits>::toREnd()
00173 {
00174 if (Base::getTraits().isSingular())
00175 {
00176 Exception::SingularIterator e;
00177 throw(e);
00178 }
00179 Base::getTraits().toREnd();
00180 }
00181
00182 template <typename Container, typename DataType, typename Position, typename Traits>
00183 ConstBidirectionalIterator<Container, DataType, Position, Traits>&
00184 ConstBidirectionalIterator<Container, DataType, Position, Traits>::operator ++ ()
00185 {
00186 if (!Base::getTraits().isValid())
00187 {
00188 Exception::InvalidIterator e;
00189 throw(e);
00190 }
00191 Base::getTraits().forward();
00192 return *this;
00193 }
00194
00195 template <typename Container, typename DataType, typename Position, typename Traits>
00196 ConstBidirectionalIterator<Container, DataType, Position, Traits>
00197 ConstBidirectionalIterator<Container, DataType, Position, Traits>::operator ++ (int)
00198 {
00199 if (!Base::getTraits().isValid())
00200 {
00201 Exception::InvalidIterator e;
00202 throw(e);
00203 }
00204 ConstBidirectionalIterator iterator(*this);
00205 ++(*this);
00206 return iterator;
00207 }
00208
00209 template <typename Container, typename DataType, typename Position, typename Traits>
00210 ConstBidirectionalIterator<Container, DataType, Position, Traits>&
00211 ConstBidirectionalIterator<Container, DataType, Position, Traits>::operator -- ()
00212 {
00213 if (Base::getTraits().isSingular())
00214 {
00215 Exception::SingularIterator e;
00216 throw(e);
00217 }
00218 Base::getTraits().backward();
00219 return *this;
00220 }
00221
00222 template <typename Container, typename DataType, typename Position, typename Traits>
00223 ConstBidirectionalIterator<Container, DataType, Position, Traits>
00224 ConstBidirectionalIterator<Container, DataType, Position, Traits>::operator -- (int)
00225 {
00226 if (Base::getTraits().isSingular())
00227 {
00228 Exception::SingularIterator e;
00229 throw(e);
00230 }
00231 ConstBidirectionalIterator iterator(*this);
00232 --(*this);
00233 return iterator;
00234 }
00235
00236 template <typename Container, typename DataType, typename Position, typename Traits>
00237 ConstBidirectionalIterator<Container, DataType, Position, Traits>
00238 ConstBidirectionalIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00239 {
00240 ConstBidirectionalIterator iterator(container);
00241 iterator.toBegin();
00242 return iterator;
00243 }
00244
00245 template <typename Container, typename DataType, typename Position, typename Traits>
00246 ConstBidirectionalIterator<Container, DataType, Position, Traits>
00247 ConstBidirectionalIterator<Container, DataType, Position, Traits>::end(const Container& container)
00248 {
00249 ConstBidirectionalIterator iterator(container);
00250 iterator.toEnd();
00251 return iterator;
00252 }
00253
00254 template <typename Container, typename DataType, typename Position, typename Traits>
00255 ConstBidirectionalIterator<Container, DataType, Position, Traits>
00256 ConstBidirectionalIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00257 {
00258 ConstBidirectionalIterator iterator(container);
00259 iterator.toRBegin();
00260 return iterator;
00261 }
00262
00263 template <typename Container, typename DataType, typename Position, typename Traits>
00264 ConstBidirectionalIterator<Container, DataType, Position, Traits>
00265 ConstBidirectionalIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00266 {
00267 ConstBidirectionalIterator iterator(container);
00268 iterator.toREnd();
00269 return iterator;
00270 }
00271
00273 template <typename Container, typename DataType, typename Position, typename Traits>
00274 class BidirectionalIterator
00275 : public ConstBidirectionalIterator<Container, DataType, Position, Traits>
00276 {
00277 public:
00278
00282
00284 typedef DataType& reference;
00286 typedef DataType* pointer;
00287
00288 typedef ConstBidirectionalIterator<Container, DataType, Position, Traits> Base;
00290
00294
00296 BidirectionalIterator() {}
00297
00299 BidirectionalIterator(const BidirectionalIterator& iterator)
00300 : ConstBidirectionalIterator<Container, DataType, Position, Traits>(iterator)
00301 {
00302 }
00303
00305 ~BidirectionalIterator() {}
00306
00308
00312
00314 reference operator * () const { return (reference)Base::getTraits().getData(); }
00315
00317 pointer operator -> () const { return (pointer)&Base::getTraits().getData(); }
00318
00322 BidirectionalIterator& operator ++ ();
00323
00327 BidirectionalIterator operator ++ (int);
00328
00332 BidirectionalIterator& operator -- ();
00333
00337 BidirectionalIterator operator -- (int);
00338
00342 static BidirectionalIterator begin(const Container& container);
00343
00347 static BidirectionalIterator end(const Container& container);
00348
00352 static BidirectionalIterator rbegin(const Container& container);
00353
00357 static BidirectionalIterator rend(const Container& container);
00359
00360 protected:
00361
00363 BidirectionalIterator(const Container& container);
00364 };
00365
00366
00367 template <typename Container, typename DataType, typename Position, typename Traits>
00368 BidirectionalIterator<Container, DataType, Position, Traits>&
00369 BidirectionalIterator<Container, DataType, Position, Traits>::operator ++ ()
00370 {
00371 Base::operator ++ ();
00372 return *this;
00373 }
00374
00375 template <typename Container, typename DataType, typename Position, typename Traits>
00376 BidirectionalIterator<Container, DataType, Position, Traits>
00377 BidirectionalIterator<Container, DataType, Position, Traits>::operator ++ (int)
00378 {
00379 BidirectionalIterator iterator(*this);
00380 this->operator ++ ();
00381 return iterator;
00382 }
00383
00384 template <typename Container, typename DataType, typename Position, typename Traits>
00385 BidirectionalIterator<Container, DataType, Position, Traits>&
00386 BidirectionalIterator<Container, DataType, Position, Traits>::operator -- ()
00387 {
00388 Base::operator -- ();
00389 return *this;
00390 }
00391
00392 template <typename Container, typename DataType, typename Position, typename Traits>
00393 BidirectionalIterator<Container, DataType, Position, Traits>
00394 BidirectionalIterator<Container, DataType, Position, Traits>::operator -- (int)
00395 {
00396 BidirectionalIterator iterator(*this);
00397 this->operator -- ();
00398 return iterator;
00399 }
00400
00401 template <typename Container, typename DataType, typename Position, typename Traits>
00402 BidirectionalIterator<Container, DataType, Position, Traits>
00403 BidirectionalIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00404 {
00405 BidirectionalIterator iterator(container);
00406 iterator.toBegin();
00407 return iterator;
00408 }
00409
00410 template <typename Container, typename DataType, typename Position, typename Traits>
00411 BidirectionalIterator<Container, DataType, Position, Traits>
00412 BidirectionalIterator<Container, DataType, Position, Traits>::end(const Container& container)
00413 {
00414 BidirectionalIterator iterator(container);
00415 iterator.toEnd();
00416 return iterator;
00417 }
00418
00419 template <typename Container, typename DataType, typename Position, typename Traits>
00420 BidirectionalIterator<Container, DataType, Position, Traits>
00421 BidirectionalIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00422 {
00423 BidirectionalIterator iterator(container);
00424 iterator.toRBegin();
00425 return iterator;
00426 }
00427
00428 template <typename Container, typename DataType, typename Position, typename Traits>
00429 BidirectionalIterator<Container, DataType, Position, Traits>
00430 BidirectionalIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00431 {
00432 BidirectionalIterator iterator(container);
00433 iterator.toREnd();
00434 return iterator;
00435 }
00436
00437 template <typename Container, typename DataType, typename Position, typename Traits>
00438 BidirectionalIterator<Container, DataType, Position, Traits>::BidirectionalIterator(const Container& container)
00439 : ConstBidirectionalIterator<Container, DataType, Position, Traits>(container)
00440 {
00441 }
00442
00443
00444 }
00445
00446 #endif // BALL_KERNEL_BIDIRECTIONALITERATOR_H