00001 // -*- Mode: C++; tab-width: 2; -*- 00002 // vi: set ts=2: 00003 // 00004 // $Id: iterator.h,v 1.28 2005/10/23 12:02:19 oliver Exp $ 00005 // 00006 00007 #ifndef BALL_KERNEL_ITERATOR_H 00008 #define BALL_KERNEL_ITERATOR_H 00009 00010 #ifndef BALL_CONCEPT_BIDIRECTIONALITERATOR_H 00011 # include <BALL/CONCEPT/bidirectionalIterator.h> 00012 #endif 00013 00014 #ifndef BALL_CONCEPT_COMPOSITE_H 00015 # include <BALL/CONCEPT/composite.h> 00016 #endif 00017 00018 00027 #define BALL_KERNEL_DEFINE_ITERATOR_CREATORS(Type) \ 00028 Type##Iterator \ 00029 begin##Type () \ 00030 { \ 00031 return Type##Iterator::begin(*this); \ 00032 } \ 00033 \ 00034 Type##Iterator \ 00035 end##Type () \ 00036 { \ 00037 return Type##Iterator::end(*this); \ 00038 } \ 00039 \ 00040 Type##ReverseIterator \ 00041 rbegin##Type () \ 00042 { \ 00043 return Type##ReverseIterator(end##Type ()); \ 00044 } \ 00045 \ 00046 Type##ReverseIterator \ 00047 rend##Type () \ 00048 { \ 00049 return Type##ReverseIterator(begin##Type ()); \ 00050 } \ 00051 \ 00052 Type##ConstIterator \ 00053 begin##Type () const \ 00054 { \ 00055 return Type##ConstIterator::begin(*this); \ 00056 } \ 00057 \ 00058 Type##ConstIterator \ 00059 end##Type () const \ 00060 { \ 00061 return Type##ConstIterator::end(*this); \ 00062 } \ 00063 \ 00064 Type##ConstReverseIterator \ 00065 rbegin##Type () const \ 00066 { \ 00067 return Type##ConstReverseIterator(end##Type ()); \ 00068 } \ 00069 \ 00070 Type##ConstReverseIterator \ 00071 rend##Type () const \ 00072 { \ 00073 return Type##ConstReverseIterator(begin##Type ()); \ 00074 } 00075 00076 namespace BALL 00077 { 00085 class BALL_EXPORT CompositeIteratorTraits 00086 { 00087 public: 00088 00092 00094 inline CompositeIteratorTraits(); 00095 00097 inline CompositeIteratorTraits(const Composite& composite); 00098 00100 inline CompositeIteratorTraits(const CompositeIteratorTraits& traits); 00101 00103 inline ~CompositeIteratorTraits() {} 00104 00106 00109 00111 inline CompositeIteratorTraits& operator = (const CompositeIteratorTraits& traits); 00113 00117 00119 Composite* getContainer() { return bound_; } 00120 00122 inline const Composite* getContainer() const { return bound_; } 00124 00128 00130 inline bool operator == (const CompositeIteratorTraits& traits) const; 00131 00133 inline bool operator != (const CompositeIteratorTraits& traits) const; 00135 00143 inline bool isValid() const { return ((bound_ != 0) && composite_iterator_.isValid()); } 00144 00146 inline bool isSingular() const { return (bound_ == 0); } 00147 00151 inline bool isBegin() const; 00152 00157 inline bool isEnd() const 00158 { 00159 return composite_iterator_.isEnd(); 00160 } 00161 00166 inline bool isRBegin() const; 00167 00172 inline bool isREnd() const; 00174 00176 inline Composite::CompositeIterator& getPosition() { return composite_iterator_; } 00177 00179 inline const Composite::CompositeIterator& getPosition() const { return composite_iterator_; } 00180 00185 inline void invalidate(); 00186 00191 inline void toBegin() throw(Exception::Precondition); 00192 00197 inline void toEnd() throw(Exception::Precondition); 00198 00200 inline Composite& getData(); 00201 00203 inline const Composite& getData() const; 00204 00206 inline void forward(); 00207 00209 inline void backward(); 00210 00212 inline void toRBegin() throw(Exception::Precondition); 00213 00215 inline void toREnd() throw(Exception::Precondition); 00216 00218 inline void setPredicate(const UnaryPredicate<Composite>& predicate) { predicate_ = &predicate; } 00219 00221 inline const UnaryPredicate<Composite>* getPredicate() const { return predicate_; } 00222 00223 00224 protected: 00225 00227 Composite* bound_; 00228 00230 Composite::CompositeIterator composite_iterator_; 00231 00233 const UnaryPredicate<Composite>* predicate_; 00234 }; 00235 00236 inline CompositeIteratorTraits::CompositeIteratorTraits() 00237 : bound_(0), 00238 composite_iterator_(), 00239 predicate_(0) 00240 { 00241 } 00242 00243 inline CompositeIteratorTraits::CompositeIteratorTraits(const Composite& composite) 00244 : bound_(const_cast<Composite*>(&composite)), 00245 composite_iterator_(const_cast<Composite&>(composite).beginComposite()), 00246 predicate_(0) 00247 { 00248 } 00249 00250 inline CompositeIteratorTraits::CompositeIteratorTraits(const CompositeIteratorTraits& traits) 00251 : bound_(traits.bound_), 00252 composite_iterator_(traits.composite_iterator_), 00253 predicate_(traits.predicate_) 00254 { 00255 } 00256 00257 inline CompositeIteratorTraits& CompositeIteratorTraits::operator = (const CompositeIteratorTraits& traits) 00258 { 00259 bound_ = traits.bound_; 00260 composite_iterator_ = traits.composite_iterator_; 00261 predicate_ = traits.predicate_; 00262 return *this; 00263 } 00264 00265 inline bool CompositeIteratorTraits::operator == (const CompositeIteratorTraits& traits) const 00266 { 00267 return ((composite_iterator_ == traits.composite_iterator_) && (bound_ == traits.bound_)); 00268 } 00269 00270 inline bool CompositeIteratorTraits::operator != (const CompositeIteratorTraits& traits) const 00271 { 00272 return !this->operator == (traits); 00273 } 00274 00275 inline void CompositeIteratorTraits::invalidate() 00276 { 00277 bound_ = 0; 00278 composite_iterator_.invalidate(); 00279 } 00280 00281 inline void CompositeIteratorTraits::toBegin() throw(Exception::Precondition) 00282 { 00283 BALL_PRECONDITION_EXCEPTION((bound_ != 0), "cannot move unbound iterator to begin") 00284 composite_iterator_ = bound_->beginComposite(); 00285 while (+composite_iterator_ && (predicate_->operator () (*composite_iterator_) == false)) 00286 { 00287 ++composite_iterator_; 00288 } 00289 } 00290 00291 inline bool CompositeIteratorTraits::isBegin() const 00292 { 00293 if (isSingular()) 00294 { 00295 return false; 00296 } 00297 00298 try 00299 { 00300 Composite::CompositeIterator sub_iterator(bound_->beginComposite()); 00301 while (+sub_iterator && (predicate_->operator () (*sub_iterator) == false)) 00302 { 00303 ++sub_iterator; 00304 } 00305 return (composite_iterator_ == sub_iterator); 00306 } 00307 catch (Exception::Precondition&) 00308 { 00309 } 00310 00311 return false; 00312 } 00313 00314 inline void CompositeIteratorTraits::toEnd() throw(Exception::Precondition) 00315 { 00316 composite_iterator_.toEnd(); 00317 } 00318 00319 inline Composite& CompositeIteratorTraits::getData() 00320 { 00321 return const_cast<Composite&>(*composite_iterator_); 00322 } 00323 00324 inline const Composite& CompositeIteratorTraits::getData() const 00325 { 00326 return *composite_iterator_; 00327 } 00328 00329 inline void CompositeIteratorTraits::forward() 00330 { 00331 ++composite_iterator_; 00332 while (+composite_iterator_ && (predicate_->operator () (*composite_iterator_) == false)) 00333 { 00334 ++composite_iterator_; 00335 } 00336 } 00337 00338 inline void CompositeIteratorTraits::toRBegin() throw(Exception::Precondition) 00339 { 00340 BALL_PRECONDITION_EXCEPTION(!isSingular(), "cannot move singular iterator to reverse begin") 00341 composite_iterator_ = --bound_->endComposite(); 00342 while (+composite_iterator_ && (predicate_->operator () (*composite_iterator_) == false)) 00343 { 00344 --composite_iterator_; 00345 } 00346 } 00347 00348 inline bool CompositeIteratorTraits::isRBegin() const 00349 { 00350 if (isSingular()) 00351 { 00352 return false; 00353 } 00354 Composite::CompositeIterator sub_iterator = --bound_->endComposite(); 00355 00356 while (+sub_iterator && (predicate_->operator () (*sub_iterator) == false)) 00357 { 00358 --sub_iterator; 00359 } 00360 return (composite_iterator_ == sub_iterator); 00361 } 00362 00363 inline void CompositeIteratorTraits::toREnd() throw(Exception::Precondition) 00364 { 00365 composite_iterator_.toREnd(); 00366 } 00367 00368 inline bool CompositeIteratorTraits::isREnd() const 00369 { 00370 if (isSingular()) 00371 { 00372 return false; 00373 } 00374 return composite_iterator_.isREnd(); 00375 } 00376 00377 inline void CompositeIteratorTraits::backward() 00378 { 00379 --composite_iterator_; 00380 while (+composite_iterator_ && (predicate_->operator () (*composite_iterator_) == false)) 00381 { 00382 --composite_iterator_; 00383 } 00384 } 00385 } // namespace BALL 00386 00387 #endif // BALL_KERNEL_ITERATOR_H