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() throw() {}
00043
00045 ConstReverseIterator(const ConstReverseIterator& iterator) throw()
00046 : Base(iterator)
00047 {
00048 }
00049
00051 ~ConstReverseIterator() throw() {}
00053
00054
00055
00059
00062 ConstReverseIterator& operator += (Distance distance)
00063 throw(Exception::InvalidIterator);
00064
00067 ConstReverseIterator& operator -= (Distance distance)
00068 throw(Exception::InvalidIterator);
00069
00073 ConstReverseIterator operator + (Distance distance) const
00074 throw(Exception::InvalidIterator);
00075
00080 ConstReverseIterator operator - (Distance distance) const
00081 throw(Exception::InvalidIterator);
00082
00087 Distance operator - (const ConstReverseIterator& iterator) const
00088 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00089
00093 static ConstReverseIterator begin(const Container& container)
00094 throw(Exception::Precondition);
00095
00099 static ConstReverseIterator end(const Container& container)
00100 throw(Exception::Precondition);
00101
00105 static ConstReverseIterator rbegin(const Container& container)
00106 throw(Exception::Precondition);
00107
00111 static ConstReverseIterator rend(const Container& container)
00112 throw(Exception::Precondition);
00113
00115 ConstReverseIterator& operator ++ () throw(Exception::InvalidIterator);
00116
00118 ConstReverseIterator operator ++ (int) throw(Exception::InvalidIterator);
00119
00121 ConstReverseIterator& operator -- () throw(Exception::SingularIterator);
00122
00124 ConstReverseIterator operator -- (int) throw(Exception::SingularIterator);
00125
00126
00128
00132
00134 bool operator + () const throw() { return Base::getTraits().isValid(); }
00135
00137 bool operator - () const throw() { return !Base::getTraits().isValid(); }
00138
00145 bool operator < (const ConstReverseIterator& iterator) const
00146 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00147
00155 bool operator <= (const ConstReverseIterator& iterator) const
00156 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00157
00165 bool operator >= (const ConstReverseIterator& iterator) const
00166 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00167
00174 bool operator > (const ConstReverseIterator& iterator) const
00175 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00176
00178
00179
00180
00186 const DataType& operator [] (Index index) const throw(Exception::InvalidIterator);
00188
00189 protected:
00190
00191 ConstReverseIterator(const Container& container) throw()
00192 : Base(container)
00193 {
00194 }
00195 };
00197
00198 template <typename Container, typename DataType, typename Position, typename Traits>
00199 ConstReverseIterator<Container, DataType, Position, Traits>&
00200 ConstReverseIterator<Container, DataType, Position, Traits>::operator ++ ()
00201 throw(Exception::InvalidIterator)
00202 {
00203 if (!Base::getTraits().isValid())
00204 {
00205 Exception::InvalidIterator e;
00206 throw(e);
00207 }
00208 Base::getTraits().backward();
00209 return *this;
00210 }
00211
00212 template <typename Container, typename DataType, typename Position, typename Traits>
00213 ConstReverseIterator<Container, DataType, Position, Traits>
00214 ConstReverseIterator<Container, DataType, Position, Traits>::operator ++ (int)
00215 throw(Exception::InvalidIterator)
00216 {
00217 if (!Base::getTraits().isValid())
00218 {
00219 Exception::InvalidIterator e;
00220 throw(e);
00221 }
00222 ConstReverseIterator iterator(*this);
00223 ++(*this);
00224 return iterator;
00225 }
00226
00227 template <typename Container, typename DataType, typename Position, typename Traits>
00228 ConstReverseIterator<Container, DataType, Position, Traits>&
00229 ConstReverseIterator<Container, DataType, Position, Traits>::operator -- ()
00230 throw(Exception::SingularIterator)
00231 {
00232 if (Base::getTraits().isSingular())
00233 {
00234 Exception::SingularIterator e;
00235 throw(e);
00236 }
00237 Base::getTraits().forward();
00238 return *this;
00239 }
00240
00241 template <typename Container, typename DataType, typename Position, typename Traits>
00242 ConstReverseIterator<Container, DataType, Position, Traits>
00243 ConstReverseIterator<Container, DataType, Position, Traits>::operator -- (int)
00244 throw(Exception::SingularIterator)
00245 {
00246 if (Base::getTraits().isSingular())
00247 {
00248 Exception::SingularIterator e;
00249 throw(e);
00250 }
00251 ConstReverseIterator iterator(*this);
00252 --(*this);
00253 return iterator;
00254 }
00255
00260 template <typename Container, typename DataType, typename Position, typename Traits>
00261 ConstReverseIterator<Container, DataType, Position, Traits> operator +
00262 (Distance distance, const ConstReverseIterator<Container, DataType, Position, Traits>& iterator)
00263 throw(Exception::InvalidIterator)
00264 {
00265 ConstReverseIterator<Container, DataType, Position, Traits> tmp_iterator(iterator);
00266 return (tmp_iterator += distance);
00267 }
00268
00273 template <typename Container, typename DataType, typename Position, typename Traits>
00274 Distance ConstReverseIterator<Container, DataType, Position, Traits>::operator -
00275 (const ConstReverseIterator<Container, DataType, Position, Traits>& b) const
00276 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00277 {
00278 if (!Base::getTraits().isValid())
00279 {
00280 Exception::InvalidIterator e;
00281 throw e;
00282 }
00283 if (!b.getTraits().isValid())
00284 {
00285 Exception::InvalidIterator e;
00286 throw e;
00287 }
00288 if (Base::getTraits().getContainer() != b.getTraits().getContainer())
00289 {
00290 Exception::IncompatibleIterators e;
00291 throw e;
00292 }
00293 return Base::getTraits().getDistance(b.getTraits());
00294 }
00295
00296 template <typename Container, typename DataType, typename Position, typename Traits>
00297 ConstReverseIterator<Container, DataType, Position, Traits>&
00298 ConstReverseIterator<Container, DataType, Position, Traits>::operator += (Distance distance)
00299 throw(Exception::InvalidIterator)
00300 {
00301 if (!Base::getTraits().isValid())
00302 {
00303 Exception::InvalidIterator e;
00304 throw e;
00305 }
00306 if (distance < (Distance)0)
00307 {
00308 return (*this -= -distance);
00309 }
00310 Base::getTraits().backward(distance);
00311 return *this;
00312 }
00313
00314 template <typename Container, typename DataType, typename Position, typename Traits>
00315 ConstReverseIterator<Container, DataType, Position, Traits>&
00316 ConstReverseIterator<Container, DataType, Position, Traits>::operator -= (Distance distance)
00317 throw(Exception::InvalidIterator)
00318 {
00319 if (Base::getTraits().isSingular())
00320 {
00321 Exception::InvalidIterator e;
00322 throw e;
00323 }
00324 if (distance < (Distance)0)
00325 {
00326 return (*this += -distance);
00327 }
00328 if (Base::getTraits().isREnd() == true)
00329 {
00330 Base::getTraits().toBegin();
00331 Base::getTraits().forward(distance - 1);
00332 }
00333 else
00334 {
00335 Base::getTraits().forward(distance);
00336 }
00337 return *this;
00338 }
00339
00340 template <typename Container, typename DataType, typename Position, typename Traits>
00341 ConstReverseIterator<Container, DataType, Position, Traits>
00342 ConstReverseIterator<Container, DataType, Position, Traits>::operator + (Distance distance) const
00343 throw(Exception::InvalidIterator)
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 throw(Exception::InvalidIterator)
00353 {
00354 ConstReverseIterator iterator(*this);
00355 return (iterator -= distance);
00356 }
00357
00358 template <typename Container, typename DataType, typename Position, typename Traits>
00359 bool ConstReverseIterator<Container, DataType, Position, Traits>::operator <
00360 (const ConstReverseIterator& iterator) const
00361 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00362 {
00363 if (!Base::getTraits().isValid())
00364 {
00365 Exception::InvalidIterator e;
00366 throw e;
00367 }
00368 if (!iterator.isValid())
00369 {
00370 Exception::InvalidIterator e;
00371 throw e;
00372 }
00373 if (Base::getTraits().getContainer() != iterator.getContainer())
00374 {
00375 Exception::IncompatibleIterators e;
00376 throw e;
00377 }
00378
00379 return !(Base::getTraits().operator < (iterator.getTraits()));
00380 }
00381
00382 template <typename Container, typename DataType, typename Position, typename Traits>
00383 bool ConstReverseIterator<Container, DataType, Position, Traits>::operator <=
00384 (const ConstReverseIterator& iterator) const
00385 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00386 {
00387 if (!Base::getTraits().isValid())
00388 {
00389 Exception::InvalidIterator e;
00390 throw e;
00391 }
00392 if (!iterator.isValid())
00393 {
00394 Exception::InvalidIterator e;
00395 throw e;
00396 }
00397 if (Base::getTraits().getContainer() != iterator.getContainer())
00398 {
00399 Exception::IncompatibleIterators e;
00400 throw e;
00401 }
00402 return (Base::getTraits().operator > (iterator.getTraits()));
00403 }
00404
00405 template <typename Container, typename DataType, typename Position, typename Traits>
00406 bool ConstReverseIterator<Container, DataType, Position, Traits>::operator >=
00407 (const ConstReverseIterator& iterator) const
00408 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00409 {
00410 if (!Base::getTraits().isValid())
00411 {
00412 Exception::InvalidIterator e;
00413 throw e;
00414 }
00415 if (!iterator.isValid())
00416 {
00417 Exception::InvalidIterator e;
00418 throw e;
00419 }
00420 if (Base::getTraits().getContainer() != iterator.getContainer())
00421 {
00422 Exception::IncompatibleIterators e;
00423 throw e;
00424 }
00425
00426 return (Base::getTraits().operator < (iterator.getTraits()));
00427 }
00428
00429 template <typename Container, typename DataType, typename Position, typename Traits>
00430 bool ConstReverseIterator<Container, DataType, Position, Traits>::operator >
00431 (const ConstReverseIterator& iterator) const
00432 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00433 {
00434 if (!Base::getTraits().isValid())
00435 {
00436 Exception::InvalidIterator e;
00437 throw e;
00438 }
00439 if (!iterator.isValid())
00440 {
00441 Exception::InvalidIterator e;
00442 throw e;
00443 }
00444 if (Base::getTraits().getContainer() != iterator.getContainer())
00445 {
00446 Exception::IncompatibleIterators e;
00447 throw e;
00448 }
00449
00450 return !(Base::getTraits().operator > (iterator.getTraits()));
00451 }
00452
00453
00454 template <typename Container, typename DataType, typename Position, typename Traits>
00455 const DataType& ConstReverseIterator<Container, DataType, Position, Traits>::operator [] (Index index) const
00456 throw(Exception::InvalidIterator)
00457 {
00458 if (!Base::getTraits().isValid())
00459 {
00460 Exception::InvalidIterator e;
00461 throw e;
00462 }
00463
00464 return Base::getTraits().getData(index);
00465 }
00466
00467 template <typename Container, typename DataType, typename Position, typename Traits>
00468 ConstReverseIterator<Container, DataType, Position, Traits>
00469 ConstReverseIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00470 throw(Exception::Precondition)
00471 {
00472 ConstReverseIterator iterator(container);
00473 iterator.toRBegin();
00474 return iterator;
00475 }
00476
00477 template <typename Container, typename DataType, typename Position, typename Traits>
00478 ConstReverseIterator<Container, DataType, Position, Traits>
00479 ConstReverseIterator<Container, DataType, Position, Traits>::end(const Container& container)
00480 throw(Exception::Precondition)
00481 {
00482 ConstReverseIterator iterator(container);
00483 iterator.toREnd();
00484 return iterator;
00485 }
00486
00487 template <typename Container, typename DataType, typename Position, typename Traits>
00488 ConstReverseIterator<Container, DataType, Position, Traits>
00489 ConstReverseIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00490 throw(Exception::Precondition)
00491 {
00492 ConstReverseIterator iterator(container);
00493 iterator.toBegin();
00494 return iterator;
00495 }
00496
00497 template <typename Container, typename DataType, typename Position, typename Traits>
00498 ConstReverseIterator<Container, DataType, Position, Traits>
00499 ConstReverseIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00500 throw(Exception::Precondition)
00501 {
00502 ConstReverseIterator iterator(container);
00503 iterator.toEnd();
00504 return iterator;
00505 }
00506
00511
00514 template <typename Container, typename DataType, typename Position, typename Traits>
00515 class ReverseIterator
00516 : public ConstReverseIterator<Container, DataType, Position, Traits>
00517 {
00518 public:
00519
00523
00524 typedef DataType& reference;
00526 typedef DataType* pointer;
00528 typedef ConstReverseIterator<Container, DataType, Position, Traits> Base;
00530
00534
00536 ReverseIterator() throw() {}
00537
00539 ReverseIterator(const ReverseIterator& iterator) throw()
00540 : Base(iterator)
00541 {
00542 }
00543
00545 ~ReverseIterator() throw() {}
00547
00551
00552 reference operator [] (Index index) const throw(Exception::InvalidIterator) { return const_cast<reference>(Base::getTraits().getData(index)); }
00554 reference operator * () const throw() { return const_cast<reference>(Base::getTraits().getData()); }
00556 pointer operator -> () const throw() { return const_cast<pointer>(&Base::getTraits().getData()); }
00558
00565 static ReverseIterator begin(const Container& container)
00566 throw(Exception::InvalidIterator);
00567
00571 static ReverseIterator end(const Container& container)
00572 throw(Exception::InvalidIterator);
00573
00577 static ReverseIterator rbegin(const Container& container)
00578 throw(Exception::InvalidIterator);
00579
00583 static ReverseIterator rend(const Container& container)
00584 throw(Exception::InvalidIterator);
00586
00587 protected:
00588
00589 ReverseIterator(const Container& container) throw()
00590 : Base(container)
00591 {
00592 }
00593
00594 };
00596
00597 template <typename Container, typename DataType, typename Position, typename Traits>
00598 ReverseIterator<Container, DataType, Position, Traits>
00599 ReverseIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00600 throw(Exception::InvalidIterator)
00601 {
00602 ReverseIterator iterator(container);
00603 iterator.toRBegin();
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>::end(const Container& container)
00610 throw(Exception::InvalidIterator)
00611 {
00612 ReverseIterator iterator(container);
00613 iterator.toREnd();
00614 return iterator;
00615 }
00616
00617 template <typename Container, typename DataType, typename Position, typename Traits>
00618 ReverseIterator<Container, DataType, Position, Traits>
00619 ReverseIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00620 throw(Exception::InvalidIterator)
00621 {
00622 ReverseIterator iterator(container);
00623 iterator.toBegin();
00624 return iterator;
00625 }
00626
00627 template <typename Container, typename DataType, typename Position, typename Traits>
00628 ReverseIterator<Container, DataType, Position, Traits>
00629 ReverseIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00630 throw(Exception::InvalidIterator)
00631 {
00632 ReverseIterator iterator(container);
00633 iterator.toEnd();
00634 return iterator;
00635 }
00636
00637 }
00638
00639 #endif // BALL_KERNEL_REVERSEITERATOR_H