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() {}
00058
00060 ConstRandomAccessFilterIterator(Predicate p, IteratorRandomAccess it)
00061 : ConstBidirectionalFilterIterator<Predicate, IteratorRandomAccess>(p,it)
00062 {
00063 }
00064
00066 ConstRandomAccessFilterIterator(const ConstRandomAccessFilterIterator& iterator)
00067 : Base(iterator)
00068 {
00069 }
00070
00072 ~ConstRandomAccessFilterIterator() {}
00074
00075
00076
00080
00084 ConstRandomAccessFilterIterator& operator += (Distance distance);
00085
00089 ConstRandomAccessFilterIterator& operator -= (Distance distance);
00090
00095 ConstRandomAccessFilterIterator operator + (Distance distance) const;
00096
00102 ConstRandomAccessFilterIterator operator - (Distance distance) const;
00103
00110 Distance operator - (const ConstRandomAccessFilterIterator& iterator) const;
00111
00116 static ConstRandomAccessFilterIterator begin(const Container& container);
00117
00122 static ConstRandomAccessFilterIterator end(const Container& container);
00123
00128 static ConstRandomAccessFilterIterator rbegin(const Container& container);
00129
00134 static ConstRandomAccessFilterIterator rend(const Container& container);
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 ConstRandomAccessFilterIterator& iterator) const;
00155
00163 bool operator <= (const ConstRandomAccessFilterIterator& iterator) const;
00164
00172 bool operator >= (const ConstRandomAccessFilterIterator& iterator) const;
00173
00180 bool operator > (const ConstRandomAccessFilterIterator& iterator) const;
00181
00183
00184
00185
00192 const DataType& operator [] (Index index) const
00193 {
00194 if (!Base::getTraits().isValid())
00195 {
00196 Exception::InvalidIterator e;
00197 throw e;
00198 }
00199
00200 return Base::iterator_[index];
00201 };
00203
00204 protected:
00205
00206 ConstRandomAccessFilterIterator(const Container& container)
00207 : Base(container)
00208 {
00209 }
00210 };
00212
00218 template <class Predicate, class IteratorRandomAccess>
00219 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess> operator +
00220 (Distance distance, const ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>& iterator)
00221 {
00222 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess> tmp_iterator(iterator);
00223 return (tmp_iterator += distance);
00224 }
00225
00232 template <class Predicate, class IteratorRandomAccess>
00233 Distance ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator -
00234 (const ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>& b) const
00235 {
00236 if (!Base::getTraits().isValid())
00237 {
00238 Exception::InvalidIterator e;
00239 throw e;
00240 }
00241 if (!b.getTraits().isValid())
00242 {
00243 Exception::InvalidIterator e;
00244 throw e;
00245 }
00246 if (Base::getTraits().getContainer() != b.getTraits().getContainer())
00247 {
00248 Exception::IncompatibleIterators e;
00249 throw e;
00250 }
00251 return Base::getTraits().getDistance(b.getTraits());
00252 }
00253
00254 template <class Predicate, class IteratorRandomAccess>
00255 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>&
00256 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator += (Distance distance)
00257 {
00258 if (!Base::getTraits().isValid())
00259 {
00260 Exception::InvalidIterator e;
00261 throw e;
00262 }
00263 if (distance < (Distance)0)
00264 {
00265 return (*this -= -distance);
00266 }
00267 Base::getTraits().forward(distance);
00268
00269 while (!Base::isEnd() && !Base::predicate_(Base::getTraits().getData()))
00270 Base::getTraits().forward();
00271 return *this;
00272 }
00273
00274 template <class Predicate, class IteratorRandomAccess>
00275 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>&
00276 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator -= (Distance distance)
00277 {
00278 if (Base::getTraits().isSingular())
00279 {
00280 Exception::InvalidIterator e;
00281 throw e;
00282 }
00283 if (distance < (Distance)0)
00284 {
00285 return (*this += -distance);
00286 }
00287 if (Base::getTraits().isEnd() == true)
00288 {
00289 Base::getTraits().toRBegin();
00290 Base::getTraits().backward(distance - 1);
00291 }
00292 else
00293 {
00294 Base::getTraits().backward(distance);
00295
00296 while (!Base::isBegin() && !Base::predicate_(Base::getTraits().getData()))
00297 Base::getTraits().backward();
00298 }
00299 return *this;
00300 }
00301
00302 template <class Predicate, class IteratorRandomAccess>
00303 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00304 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator + (Distance distance) const
00305 {
00306 ConstRandomAccessFilterIterator iterator(*this);
00307 return (iterator += distance);
00308 }
00309
00310 template <class Predicate, class IteratorRandomAccess>
00311 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00312 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator - (Distance distance) const
00313 {
00314 ConstRandomAccessFilterIterator iterator(*this);
00315 return (iterator -= distance);
00316 }
00317
00318 template <class Predicate, class IteratorRandomAccess>
00319 bool ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator <
00320 (const ConstRandomAccessFilterIterator& iterator) const
00321 {
00322 if (!Base::getTraits().isValid())
00323 {
00324 Exception::InvalidIterator e;
00325 throw e;
00326 }
00327 if (!iterator.isValid())
00328 {
00329 Exception::InvalidIterator e;
00330 throw e;
00331 }
00332 if (Base::getTraits().getContainer() != iterator.getContainer())
00333 {
00334 Exception::IncompatibleIterators e;
00335 throw e;
00336 }
00337
00338 return (Base::getTraits().operator < (iterator.getTraits()));
00339 }
00340
00341 template <class Predicate, class IteratorRandomAccess>
00342 bool ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator <=
00343 (const ConstRandomAccessFilterIterator& iterator) const
00344 {
00345 if (!Base::getTraits().isValid())
00346 {
00347 Exception::InvalidIterator e;
00348 throw e;
00349 }
00350 if (!iterator.isValid())
00351 {
00352 Exception::InvalidIterator e;
00353 throw e;
00354 }
00355 if (Base::getTraits().getContainer() != iterator.getContainer())
00356 {
00357 Exception::IncompatibleIterators e;
00358 throw e;
00359 }
00360 return !(Base::getTraits().operator > (iterator.getTraits()));
00361 }
00362
00363 template <class Predicate, class IteratorRandomAccess>
00364 bool ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator >=
00365 (const ConstRandomAccessFilterIterator& iterator) const
00366 {
00367 if (!Base::getTraits().isValid())
00368 {
00369 Exception::InvalidIterator e;
00370 throw e;
00371 }
00372 if (!iterator.isValid())
00373 {
00374 Exception::InvalidIterator e;
00375 throw e;
00376 }
00377 if (Base::getTraits().getContainer() != iterator.getContainer())
00378 {
00379 Exception::IncompatibleIterators e;
00380 throw e;
00381 }
00382
00383 return !(Base::getTraits().operator < (iterator.getTraits()));
00384 }
00385
00386 template <class Predicate, class IteratorRandomAccess>
00387 bool ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::operator >
00388 (const ConstRandomAccessFilterIterator& iterator) const
00389 {
00390 if (!Base::getTraits().isValid())
00391 {
00392 Exception::InvalidIterator e;
00393 throw e;
00394 }
00395 if (!iterator.isValid())
00396 {
00397 Exception::InvalidIterator e;
00398 throw e;
00399 }
00400 if (Base::getTraits().getContainer() != iterator.getContainer())
00401 {
00402 Exception::IncompatibleIterators e;
00403 throw e;
00404 }
00405
00406 return (Base::getTraits().operator > (iterator.getTraits()));
00407 }
00408
00409 template <class Predicate, class IteratorRandomAccess>
00410 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00411 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::begin(const Container& container)
00412 {
00413 ConstRandomAccessFilterIterator iterator(container);
00414 iterator.toBegin();
00415 return iterator;
00416 }
00417
00418 template <class Predicate, class IteratorRandomAccess>
00419 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00420 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::end(const Container& container)
00421 {
00422 ConstRandomAccessFilterIterator iterator(container);
00423 iterator.toEnd();
00424 return iterator;
00425 }
00426
00427 template <class Predicate, class IteratorRandomAccess>
00428 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00429 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::rbegin(const Container& container)
00430 {
00431 ConstRandomAccessFilterIterator iterator(container);
00432 iterator.toRBegin();
00433 return iterator;
00434 }
00435
00436 template <class Predicate, class IteratorRandomAccess>
00437 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00438 ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>::rend(const Container& container)
00439 {
00440 ConstRandomAccessFilterIterator iterator(container);
00441 iterator.toREnd();
00442 return iterator;
00443 }
00444
00449
00452 template <class Predicate, class IteratorRandomAccess>
00453 class RandomAccessFilterIterator
00454 : public ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00455 {
00456 public:
00457
00461
00463 typedef typename IteratorRandomAccess::container_type Container;
00465 typedef typename IteratorRandomAccess::value_type value_type;
00467 typedef typename IteratorRandomAccess::difference_type difference_type;
00469 typedef typename IteratorRandomAccess::pointer pointer;
00471 typedef typename IteratorRandomAccess::reference reference;
00473 typedef ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess> Base;
00475
00479
00481 RandomAccessFilterIterator() {}
00482
00484 RandomAccessFilterIterator(Predicate p, IteratorRandomAccess it)
00485 : ConstRandomAccessFilterIterator<Predicate, IteratorRandomAccess>(p,it)
00486 {
00487 }
00488
00490 RandomAccessFilterIterator(const RandomAccessFilterIterator& iterator)
00491 : Base(iterator)
00492 {
00493 }
00494
00496 ~RandomAccessFilterIterator() {}
00498
00505 reference operator [] (Index index) const { return const_cast<reference>(Base::getTraits().getData(index)); }
00507 reference operator * () const { return const_cast<reference>(Base::getTraits().getData()); }
00509 pointer operator -> () const { return const_cast<pointer>(&Base::getTraits().getData()); }
00511
00519 static RandomAccessFilterIterator begin(const Container& container);
00520
00525 static RandomAccessFilterIterator end(const Container& container);
00526
00531 static RandomAccessFilterIterator rbegin(const Container& container);
00532
00537 static RandomAccessFilterIterator rend(const Container& container);
00539
00540 protected:
00541
00542 RandomAccessFilterIterator(const Container& container)
00543 : Base(container)
00544 {
00545 }
00546
00547 };
00549
00550 template <class Predicate, class IteratorRandomAccess>
00551 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00552 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>::begin(const Container& container)
00553 {
00554 RandomAccessFilterIterator iterator(container);
00555 iterator.toBegin();
00556 return iterator;
00557 }
00558
00559 template <class Predicate, class IteratorRandomAccess>
00560 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00561 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>::end(const Container& container)
00562 {
00563 RandomAccessFilterIterator iterator(container);
00564 iterator.toEnd();
00565 return iterator;
00566 }
00567
00568 template <class Predicate, class IteratorRandomAccess>
00569 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00570 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>::rbegin(const Container& container)
00571 {
00572 RandomAccessFilterIterator iterator(container);
00573 iterator.toRBegin();
00574 return iterator;
00575 }
00576
00577 template <class Predicate, class IteratorRandomAccess>
00578 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>
00579 RandomAccessFilterIterator<Predicate, IteratorRandomAccess>::rend(const Container& container)
00580 {
00581 RandomAccessFilterIterator iterator(container);
00582 iterator.toREnd();
00583 return iterator;
00584 }
00585
00586 }
00587
00588 #endif // BALL_KERNEL_RANDOMACCESSFILTERITERATOR_H