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() {}
00057
00059 ConstBidirectionalFilterIterator(Predicate p, IteratorBidirectional it)
00060 : ConstForwardFilterIterator<Predicate, IteratorBidirectional>(p,it)
00061 {
00062 }
00063
00065 ConstBidirectionalFilterIterator(const ConstBidirectionalFilterIterator& iterator)
00066 : Base(iterator)
00067 {
00068 }
00069
00071 ~ConstBidirectionalFilterIterator() {}
00073
00075 void setIterator(const IteratorBidirectional& iterator)
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
00099 void toBegin();
00100
00102 bool isBegin() const { return Base::getTraits().isBegin(); }
00103
00107 void toEnd();
00108
00110 bool isEnd() const { return Base::getTraits().isEnd(); }
00111
00115 void toRBegin();
00116
00118 bool isRBegin() const { return Base::getTraits().isRBegin(); }
00119
00123 void toREnd();
00124
00126 bool isREnd() const { return Base::getTraits().isREnd(); }
00127
00131 ConstBidirectionalFilterIterator& operator ++ ();
00132
00136 ConstBidirectionalFilterIterator operator ++ (int);
00137
00141 ConstBidirectionalFilterIterator& operator -- ();
00142
00146 ConstBidirectionalFilterIterator operator -- (int);
00147
00151 static ConstBidirectionalFilterIterator begin(const Container& container);
00152
00156 static ConstBidirectionalFilterIterator end(const Container& container);
00157
00161 static ConstBidirectionalFilterIterator rbegin(const Container& container);
00162
00166 static ConstBidirectionalFilterIterator rend(const Container& container);
00168
00169 protected:
00170
00172 ConstBidirectionalFilterIterator(const Container& container)
00173 : Base(container)
00174 {
00175 }
00176 };
00178
00179 template <class Predicate, class IteratorBidirectional>
00180 void ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::toBegin()
00181 {
00182 if (Base::getTraits().isSingular())
00183 {
00184 Exception::SingularIterator e;
00185 throw(e);
00186 }
00187 Base::getTraits().toBegin();
00188 }
00189
00190 template <class Predicate, class IteratorBidirectional>
00191 void ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::toEnd()
00192 {
00193 if (Base::getTraits().isSingular())
00194 {
00195 Exception::SingularIterator e;
00196 throw(e);
00197 }
00198 Base::getTraits().toEnd();
00199 }
00200
00201 template <class Predicate, class IteratorBidirectional>
00202 void ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::toRBegin()
00203 {
00204 if (Base::getTraits().isSingular())
00205 {
00206 Exception::SingularIterator e;
00207 throw(e);
00208 }
00209 Base::getTraits().toRBegin();
00210 }
00211
00212 template <class Predicate, class IteratorBidirectional>
00213 void ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::toREnd()
00214 {
00215 if (Base::getTraits().isSingular())
00216 {
00217 Exception::SingularIterator e;
00218 throw(e);
00219 }
00220 Base::getTraits().toREnd();
00221 }
00222
00223 template <class Predicate, class IteratorBidirectional>
00224 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>&
00225 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator ++ ()
00226 {
00227 if (!Base::getTraits().isValid())
00228 {
00229 Exception::InvalidIterator e;
00230 throw(e);
00231 }
00232 Base::getTraits().forward();
00233
00234 while (!isEnd() && !Base::predicate_(Base::getTraits().getData()))
00235 Base::getTraits().forward();
00236 return *this;
00237 }
00238
00239 template <class Predicate, class IteratorBidirectional>
00240 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00241 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator ++ (int)
00242 {
00243 if (!Base::getTraits().isValid())
00244 {
00245 Exception::InvalidIterator e;
00246 throw(e);
00247 }
00248 ConstBidirectionalFilterIterator iterator(*this);
00249 ++(*this);
00250 return iterator;
00251 }
00252
00253 template <class Predicate, class IteratorBidirectional>
00254 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>&
00255 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator -- ()
00256 {
00257 if (Base::getTraits().isSingular())
00258 {
00259 Exception::SingularIterator e;
00260 throw(e);
00261 }
00262 Base::getTraits().backward();
00263
00264 while (!isBegin() && !Base::predicate_(Base::getTraits().getData()))
00265 Base::getTraits().backward();
00266 return *this;
00267 }
00268
00269 template <class Predicate, class IteratorBidirectional>
00270 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00271 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator -- (int)
00272 {
00273 if (Base::getTraits().isSingular())
00274 {
00275 Exception::SingularIterator e;
00276 throw(e);
00277 }
00278 ConstBidirectionalFilterIterator iterator(*this);
00279 --(*this);
00280 return iterator;
00281 }
00282
00283 template <class Predicate, class IteratorBidirectional>
00284 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00285 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::begin(const Container& container)
00286 {
00287 ConstBidirectionalFilterIterator iterator(container);
00288 iterator.toBegin();
00289 return iterator;
00290 }
00291
00292 template <class Predicate, class IteratorBidirectional>
00293 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00294 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::end(const Container& container)
00295 {
00296 ConstBidirectionalFilterIterator iterator(container);
00297 iterator.toEnd();
00298 return iterator;
00299 }
00300
00301 template <class Predicate, class IteratorBidirectional>
00302 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00303 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::rbegin(const Container& container)
00304 {
00305 ConstBidirectionalFilterIterator iterator(container);
00306 iterator.toRBegin();
00307 return iterator;
00308 }
00309
00310 template <class Predicate, class IteratorBidirectional>
00311 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00312 ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>::rend(const Container& container)
00313 {
00314 ConstBidirectionalFilterIterator iterator(container);
00315 iterator.toREnd();
00316 return iterator;
00317 }
00318
00320 template <class Predicate, class IteratorBidirectional>
00321 class BidirectionalFilterIterator
00322 : public ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>
00323 {
00324 public:
00325
00329
00331 typedef typename IteratorBidirectional::container_type Container;
00333 typedef typename IteratorBidirectional::value_type DataType;
00335 typedef typename IteratorBidirectional::difference_type Position;
00337 typedef typename IteratorBidirectional::traits_type Traits;
00339 typedef typename IteratorBidirectional::value_type value_type;
00341 typedef typename IteratorBidirectional::difference_type difference_type;
00343 typedef typename IteratorBidirectional::pointer pointer;
00345 typedef typename IteratorBidirectional::reference reference;
00346
00347 typedef ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional> Base;
00349
00353
00355 BidirectionalFilterIterator() {}
00356
00358 BidirectionalFilterIterator(Predicate p, IteratorBidirectional it)
00359 : ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>(p,it)
00360 {
00361 }
00362
00364 BidirectionalFilterIterator(const BidirectionalFilterIterator& iterator)
00365 : ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>(iterator)
00366 {
00367 }
00368
00370 ~BidirectionalFilterIterator() {}
00371
00373
00377
00379 reference operator * () const { return (reference)Base::getTraits().getData(); }
00380
00382 pointer operator -> () const { return (pointer)&Base::getTraits().getData(); }
00383
00387 BidirectionalFilterIterator& operator ++ ();
00388
00392 BidirectionalFilterIterator operator ++ (int);
00393
00397 BidirectionalFilterIterator& operator -- ();
00398
00402 BidirectionalFilterIterator operator -- (int);
00403
00407 static BidirectionalFilterIterator begin(const Container& container);
00408
00412 static BidirectionalFilterIterator end(const Container& container);
00413
00417 static BidirectionalFilterIterator rbegin(const Container& container);
00418
00422 static BidirectionalFilterIterator rend(const Container& container);
00424
00425 protected:
00426
00428 BidirectionalFilterIterator(const Container& container);
00429 };
00430
00431
00432 template <class Predicate, class IteratorBidirectional>
00433 BidirectionalFilterIterator<Predicate, IteratorBidirectional>&
00434 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator ++ ()
00435 {
00436 Base::operator ++ ();
00437 return *this;
00438 }
00439
00440 template <class Predicate, class IteratorBidirectional>
00441 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00442 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator ++ (int)
00443 {
00444 BidirectionalFilterIterator iterator(*this);
00445 this->operator ++ ();
00446 return iterator;
00447 }
00448
00449 template <class Predicate, class IteratorBidirectional>
00450 BidirectionalFilterIterator<Predicate, IteratorBidirectional>&
00451 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator -- ()
00452 {
00453 Base::operator -- ();
00454 return *this;
00455 }
00456
00457 template <class Predicate, class IteratorBidirectional>
00458 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00459 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::operator -- (int)
00460 {
00461 BidirectionalFilterIterator iterator(*this);
00462 this->operator -- ();
00463 return iterator;
00464 }
00465
00466 template <class Predicate, class IteratorBidirectional>
00467 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00468 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::begin(const Container& container)
00469 {
00470 BidirectionalFilterIterator iterator(container);
00471 iterator.toBegin();
00472 return iterator;
00473 }
00474
00475 template <class Predicate, class IteratorBidirectional>
00476 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00477 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::end(const Container& container)
00478 {
00479 BidirectionalFilterIterator iterator(container);
00480 iterator.toEnd();
00481 return iterator;
00482 }
00483
00484 template <class Predicate, class IteratorBidirectional>
00485 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00486 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::rbegin(const Container& container)
00487 {
00488 BidirectionalFilterIterator iterator(container);
00489 iterator.toRBegin();
00490 return iterator;
00491 }
00492
00493 template <class Predicate, class IteratorBidirectional>
00494 BidirectionalFilterIterator<Predicate, IteratorBidirectional>
00495 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::rend(const Container& container)
00496 {
00497 BidirectionalFilterIterator iterator(container);
00498 iterator.toREnd();
00499 return iterator;
00500 }
00501
00502 template <class Predicate, class IteratorBidirectional>
00503 BidirectionalFilterIterator<Predicate, IteratorBidirectional>::BidirectionalFilterIterator(const Container& container)
00504 : ConstBidirectionalFilterIterator<Predicate, IteratorBidirectional>(container)
00505 {
00506 }
00507
00508
00509 }
00510
00511 #endif // BALL_KERNEL_BIDIRECTIONALFILTERITERATOR_H