00001 #ifndef BALL_LINALG_REVERSEITERATOR_H
00002 #define BALL_LINALG_REVERSEITERATOR_H
00003
00004 #ifndef BALL_CONCEPT_RANDOMACCESSITERATOR_H
00005 #include <BALL/CONCEPT/randomAccessIterator.h>
00006 #endif
00007
00008 #include <BALL/MATHS/LINALG/linalgException.h>
00009
00010 namespace BALL
00011 {
00013 typedef int Distance;
00015 typedef int Index;
00016
00021 template <typename Container, typename DataType, typename Position, typename Traits>
00022 class ConstReverseIterator
00023 : public ConstRandomAccessIterator<Container, DataType, Position, Traits>
00024 {
00025 public:
00026
00030
00032 typedef std::random_access_iterator_tag iterator_category;
00033
00034 typedef ConstRandomAccessIterator<Container, DataType, Position, Traits> Base;
00036
00040
00042 ConstReverseIterator() {}
00043
00045 ConstReverseIterator(const ConstReverseIterator& iterator)
00046 : Base(iterator)
00047 {
00048 }
00049
00051 ~ConstReverseIterator() {}
00053
00054
00055
00059
00063 ConstReverseIterator& operator += (Distance distance);
00064
00068 ConstReverseIterator& operator -= (Distance distance);
00069
00074 ConstReverseIterator operator + (Distance distance) const;
00075
00081 ConstReverseIterator operator - (Distance distance) const;
00082
00089 Distance operator - (const ConstReverseIterator& iterator) const;
00090
00095 static ConstReverseIterator begin(const Container& container);
00096
00101 static ConstReverseIterator end(const Container& container);
00102
00107 static ConstReverseIterator rbegin(const Container& container);
00108
00113 static ConstReverseIterator rend(const Container& container);
00114
00118 ConstReverseIterator& operator ++ ();
00119
00123 ConstReverseIterator operator ++ (int);
00124
00128 ConstReverseIterator& operator -- ();
00129
00133 ConstReverseIterator operator -- (int);
00134
00135
00137
00141
00143 bool operator + () const { return Base::getTraits().isValid(); }
00144
00146 bool operator - () const { return !Base::getTraits().isValid(); }
00147
00154 bool operator < (const ConstReverseIterator& iterator) const;
00155
00163 bool operator <= (const ConstReverseIterator& iterator) const;
00164
00172 bool operator >= (const ConstReverseIterator& iterator) const;
00173
00180 bool operator > (const ConstReverseIterator& iterator) const;
00181
00183
00184
00185
00192 const DataType& operator [] (Index index) const;
00194
00195 protected:
00196
00197 ConstReverseIterator(const Container& container)
00198 : Base(container)
00199 {
00200 }
00201 };
00203
00204 template <typename Container, typename DataType, typename Position, typename Traits>
00205 ConstReverseIterator<Container, DataType, Position, Traits>&
00206 ConstReverseIterator<Container, DataType, Position, Traits>::operator ++ ()
00207 {
00208 if (!Base::getTraits().isValid())
00209 {
00210 Exception::InvalidIterator e;
00211 throw(e);
00212 }
00213 Base::getTraits().backward();
00214 return *this;
00215 }
00216
00217 template <typename Container, typename DataType, typename Position, typename Traits>
00218 ConstReverseIterator<Container, DataType, Position, Traits>
00219 ConstReverseIterator<Container, DataType, Position, Traits>::operator ++ (int)
00220 {
00221 if (!Base::getTraits().isValid())
00222 {
00223 Exception::InvalidIterator e;
00224 throw(e);
00225 }
00226 ConstReverseIterator iterator(*this);
00227 ++(*this);
00228 return iterator;
00229 }
00230
00231 template <typename Container, typename DataType, typename Position, typename Traits>
00232 ConstReverseIterator<Container, DataType, Position, Traits>&
00233 ConstReverseIterator<Container, DataType, Position, Traits>::operator -- ()
00234 {
00235 if (Base::getTraits().isSingular())
00236 {
00237 Exception::SingularIterator e;
00238 throw(e);
00239 }
00240 Base::getTraits().forward();
00241 return *this;
00242 }
00243
00244 template <typename Container, typename DataType, typename Position, typename Traits>
00245 ConstReverseIterator<Container, DataType, Position, Traits>
00246 ConstReverseIterator<Container, DataType, Position, Traits>::operator -- (int)
00247 {
00248 if (Base::getTraits().isSingular())
00249 {
00250 Exception::SingularIterator e;
00251 throw(e);
00252 }
00253 ConstReverseIterator iterator(*this);
00254 --(*this);
00255 return iterator;
00256 }
00257
00263 template <typename Container, typename DataType, typename Position, typename Traits>
00264 ConstReverseIterator<Container, DataType, Position, Traits> operator +
00265 (Distance distance, const ConstReverseIterator<Container, DataType, Position, Traits>& iterator)
00266 {
00267 ConstReverseIterator<Container, DataType, Position, Traits> tmp_iterator(iterator);
00268 return (tmp_iterator += distance);
00269 }
00270
00277 template <typename Container, typename DataType, typename Position, typename Traits>
00278 Distance ConstReverseIterator<Container, DataType, Position, Traits>::operator -
00279 (const ConstReverseIterator<Container, DataType, Position, Traits>& b) const
00280 {
00281 if (!Base::getTraits().isValid())
00282 {
00283 Exception::InvalidIterator e;
00284 throw e;
00285 }
00286 if (!b.getTraits().isValid())
00287 {
00288 Exception::InvalidIterator e;
00289 throw e;
00290 }
00291 if (Base::getTraits().getContainer() != b.getTraits().getContainer())
00292 {
00293 Exception::IncompatibleIterators e;
00294 throw e;
00295 }
00296 return Base::getTraits().getDistance(b.getTraits());
00297 }
00298
00299 template <typename Container, typename DataType, typename Position, typename Traits>
00300 ConstReverseIterator<Container, DataType, Position, Traits>&
00301 ConstReverseIterator<Container, DataType, Position, Traits>::operator += (Distance distance)
00302 {
00303 if (!Base::getTraits().isValid())
00304 {
00305 Exception::InvalidIterator e;
00306 throw e;
00307 }
00308 if (distance < (Distance)0)
00309 {
00310 return (*this -= -distance);
00311 }
00312 Base::getTraits().backward(distance);
00313 return *this;
00314 }
00315
00316 template <typename Container, typename DataType, typename Position, typename Traits>
00317 ConstReverseIterator<Container, DataType, Position, Traits>&
00318 ConstReverseIterator<Container, DataType, Position, Traits>::operator -= (Distance distance)
00319 {
00320 if (Base::getTraits().isSingular())
00321 {
00322 Exception::InvalidIterator e;
00323 throw e;
00324 }
00325 if (distance < (Distance)0)
00326 {
00327 return (*this += -distance);
00328 }
00329 if (Base::getTraits().isREnd() == true)
00330 {
00331 Base::getTraits().toBegin();
00332 Base::getTraits().forward(distance - 1);
00333 }
00334 else
00335 {
00336 Base::getTraits().forward(distance);
00337 }
00338 return *this;
00339 }
00340
00341 template <typename Container, typename DataType, typename Position, typename Traits>
00342 ConstReverseIterator<Container, DataType, Position, Traits>
00343 ConstReverseIterator<Container, DataType, Position, Traits>::operator + (Distance distance) const
00344 {
00345 ConstReverseIterator iterator(*this);
00346 return (iterator += distance);
00347 }
00348
00349 template <typename Container, typename DataType, typename Position, typename Traits>
00350 ConstReverseIterator<Container, DataType, Position, Traits>
00351 ConstReverseIterator<Container, DataType, Position, Traits>::operator - (Distance distance) const
00352 {
00353 ConstReverseIterator iterator(*this);
00354 return (iterator -= distance);
00355 }
00356
00357 template <typename Container, typename DataType, typename Position, typename Traits>
00358 bool ConstReverseIterator<Container, DataType, Position, Traits>::operator <
00359 (const ConstReverseIterator& iterator) const
00360 {
00361 if (!Base::getTraits().isValid())
00362 {
00363 Exception::InvalidIterator e;
00364 throw e;
00365 }
00366 if (!iterator.isValid())
00367 {
00368 Exception::InvalidIterator e;
00369 throw e;
00370 }
00371 if (Base::getTraits().getContainer() != iterator.getContainer())
00372 {
00373 Exception::IncompatibleIterators e;
00374 throw e;
00375 }
00376
00377 return !(Base::getTraits().operator < (iterator.getTraits()));
00378 }
00379
00380 template <typename Container, typename DataType, typename Position, typename Traits>
00381 bool ConstReverseIterator<Container, DataType, Position, Traits>::operator <=
00382 (const ConstReverseIterator& iterator) const
00383 {
00384 if (!Base::getTraits().isValid())
00385 {
00386 Exception::InvalidIterator e;
00387 throw e;
00388 }
00389 if (!iterator.isValid())
00390 {
00391 Exception::InvalidIterator e;
00392 throw e;
00393 }
00394 if (Base::getTraits().getContainer() != iterator.getContainer())
00395 {
00396 Exception::IncompatibleIterators e;
00397 throw e;
00398 }
00399 return (Base::getTraits().operator > (iterator.getTraits()));
00400 }
00401
00402 template <typename Container, typename DataType, typename Position, typename Traits>
00403 bool ConstReverseIterator<Container, DataType, Position, Traits>::operator >=
00404 (const ConstReverseIterator& iterator) const
00405 {
00406 if (!Base::getTraits().isValid())
00407 {
00408 Exception::InvalidIterator e;
00409 throw e;
00410 }
00411 if (!iterator.isValid())
00412 {
00413 Exception::InvalidIterator e;
00414 throw e;
00415 }
00416 if (Base::getTraits().getContainer() != iterator.getContainer())
00417 {
00418 Exception::IncompatibleIterators e;
00419 throw e;
00420 }
00421
00422 return (Base::getTraits().operator < (iterator.getTraits()));
00423 }
00424
00425 template <typename Container, typename DataType, typename Position, typename Traits>
00426 bool ConstReverseIterator<Container, DataType, Position, Traits>::operator >
00427 (const ConstReverseIterator& iterator) const
00428 {
00429 if (!Base::getTraits().isValid())
00430 {
00431 Exception::InvalidIterator e;
00432 throw e;
00433 }
00434 if (!iterator.isValid())
00435 {
00436 Exception::InvalidIterator e;
00437 throw e;
00438 }
00439 if (Base::getTraits().getContainer() != iterator.getContainer())
00440 {
00441 Exception::IncompatibleIterators e;
00442 throw e;
00443 }
00444
00445 return !(Base::getTraits().operator > (iterator.getTraits()));
00446 }
00447
00448
00449 template <typename Container, typename DataType, typename Position, typename Traits>
00450 const DataType& ConstReverseIterator<Container, DataType, Position, Traits>::operator [] (Index index) const
00451 {
00452 if (!Base::getTraits().isValid())
00453 {
00454 Exception::InvalidIterator e;
00455 throw e;
00456 }
00457
00458 return Base::getTraits().getData(index);
00459 }
00460
00461 template <typename Container, typename DataType, typename Position, typename Traits>
00462 ConstReverseIterator<Container, DataType, Position, Traits>
00463 ConstReverseIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00464 {
00465 ConstReverseIterator iterator(container);
00466 iterator.toRBegin();
00467 return iterator;
00468 }
00469
00470 template <typename Container, typename DataType, typename Position, typename Traits>
00471 ConstReverseIterator<Container, DataType, Position, Traits>
00472 ConstReverseIterator<Container, DataType, Position, Traits>::end(const Container& container)
00473 {
00474 ConstReverseIterator iterator(container);
00475 iterator.toREnd();
00476 return iterator;
00477 }
00478
00479 template <typename Container, typename DataType, typename Position, typename Traits>
00480 ConstReverseIterator<Container, DataType, Position, Traits>
00481 ConstReverseIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00482 {
00483 ConstReverseIterator iterator(container);
00484 iterator.toBegin();
00485 return iterator;
00486 }
00487
00488 template <typename Container, typename DataType, typename Position, typename Traits>
00489 ConstReverseIterator<Container, DataType, Position, Traits>
00490 ConstReverseIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00491 {
00492 ConstReverseIterator iterator(container);
00493 iterator.toEnd();
00494 return iterator;
00495 }
00496
00501
00504 template <typename Container, typename DataType, typename Position, typename Traits>
00505 class ReverseIterator
00506 : public ConstReverseIterator<Container, DataType, Position, Traits>
00507 {
00508 public:
00509
00513
00514 typedef DataType& reference;
00516 typedef DataType* pointer;
00518 typedef ConstReverseIterator<Container, DataType, Position, Traits> Base;
00520
00524
00526 ReverseIterator() {}
00527
00529 ReverseIterator(const ReverseIterator& iterator)
00530 : Base(iterator)
00531 {
00532 }
00533
00535 ~ReverseIterator() {}
00537
00544 reference operator [] (Index index) const { return const_cast<reference>(Base::getTraits().getData(index)); }
00546 reference operator * () const { return const_cast<reference>(Base::getTraits().getData()); }
00548 pointer operator -> () const { return const_cast<pointer>(&Base::getTraits().getData()); }
00550
00558 static ReverseIterator begin(const Container& container);
00559
00564 static ReverseIterator end(const Container& container);
00565
00570 static ReverseIterator rbegin(const Container& container);
00571
00576 static ReverseIterator rend(const Container& container);
00578
00579 protected:
00580
00581 ReverseIterator(const Container& container)
00582 : Base(container)
00583 {
00584 }
00585
00586 };
00588
00589 template <typename Container, typename DataType, typename Position, typename Traits>
00590 ReverseIterator<Container, DataType, Position, Traits>
00591 ReverseIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00592 {
00593 ReverseIterator iterator(container);
00594 iterator.toRBegin();
00595 return iterator;
00596 }
00597
00598 template <typename Container, typename DataType, typename Position, typename Traits>
00599 ReverseIterator<Container, DataType, Position, Traits>
00600 ReverseIterator<Container, DataType, Position, Traits>::end(const Container& container)
00601 {
00602 ReverseIterator iterator(container);
00603 iterator.toREnd();
00604 return iterator;
00605 }
00606
00607 template <typename Container, typename DataType, typename Position, typename Traits>
00608 ReverseIterator<Container, DataType, Position, Traits>
00609 ReverseIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00610 {
00611 ReverseIterator iterator(container);
00612 iterator.toBegin();
00613 return iterator;
00614 }
00615
00616 template <typename Container, typename DataType, typename Position, typename Traits>
00617 ReverseIterator<Container, DataType, Position, Traits>
00618 ReverseIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00619 {
00620 ReverseIterator iterator(container);
00621 iterator.toEnd();
00622 return iterator;
00623 }
00624
00625 }
00626
00627 #endif // BALL_KERNEL_REVERSEITERATOR_H