00001 // -*- Mode: C++; tab-width: 2; -*- 00002 // vi: set ts=2: 00003 // 00004 00005 #ifndef BALL_KERNEL_ITERATOR_H 00006 #define BALL_KERNEL_ITERATOR_H 00007 00008 #ifndef BALL_CONCEPT_BIDIRECTIONALITERATOR_H 00009 # include <BALL/CONCEPT/bidirectionalIterator.h> 00010 #endif 00011 00012 #ifndef BALL_CONCEPT_COMPOSITE_H 00013 # include <BALL/CONCEPT/composite.h> 00014 #endif 00015 00016 00025 #define BALL_KERNEL_DEFINE_ITERATOR_CREATORS(Type) \ 00026 Type##Iterator \ 00027 begin##Type () \ 00028 { \ 00029 return Type##Iterator::begin(*this); \ 00030 } \ 00031 \ 00032 Type##Iterator \ 00033 end##Type () \ 00034 { \ 00035 return Type##Iterator::end(*this); \ 00036 } \ 00037 \ 00038 Type##ReverseIterator \ 00039 rbegin##Type () \ 00040 { \ 00041 return Type##ReverseIterator(end##Type ()); \ 00042 } \ 00043 \ 00044 Type##ReverseIterator \ 00045 rend##Type () \ 00046 { \ 00047 return Type##ReverseIterator(begin##Type ()); \ 00048 } \ 00049 \ 00050 Type##ConstIterator \ 00051 begin##Type () const \ 00052 { \ 00053 return Type##ConstIterator::begin(*this); \ 00054 } \ 00055 \ 00056 Type##ConstIterator \ 00057 end##Type () const \ 00058 { \ 00059 return Type##ConstIterator::end(*this); \ 00060 } \ 00061 \ 00062 Type##ConstReverseIterator \ 00063 rbegin##Type () const \ 00064 { \ 00065 return Type##ConstReverseIterator(end##Type ()); \ 00066 } \ 00067 \ 00068 Type##ConstReverseIterator \ 00069 rend##Type () const \ 00070 { \ 00071 return Type##ConstReverseIterator(begin##Type ()); \ 00072 } 00073 00074 namespace BALL 00075 { 00083 class BALL_EXPORT CompositeIteratorTraits 00084 { 00085 public: 00086 00090 00092 inline CompositeIteratorTraits(); 00093 00095 inline CompositeIteratorTraits(const Composite& composite); 00096 00098 inline CompositeIteratorTraits(const CompositeIteratorTraits& traits); 00099 00101 inline ~CompositeIteratorTraits() {} 00102 00104 00107 00109 inline CompositeIteratorTraits& operator = (const CompositeIteratorTraits& traits); 00111 00115 00117 Composite* getContainer() { return bound_; } 00118 00120 inline const Composite* getContainer() const { return bound_; } 00122 00126 00128 inline bool operator == (const CompositeIteratorTraits& traits) const; 00129 00131 inline bool operator != (const CompositeIteratorTraits& traits) const; 00133 00141 inline bool isValid() const { return ((bound_ != 0) && composite_iterator_.isValid()); } 00142 00144 inline bool isSingular() const { return (bound_ == 0); } 00145 00149 inline bool isBegin() const; 00150 00155 inline bool isEnd() const 00156 { 00157 return composite_iterator_.isEnd(); 00158 } 00159 00164 inline bool isRBegin() const; 00165 00170 inline bool isREnd() const; 00172 00174 inline Composite::CompositeIterator& getPosition() { return composite_iterator_; } 00175 00177 inline const Composite::CompositeIterator& getPosition() const { return composite_iterator_; } 00178 00183 inline void invalidate(); 00184 00189 inline void toBegin(); 00190 00195 inline void toEnd(); 00196 00198 inline Composite& getData(); 00199 00201 inline const Composite& getData() const; 00202 00204 inline void forward(); 00205 00207 inline void backward(); 00208 00212 inline void toRBegin(); 00213 00217 inline void toREnd(); 00218 00220 inline void setPredicate(const UnaryPredicate<Composite>& predicate) { predicate_ = &predicate; } 00221 00223 inline const UnaryPredicate<Composite>* getPredicate() const { return predicate_; } 00224 00225 00226 protected: 00227 00229 Composite* bound_; 00230 00232 Composite::CompositeIterator composite_iterator_; 00233 00235 const UnaryPredicate<Composite>* predicate_; 00236 }; 00237 00238 inline CompositeIteratorTraits::CompositeIteratorTraits() 00239 : bound_(0), 00240 composite_iterator_(), 00241 predicate_(0) 00242 { 00243 } 00244 00245 inline CompositeIteratorTraits::CompositeIteratorTraits(const Composite& composite) 00246 : bound_(const_cast<Composite*>(&composite)), 00247 composite_iterator_(const_cast<Composite&>(composite).beginComposite()), 00248 predicate_(0) 00249 { 00250 } 00251 00252 inline CompositeIteratorTraits::CompositeIteratorTraits(const CompositeIteratorTraits& traits) 00253 : bound_(traits.bound_), 00254 composite_iterator_(traits.composite_iterator_), 00255 predicate_(traits.predicate_) 00256 { 00257 } 00258 00259 inline CompositeIteratorTraits& CompositeIteratorTraits::operator = (const CompositeIteratorTraits& traits) 00260 { 00261 bound_ = traits.bound_; 00262 composite_iterator_ = traits.composite_iterator_; 00263 predicate_ = traits.predicate_; 00264 return *this; 00265 } 00266 00267 inline bool CompositeIteratorTraits::operator == (const CompositeIteratorTraits& traits) const 00268 { 00269 return ((composite_iterator_ == traits.composite_iterator_) && (bound_ == traits.bound_)); 00270 } 00271 00272 inline bool CompositeIteratorTraits::operator != (const CompositeIteratorTraits& traits) const 00273 { 00274 return !this->operator == (traits); 00275 } 00276 00277 inline void CompositeIteratorTraits::invalidate() 00278 { 00279 bound_ = 0; 00280 composite_iterator_.invalidate(); 00281 } 00282 00283 inline void CompositeIteratorTraits::toBegin() 00284 { 00285 BALL_PRECONDITION_EXCEPTION((bound_ != 0), "cannot move unbound iterator to begin") 00286 composite_iterator_ = bound_->beginComposite(); 00287 while (+composite_iterator_ && (predicate_->operator () (*composite_iterator_) == false)) 00288 { 00289 ++composite_iterator_; 00290 } 00291 } 00292 00293 inline bool CompositeIteratorTraits::isBegin() const 00294 { 00295 if (isSingular()) 00296 { 00297 return false; 00298 } 00299 00300 try 00301 { 00302 Composite::CompositeIterator sub_iterator(bound_->beginComposite()); 00303 while (+sub_iterator && (predicate_->operator () (*sub_iterator) == false)) 00304 { 00305 ++sub_iterator; 00306 } 00307 return (composite_iterator_ == sub_iterator); 00308 } 00309 catch (Exception::Precondition&) 00310 { 00311 } 00312 00313 return false; 00314 } 00315 00316 inline void CompositeIteratorTraits::toEnd() 00317 { 00318 composite_iterator_.toEnd(); 00319 } 00320 00321 inline Composite& CompositeIteratorTraits::getData() 00322 { 00323 return const_cast<Composite&>(*composite_iterator_); 00324 } 00325 00326 inline const Composite& CompositeIteratorTraits::getData() const 00327 { 00328 return *composite_iterator_; 00329 } 00330 00331 inline void CompositeIteratorTraits::forward() 00332 { 00333 ++composite_iterator_; 00334 while (+composite_iterator_ && (predicate_->operator () (*composite_iterator_) == false)) 00335 { 00336 ++composite_iterator_; 00337 } 00338 } 00339 00340 inline void CompositeIteratorTraits::toRBegin() 00341 { 00342 BALL_PRECONDITION_EXCEPTION(!isSingular(), "cannot move singular iterator to reverse begin") 00343 composite_iterator_ = --bound_->endComposite(); 00344 while (+composite_iterator_ && (predicate_->operator () (*composite_iterator_) == false)) 00345 { 00346 --composite_iterator_; 00347 } 00348 } 00349 00350 inline bool CompositeIteratorTraits::isRBegin() const 00351 { 00352 if (isSingular()) 00353 { 00354 return false; 00355 } 00356 Composite::CompositeIterator sub_iterator = --bound_->endComposite(); 00357 00358 while (+sub_iterator && (predicate_->operator () (*sub_iterator) == false)) 00359 { 00360 --sub_iterator; 00361 } 00362 return (composite_iterator_ == sub_iterator); 00363 } 00364 00365 inline void CompositeIteratorTraits::toREnd() 00366 { 00367 composite_iterator_.toREnd(); 00368 } 00369 00370 inline bool CompositeIteratorTraits::isREnd() const 00371 { 00372 if (isSingular()) 00373 { 00374 return false; 00375 } 00376 return composite_iterator_.isREnd(); 00377 } 00378 00379 inline void CompositeIteratorTraits::backward() 00380 { 00381 --composite_iterator_; 00382 while (+composite_iterator_ && (predicate_->operator () (*composite_iterator_) == false)) 00383 { 00384 --composite_iterator_; 00385 } 00386 } 00387 } // namespace BALL 00388 00389 #endif // BALL_KERNEL_ITERATOR_H