00001 #ifndef BALL_LINALG_RANDOMACCESSFILTERITERATOR_H
00002 #define BALL_LINALG_RANDOMACCESSFILTERITERATOR_H
00003
00004 #ifndef BALL_LINALG_BIDIRECTIONALFILTERITERATOR_H
00005 # include <BALL/MATHS/LINALG/bidirectionalFilterIterator.h>
00006 #endif
00007
00008 namespace BALL
00009 {
00011 typedef int Distance;
00013 typedef int Index;
00014
00019 template <class Predicate, class IteratorRandomAccess>
00020 class ConstRandomAccessFilterIterator
00021 : public ConstBidirectionalFilterIterator<Predicate, IteratorRandomAccess>
00022 {
00023 public:
00024
00028
00029
00031 typedef typename IteratorRandomAccess::difference_type difference_type;
00033 typedef typename IteratorRandomAccess::value_type value_type;
00035 typedef typename IteratorRandomAccess::container_type Container;
00037 typedef typename IteratorRandomAccess::value_type DataType;
00039 typedef typename IteratorRandomAccess::difference_type Position;
00041 typedef typename IteratorRandomAccess::traits_type Traits;
00043 typedef typename IteratorRandomAccess::pointer pointer;
00045 typedef typename IteratorRandomAccess::reference reference;
00047 typedef std::random_access_iterator_tag iterator_category;
00048
00049 typedef ConstBidirectionalFilterIterator<Predicate, IteratorRandomAccess> Base;
00051
00055
00057 ConstRandomAccessFilterIterator() throw() {}
00058
00060 ConstRandomAccessFilterIterator(Predicate p, IteratorRandomAccess it) throw()
00061 : ConstBidirectionalFilterIterator<Predicate, IteratorRandomAccess>(p,it)
00062 {
00063 }
00064
00066 ConstRandomAccessFilterIterator(const ConstRandomAccessFilterIterator& iterator) throw()
00067 : Base(iterator)
00068 {
00069 }
00070
00072 ~ConstRandomAccessFilterIterator() throw() {}
00074
00075
00076
00080
00083 ConstRandomAccessFilterIterator& operator += (Distance distance)
00084 throw(Exception::InvalidIterator);
00085
00088 ConstRandomAccessFilterIterator& operator -= (Distance distance)
00089 throw(Exception::InvalidIterator);
00090
00094 ConstRandomAccessFilterIterator operator + (Distance distance) const
00095 throw(Exception::InvalidIterator);
00096
00101 ConstRandomAccessFilterIterator operator - (Distance distance) const
00102 throw(Exception::InvalidIterator);
00103
00108 Distance operator - (const ConstRandomAccessFilterIterator& iterator) const
00109 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00110
00114 static ConstRandomAccessFilterIterator begin(const Container& container)
00115 throw(Exception::Precondition);
00116
00120 static ConstRandomAccessFilterIterator end(const Container& container)
00121 throw(Exception::Precondition);
00122
00126 static ConstRandomAccessFilterIterator rbegin(const Container& container)
00127 throw(Exception::Precondition);
00128
00132 static ConstRandomAccessFilterIterator rend(const Container& container)
00133 throw(Exception::Precondition);
00134
00136
00140
00142 bool operator + () const throw() { return Base::getTraits().isValid(); }
00143
00145 bool operator - () const throw() { return !Base::getTraits().isValid(); }
00146
00153 bool operator < (const ConstRandomAccessFilterIterator& iterator) const
00154 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00155
00163 bool operator <= (const ConstRandomAccessFilterIterator& iterator) const
00164 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00165
00173 bool operator >= (const ConstRandomAccessFilterIterator& iterator) const
00174 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00175
00182 bool operator > (const ConstRandomAccessFilterIterator& iterator) const
00183 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00184
00186
00187
00188
00194 const DataType& operator [] (Index index) const throw(Exception::InvalidIterator)
00195 {
00196 if (!Base::getTraits().isValid())
00197 {
00198 Exception::InvalidIterator e;
00199 throw e;
00200 }
00201
00202 return Base::iterator_[index];
00203 };
00205
00206 protected:
00207
00208 ConstRandomAccessFilterIterator(const Container& container) throw()
00209 : Base(container)
00210 {
00211 }
00212 };
00214
00219 template <class Predicate, class IteratorRandomAccess>
00220 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess> operator +
00221 (Distance distance, const ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>& iterator)
00222 throw(Exception::InvalidIterator)
00223 {
00224 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess> tmp_iterator(iterator);
00225 return (tmp_iterator += distance);
00226 }
00227
00232 template <class Predicate, class IteratorRandomAccess>
00233 Distance ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator -
00234 (const ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>& b) const
00235 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00236 {
00237 if (!Base::getTraits().isValid())
00238 {
00239 Exception::InvalidIterator e;
00240 throw e;
00241 }
00242 if (!b.getTraits().isValid())
00243 {
00244 Exception::InvalidIterator e;
00245 throw e;
00246 }
00247 if (Base::getTraits().getContainer() != b.getTraits().getContainer())
00248 {
00249 Exception::IncompatibleIterators e;
00250 throw e;
00251 }
00252 return Base::getTraits().getDistance(b.getTraits());
00253 }
00254
00255 template <class Predicate, class IteratorRandomAccess>
00256 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>&
00257 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator += (Distance distance)
00258 throw(Exception::InvalidIterator)
00259 {
00260 if (!Base::getTraits().isValid())
00261 {
00262 Exception::InvalidIterator e;
00263 throw e;
00264 }
00265 if (distance < (Distance)0)
00266 {
00267 return (*this -= -distance);
00268 }
00269 Base::getTraits().forward(distance);
00270
00271 while (!Base::isEnd() && !Base::predicate_(Base::getTraits().getData()))
00272 Base::getTraits().forward();
00273 return *this;
00274 }
00275
00276 template <class Predicate, class IteratorRandomAccess>
00277 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>&
00278 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator -= (Distance distance)
00279 throw(Exception::InvalidIterator)
00280 {
00281 if (Base::getTraits().isSingular())
00282 {
00283 Exception::InvalidIterator e;
00284 throw e;
00285 }
00286 if (distance < (Distance)0)
00287 {
00288 return (*this += -distance);
00289 }
00290 if (Base::getTraits().isEnd() == true)
00291 {
00292 Base::getTraits().toRBegin();
00293 Base::getTraits().backward(distance - 1);
00294 }
00295 else
00296 {
00297 Base::getTraits().backward(distance);
00298
00299 while (!Base::isBegin() && !Base::predicate_(Base::getTraits().getData()))
00300 Base::getTraits().backward();
00301 }
00302 return *this;
00303 }
00304
00305 template <class Predicate, class IteratorRandomAccess>
00306 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00307 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator + (Distance distance) const
00308 throw(Exception::InvalidIterator)
00309 {
00310 ConstRandomAccessFilterIterator iterator(*this);
00311 return (iterator += distance);
00312 }
00313
00314 template <class Predicate, class IteratorRandomAccess>
00315 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00316 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator - (Distance distance) const
00317 throw(Exception::InvalidIterator)
00318 {
00319 ConstRandomAccessFilterIterator iterator(*this);
00320 return (iterator -= distance);
00321 }
00322
00323 template <class Predicate, class IteratorRandomAccess>
00324 bool ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator <
00325 (const ConstRandomAccessFilterIterator& iterator) const
00326 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00327 {
00328 if (!Base::getTraits().isValid())
00329 {
00330 Exception::InvalidIterator e;
00331 throw e;
00332 }
00333 if (!iterator.isValid())
00334 {
00335 Exception::InvalidIterator e;
00336 throw e;
00337 }
00338 if (Base::getTraits().getContainer() != iterator.getContainer())
00339 {
00340 Exception::IncompatibleIterators e;
00341 throw e;
00342 }
00343
00344 return (Base::getTraits().operator < (iterator.getTraits()));
00345 }
00346
00347 template <class Predicate, class IteratorRandomAccess>
00348 bool ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator <=
00349 (const ConstRandomAccessFilterIterator& iterator) const
00350 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00351 {
00352 if (!Base::getTraits().isValid())
00353 {
00354 Exception::InvalidIterator e;
00355 throw e;
00356 }
00357 if (!iterator.isValid())
00358 {
00359 Exception::InvalidIterator e;
00360 throw e;
00361 }
00362 if (Base::getTraits().getContainer() != iterator.getContainer())
00363 {
00364 Exception::IncompatibleIterators e;
00365 throw e;
00366 }
00367 return !(Base::getTraits().operator > (iterator.getTraits()));
00368 }
00369
00370 template <class Predicate, class IteratorRandomAccess>
00371 bool ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator >=
00372 (const ConstRandomAccessFilterIterator& iterator) const
00373 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00374 {
00375 if (!Base::getTraits().isValid())
00376 {
00377 Exception::InvalidIterator e;
00378 throw e;
00379 }
00380 if (!iterator.isValid())
00381 {
00382 Exception::InvalidIterator e;
00383 throw e;
00384 }
00385 if (Base::getTraits().getContainer() != iterator.getContainer())
00386 {
00387 Exception::IncompatibleIterators e;
00388 throw e;
00389 }
00390
00391 return !(Base::getTraits().operator < (iterator.getTraits()));
00392 }
00393
00394 template <class Predicate, class IteratorRandomAccess>
00395 bool ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator >
00396 (const ConstRandomAccessFilterIterator& iterator) const
00397 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00398 {
00399 if (!Base::getTraits().isValid())
00400 {
00401 Exception::InvalidIterator e;
00402 throw e;
00403 }
00404 if (!iterator.isValid())
00405 {
00406 Exception::InvalidIterator e;
00407 throw e;
00408 }
00409 if (Base::getTraits().getContainer() != iterator.getContainer())
00410 {
00411 Exception::IncompatibleIterators e;
00412 throw e;
00413 }
00414
00415 return (Base::getTraits().operator > (iterator.getTraits()));
00416 }
00417
00418 template <class Predicate, class IteratorRandomAccess>
00419 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00420 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::begin(const Container& container)
00421 throw(Exception::Precondition)
00422 {
00423 ConstRandomAccessFilterIterator iterator(container);
00424 iterator.toBegin();
00425 return iterator;
00426 }
00427
00428 template <class Predicate, class IteratorRandomAccess>
00429 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00430 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::end(const Container& container)
00431 throw(Exception::Precondition)
00432 {
00433 ConstRandomAccessFilterIterator iterator(container);
00434 iterator.toEnd();
00435 return iterator;
00436 }
00437
00438 template <class Predicate, class IteratorRandomAccess>
00439 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00440 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::rbegin(const Container& container)
00441 throw(Exception::Precondition)
00442 {
00443 ConstRandomAccessFilterIterator iterator(container);
00444 iterator.toRBegin();
00445 return iterator;
00446 }
00447
00448 template <class Predicate, class IteratorRandomAccess>
00449 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00450 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::rend(const Container& container)
00451 throw(Exception::Precondition)
00452 {
00453 ConstRandomAccessFilterIterator iterator(container);
00454 iterator.toREnd();
00455 return iterator;
00456 }
00457
00462
00465 template <class Predicate, class IteratorRandomAccess>
00466 class RandomAccessFilterIterator
00467 : public ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00468 {
00469 public:
00470
00474
00476 typedef typename IteratorRandomAccess::container_type Container;
00478 typedef typename IteratorRandomAccess::value_type value_type;
00480 typedef typename IteratorRandomAccess::difference_type difference_type;
00482 typedef typename IteratorRandomAccess::pointer pointer;
00484 typedef typename IteratorRandomAccess::reference reference;
00486 typedef ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess> Base;
00488
00492
00494 RandomAccessFilterIterator() throw() {}
00495
00497 RandomAccessFilterIterator(Predicate p, IteratorRandomAccess it) throw()
00498 : ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>(p,it)
00499 {
00500 }
00501
00503 RandomAccessFilterIterator(const RandomAccessFilterIterator& iterator) throw()
00504 : Base(iterator)
00505 {
00506 }
00507
00509 ~RandomAccessFilterIterator() throw() {}
00511
00515
00516 reference operator [] (Index index) const throw(Exception::InvalidIterator) { return const_cast<reference>(Base::getTraits().getData(index)); }
00518 reference operator * () const throw() { return const_cast<reference>(Base::getTraits().getData()); }
00520 pointer operator -> () const throw() { return const_cast<pointer>(&Base::getTraits().getData()); }
00522
00529 static RandomAccessFilterIterator begin(const Container& container)
00530 throw(Exception::InvalidIterator);
00531
00535 static RandomAccessFilterIterator end(const Container& container)
00536 throw(Exception::InvalidIterator);
00537
00541 static RandomAccessFilterIterator rbegin(const Container& container)
00542 throw(Exception::InvalidIterator);
00543
00547 static RandomAccessFilterIterator rend(const Container& container)
00548 throw(Exception::InvalidIterator);
00550
00551 protected:
00552
00553 RandomAccessFilterIterator(const Container& container) throw()
00554 : Base(container)
00555 {
00556 }
00557
00558 };
00560
00561 template <class Predicate, class IteratorRandomAccess>
00562 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00563 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>::begin(const Container& container)
00564 throw(Exception::InvalidIterator)
00565 {
00566 RandomAccessFilterIterator iterator(container);
00567 iterator.toBegin();
00568 return iterator;
00569 }
00570
00571 template <class Predicate, class IteratorRandomAccess>
00572 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00573 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>::end(const Container& container)
00574 throw(Exception::InvalidIterator)
00575 {
00576 RandomAccessFilterIterator iterator(container);
00577 iterator.toEnd();
00578 return iterator;
00579 }
00580
00581 template <class Predicate, class IteratorRandomAccess>
00582 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00583 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>::rbegin(const Container& container)
00584 throw(Exception::InvalidIterator)
00585 {
00586 RandomAccessFilterIterator iterator(container);
00587 iterator.toRBegin();
00588 return iterator;
00589 }
00590
00591 template <class Predicate, class IteratorRandomAccess>
00592 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00593 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>::rend(const Container& container)
00594 throw(Exception::InvalidIterator)
00595 {
00596 RandomAccessFilterIterator iterator(container);
00597 iterator.toREnd();
00598 return iterator;
00599 }
00600
00601 }
00602
00603 #endif // BALL_KERNEL_RANDOMACCESSFILTERITERATOR_H