00001 #ifndef BALL_LINALG_BIDIRECTIONALFILTERITERATOR_H
00002 #define BALL_LINALG_BIDIRECTIONALFILTERITERATOR_H
00003
00004 #ifndef BALL_LINALG_FORWARDFILTERITERATOR_H
00005 # include <BALL/MATHS/LINALG/forwardFilterIterator.h>
00006 #endif
00007
00008 namespace BALL
00009 {
00010
00015
00018 template <class Predicate, class IteratorBidirectional>
00019 class ConstBidirectionalFilterIterator
00020 : public ConstForwardFilterIterator<Predicate, IteratorBidirectional>
00021 {
00022 public:
00023
00027
00028
00030 typedef typename IteratorBidirectional::container_type Container;
00032 typedef typename IteratorBidirectional::value_type DataType;
00034 typedef typename IteratorBidirectional::difference_type Position;
00036 typedef typename IteratorBidirectional::traits_type Traits;
00038 typedef typename IteratorBidirectional::value_type value_type;
00040 typedef typename IteratorBidirectional::difference_type difference_type;
00042 typedef typename IteratorBidirectional::pointer pointer;
00044 typedef typename IteratorBidirectional::reference reference;
00046 typedef std::bidirectional_iterator_tag iterator_category;
00047
00048 typedef ConstForwardFilterIterator<Predicate, IteratorBidirectional> Base;
00050
00054
00056 ConstBidirectionalFilterIterator() throw() {}
00057
00059 ConstBidirectionalFilterIterator(Predicate p, IteratorBidirectional it) throw()
00060 : ConstForwardFilterIterator<Predicate, IteratorBidirectional>(p,it)
00061 {
00062 }
00063
00065 ConstBidirectionalFilterIterator(const ConstBidirectionalFilterIterator& iterator) throw()
00066 : Base(iterator)
00067 {
00068 }
00069
00071 ~ConstBidirectionalFilterIterator() throw() {}
00073
00075 void setIterator(const IteratorBidirectional& iterator) throw()
00076 {
00077 Base::iterator_ = iterator;
00078
00079 if (isEnd())
00080 {
00081 Base::getTraits().backward();
00082
00083 while (!isBegin() && !Base::predicate_(Base::getTraits().getData()))
00084 Base::getTraits().backward();
00085 return;
00086 }
00087
00088 while (!isEnd() && !Base::predicate_(Base::getTraits().getData()))
00089 Base::getTraits().forward();
00090 }
00091
00095
00097 void toBegin() throw(Exception::SingularIterator);
00098
00100 bool isBegin() const throw() { return Base::getTraits().isBegin(); }
00101
00103 void toEnd() throw(Exception::SingularIterator);
00104
00106 bool isEnd() const throw() { return Base::getTraits().isEnd(); }
00107
00109 void toRBegin() throw(Exception::SingularIterator);
00110
00112 bool isRBegin() const throw() { return Base::getTraits().isRBegin(); }
00113
00115 void toREnd() throw(Exception::SingularIterator);
00116
00118 bool isREnd() const throw() { return Base::getTraits().isREnd(); }
00119
00121 ConstBidirectionalFilterIterator& operator ++ () throw(Exception::InvalidIterator);
00122
00124 ConstBidirectionalFilterIterator operator ++ (int) throw(Exception::InvalidIterator);
00125
00127 ConstBidirectionalFilterIterator& operator -- () throw(Exception::SingularIterator);
00128
00130 ConstBidirectionalFilterIterator operator -- (int) throw(Exception::SingularIterator);
00131
00133 static ConstBidirectionalFilterIterator begin(const Container& container) throw(Exception::Precondition);
00134
00136 static ConstBidirectionalFilterIterator end(const Container& container) throw(Exception::Precondition);
00137
00139 static ConstBidirectionalFilterIterator rbegin(const Container& container) throw(Exception::Precondition);
00140
00142 static ConstBidirectionalFilterIterator rend(const Container& container) throw(Exception::Precondition);
00144
00145 protected:
00146
00148 ConstBidirectionalFilterIterator(const Container& container) throw()
00149 : Base(container)
00150 {
00151 }
00152 };
00154
00155 template <class Predicate, class IteratorBidirectional>
00156 void ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::toBegin()
00157 throw(Exception::SingularIterator)
00158 {
00159 if (Base::getTraits().isSingular())
00160 {
00161 Exception::SingularIterator e;
00162 throw(e);
00163 }
00164 Base::getTraits().toBegin();
00165 }
00166
00167 template <class Predicate, class IteratorBidirectional>
00168 void ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::toEnd()
00169 throw(Exception::SingularIterator)
00170 {
00171 if (Base::getTraits().isSingular())
00172 {
00173 Exception::SingularIterator e;
00174 throw(e);
00175 }
00176 Base::getTraits().toEnd();
00177 }
00178
00179 template <class Predicate, class IteratorBidirectional>
00180 void ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::toRBegin()
00181 throw(Exception::SingularIterator)
00182 {
00183 if (Base::getTraits().isSingular())
00184 {
00185 Exception::SingularIterator e;
00186 throw(e);
00187 }
00188 Base::getTraits().toRBegin();
00189 }
00190
00191 template <class Predicate, class IteratorBidirectional>
00192 void ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::toREnd()
00193 throw(Exception::SingularIterator)
00194 {
00195 if (Base::getTraits().isSingular())
00196 {
00197 Exception::SingularIterator e;
00198 throw(e);
00199 }
00200 Base::getTraits().toREnd();
00201 }
00202
00203 template <class Predicate, class IteratorBidirectional>
00204 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>&
00205 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator ++ ()
00206 throw(Exception::InvalidIterator)
00207 {
00208 if (!Base::getTraits().isValid())
00209 {
00210 Exception::InvalidIterator e;
00211 throw(e);
00212 }
00213 Base::getTraits().forward();
00214
00215 while (!isEnd() && !Base::predicate_(Base::getTraits().getData()))
00216 Base::getTraits().forward();
00217 return *this;
00218 }
00219
00220 template <class Predicate, class IteratorBidirectional>
00221 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00222 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator ++ (int)
00223 throw(Exception::InvalidIterator)
00224 {
00225 if (!Base::getTraits().isValid())
00226 {
00227 Exception::InvalidIterator e;
00228 throw(e);
00229 }
00230 ConstBidirectionalFilterIterator iterator(*this);
00231 ++(*this);
00232 return iterator;
00233 }
00234
00235 template <class Predicate, class IteratorBidirectional>
00236 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>&
00237 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator -- ()
00238 throw(Exception::SingularIterator)
00239 {
00240 if (Base::getTraits().isSingular())
00241 {
00242 Exception::SingularIterator e;
00243 throw(e);
00244 }
00245 Base::getTraits().backward();
00246
00247 while (!isBegin() && !Base::predicate_(Base::getTraits().getData()))
00248 Base::getTraits().backward();
00249 return *this;
00250 }
00251
00252 template <class Predicate, class IteratorBidirectional>
00253 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00254 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator -- (int)
00255 throw(Exception::SingularIterator)
00256 {
00257 if (Base::getTraits().isSingular())
00258 {
00259 Exception::SingularIterator e;
00260 throw(e);
00261 }
00262 ConstBidirectionalFilterIterator iterator(*this);
00263 --(*this);
00264 return iterator;
00265 }
00266
00267 template <class Predicate, class IteratorBidirectional>
00268 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00269 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::begin(const Container& container)
00270 throw(Exception::Precondition)
00271 {
00272 ConstBidirectionalFilterIterator iterator(container);
00273 iterator.toBegin();
00274 return iterator;
00275 }
00276
00277 template <class Predicate, class IteratorBidirectional>
00278 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00279 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::end(const Container& container)
00280 throw(Exception::Precondition)
00281 {
00282 ConstBidirectionalFilterIterator iterator(container);
00283 iterator.toEnd();
00284 return iterator;
00285 }
00286
00287 template <class Predicate, class IteratorBidirectional>
00288 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00289 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::rbegin(const Container& container)
00290 throw(Exception::Precondition)
00291 {
00292 ConstBidirectionalFilterIterator iterator(container);
00293 iterator.toRBegin();
00294 return iterator;
00295 }
00296
00297 template <class Predicate, class IteratorBidirectional>
00298 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00299 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::rend(const Container& container)
00300 throw(Exception::Precondition)
00301 {
00302 ConstBidirectionalFilterIterator iterator(container);
00303 iterator.toREnd();
00304 return iterator;
00305 }
00306
00308 template <class Predicate, class IteratorBidirectional>
00309 class BidirectionalFilterIterator
00310 : public ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00311 {
00312 public:
00313
00317
00319 typedef typename IteratorBidirectional::container_type Container;
00321 typedef typename IteratorBidirectional::value_type DataType;
00323 typedef typename IteratorBidirectional::difference_type Position;
00325 typedef typename IteratorBidirectional::traits_type Traits;
00327 typedef typename IteratorBidirectional::value_type value_type;
00329 typedef typename IteratorBidirectional::difference_type difference_type;
00331 typedef typename IteratorBidirectional::pointer pointer;
00333 typedef typename IteratorBidirectional::reference reference;
00334
00335 typedef ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional> Base;
00337
00341
00343 BidirectionalFilterIterator() throw() {}
00344
00346 BidirectionalFilterIterator(Predicate p, IteratorBidirectional it) throw()
00347 : ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>(p,it)
00348 {
00349 }
00350
00352 BidirectionalFilterIterator(const BidirectionalFilterIterator& iterator)
00353 throw()
00354 : ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>(iterator)
00355 {
00356 }
00357
00359 ~BidirectionalFilterIterator() throw() {}
00360
00362
00366
00368 reference operator * () const throw() { return (reference)Base::getTraits().getData(); }
00369
00371 pointer operator -> () const throw() { return (pointer)&Base::getTraits().getData(); }
00372
00374 BidirectionalFilterIterator& operator ++ () throw(Exception::Precondition);
00375
00377 BidirectionalFilterIterator operator ++ (int) throw(Exception::Precondition);
00378
00380 BidirectionalFilterIterator& operator -- () throw(Exception::Precondition);
00381
00383 BidirectionalFilterIterator operator -- (int) throw(Exception::Precondition);
00384
00386 static BidirectionalFilterIterator begin(const Container& container)
00387 throw(Exception::Precondition);
00388
00390 static BidirectionalFilterIterator end(const Container& container)
00391 throw(Exception::Precondition);
00392
00394 static BidirectionalFilterIterator rbegin(const Container& container)
00395 throw(Exception::Precondition);
00396
00398 static BidirectionalFilterIterator rend(const Container& container)
00399 throw(Exception::Precondition);
00401
00402 protected:
00403
00405 BidirectionalFilterIterator(const Container& container) throw();
00406 };
00407
00408
00409 template <class Predicate, class IteratorBidirectional>
00410 BidirectionalFilterIterator<Predicate, IteratorBidirectional>&
00411 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator ++ ()
00412 throw(Exception::Precondition)
00413 {
00414 Base::operator ++ ();
00415 return *this;
00416 }
00417
00418 template <class Predicate, class IteratorBidirectional>
00419 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00420 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator ++ (int)
00421 throw(Exception::Precondition)
00422 {
00423 BidirectionalFilterIterator iterator(*this);
00424 this->operator ++ ();
00425 return iterator;
00426 }
00427
00428 template <class Predicate, class IteratorBidirectional>
00429 BidirectionalFilterIterator<Predicate, IteratorBidirectional>&
00430 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator -- ()
00431 throw(Exception::Precondition)
00432 {
00433 Base::operator -- ();
00434 return *this;
00435 }
00436
00437 template <class Predicate, class IteratorBidirectional>
00438 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00439 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator -- (int)
00440 throw(Exception::Precondition)
00441 {
00442 BidirectionalFilterIterator iterator(*this);
00443 this->operator -- ();
00444 return iterator;
00445 }
00446
00447 template <class Predicate, class IteratorBidirectional>
00448 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00449 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::begin(const Container& container)
00450 throw(Exception::Precondition)
00451 {
00452 BidirectionalFilterIterator iterator(container);
00453 iterator.toBegin();
00454 return iterator;
00455 }
00456
00457 template <class Predicate, class IteratorBidirectional>
00458 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00459 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::end(const Container& container)
00460 throw(Exception::Precondition)
00461 {
00462 BidirectionalFilterIterator iterator(container);
00463 iterator.toEnd();
00464 return iterator;
00465 }
00466
00467 template <class Predicate, class IteratorBidirectional>
00468 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00469 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::rbegin(const Container& container)
00470 throw(Exception::Precondition)
00471 {
00472 BidirectionalFilterIterator iterator(container);
00473 iterator.toRBegin();
00474 return iterator;
00475 }
00476
00477 template <class Predicate, class IteratorBidirectional>
00478 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00479 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::rend(const Container& container)
00480 throw(Exception::Precondition)
00481 {
00482 BidirectionalFilterIterator iterator(container);
00483 iterator.toREnd();
00484 return iterator;
00485 }
00486
00487 template <class Predicate, class IteratorBidirectional>
00488 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::BidirectionalFilterIterator(const Container& container)
00489 throw()
00490 : ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>(container)
00491 {
00492 }
00493
00494
00495 }
00496
00497 #endif // BALL_KERNEL_BIDIRECTIONALFILTERITERATOR_H