iterator.h

Go to the documentation of this file.
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