BALL  1.4.1
iterator.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines