randomAccessIterator.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: randomAccessIterator.h,v 1.30 2004/02/23 15:19:57 anhi Exp $ 
00005 //
00006 
00007 #ifndef BALL_CONCEPT_RANDOMACCESSITERATOR_H
00008 #define BALL_CONCEPT_RANDOMACCESSITERATOR_H
00009 
00010 #ifndef BALL_COMMON_H
00011 # include <BALL/common.h>
00012 #endif
00013 
00014 #ifndef BALL_CONCEPT_BIDIRECTIONALITERATOR_H
00015 # include <BALL/CONCEPT/bidirectionalIterator.h>
00016 #endif
00017 
00018 namespace BALL 
00019 {
00020 
00025   template <typename Container, typename DataType, typename Position, typename Traits>
00026   class ConstRandomAccessIterator
00027     : public ConstBidirectionalIterator<Container, DataType, Position, Traits>
00028   {
00029     public:
00030 
00034 
00036     typedef std::random_access_iterator_tag iterator_category;
00037     // convenience typedef
00038     typedef ConstBidirectionalIterator<Container, DataType, Position, Traits> Base;
00040 
00044 
00046     BALL_INLINE ConstRandomAccessIterator()  {}
00047   
00049     BALL_INLINE ConstRandomAccessIterator(const ConstRandomAccessIterator& iterator) 
00050       : Base(iterator)
00051     {
00052     }
00053 
00055     BALL_INLINE ~ConstRandomAccessIterator()  {}
00057 
00058 
00059 
00063     
00066     ConstRandomAccessIterator& operator += (Distance distance)
00067       throw(Exception::InvalidIterator);
00068 
00071     ConstRandomAccessIterator& operator -= (Distance distance)
00072       throw(Exception::InvalidIterator);
00073 
00077     ConstRandomAccessIterator operator + (Distance distance) const
00078       throw(Exception::InvalidIterator);
00079 
00084     ConstRandomAccessIterator operator - (Distance distance) const
00085       throw(Exception::InvalidIterator);
00086 
00091     Distance operator - (const ConstRandomAccessIterator& iterator) const
00092       throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00093 
00097     static ConstRandomAccessIterator begin(const Container& container) 
00098       throw(Exception::InvalidIterator);
00099 
00103     static ConstRandomAccessIterator end(const Container& container)
00104       throw(Exception::InvalidIterator);
00105 
00109     static ConstRandomAccessIterator rbegin(const Container& container)
00110       throw(Exception::InvalidIterator);
00111 
00115     static ConstRandomAccessIterator rend(const Container& container) 
00116       throw(Exception::InvalidIterator);
00117 
00119 
00123 
00125     BALL_INLINE bool operator + () const  { return Base::getTraits().isValid(); }
00126 
00128     BALL_INLINE bool operator - () const  { return !Base::getTraits().isValid(); }
00129 
00136     bool operator < (const ConstRandomAccessIterator& iterator) const
00137       throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00138 
00146     bool operator <= (const ConstRandomAccessIterator& iterator) const
00147       throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00148 
00156     bool operator >= (const ConstRandomAccessIterator& iterator) const
00157       throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00158 
00165     bool operator > (const ConstRandomAccessIterator& iterator) const
00166       throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00167 
00169 
00170       
00171 
00177     const DataType& operator [] (Index index) const throw(Exception::InvalidIterator);
00179 
00180     protected:
00181 
00182     ConstRandomAccessIterator(const Container& container) 
00183       : Base(container)
00184     {
00185     }
00186   };
00188   
00193   template <typename Container, typename DataType, typename Position, typename Traits>
00194   ConstRandomAccessIterator<Container, DataType, Position, Traits> operator + 
00195     (Distance distance, const ConstRandomAccessIterator<Container, DataType, Position, Traits>& iterator) 
00196     throw(Exception::InvalidIterator)
00197   {
00198     ConstRandomAccessIterator<Container, DataType, Position, Traits> tmp_iterator(iterator);
00199     return (tmp_iterator += distance);
00200   }
00201 
00206   template <typename Container, typename DataType, typename Position, typename Traits>
00207   Distance ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator -
00208     (const ConstRandomAccessIterator<Container, DataType, Position, Traits>& b) const
00209     throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00210   {
00211     if (!Base::getTraits().isValid())
00212     {
00213       throw Exception::InvalidIterator(__FILE__, __LINE__);
00214     }
00215     if (!b.getTraits().isValid())
00216     {
00217       throw Exception::InvalidIterator(__FILE__, __LINE__);
00218     }
00219     if (Base::getTraits().getContainer() != b.getTraits().getContainer())
00220     {
00221       throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00222     }
00223     return Base::getTraits().getDistance(b.getTraits());
00224   }
00225 
00226   template <typename Container, typename DataType, typename Position, typename Traits>
00227   ConstRandomAccessIterator<Container, DataType, Position, Traits>&
00228     ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator += (Distance distance)
00229     throw(Exception::InvalidIterator)
00230   {
00231     if (!Base::getTraits().isValid())
00232     {
00233       throw Exception::InvalidIterator(__FILE__, __LINE__);
00234     }
00235     if (distance < (Distance)0)
00236     {
00237       return (*this -= -distance);
00238     }
00239     Base::getTraits().forward(distance);
00240     return *this;
00241   }
00242 
00243   template <typename Container, typename DataType, typename Position, typename Traits>
00244   ConstRandomAccessIterator<Container, DataType, Position, Traits>&
00245     ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator -= (Distance distance)
00246     throw(Exception::InvalidIterator)
00247   {
00248     if (Base::getTraits().isSingular())
00249     {
00250       throw Exception::InvalidIterator(__FILE__, __LINE__);
00251     }
00252     if (distance < (Distance)0)
00253     {
00254       return (*this += -distance);
00255     }
00256     if (Base::getTraits().isEnd() == true)
00257     {
00258       Base::getTraits().toRBegin();
00259       Base::getTraits().backward(distance - 1);
00260     }
00261     else 
00262     {
00263       Base::getTraits().backward(distance);
00264     }
00265     return *this;
00266   }
00267 
00268   template <typename Container, typename DataType, typename Position, typename Traits>
00269   ConstRandomAccessIterator<Container, DataType, Position, Traits>
00270     ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator + (Distance distance) const
00271     throw(Exception::InvalidIterator)
00272   {
00273     ConstRandomAccessIterator iterator(*this);
00274     return (iterator += distance);
00275   }
00276 
00277   template <typename Container, typename DataType, typename Position, typename Traits>
00278   ConstRandomAccessIterator<Container, DataType, Position, Traits> 
00279     ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator - (Distance distance) const
00280     throw(Exception::InvalidIterator)
00281   {
00282     ConstRandomAccessIterator iterator(*this);
00283     return (iterator -= distance);
00284   }
00285 
00286   template <typename Container, typename DataType, typename Position, typename Traits>
00287   bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator < 
00288     (const ConstRandomAccessIterator& iterator) const
00289     throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00290   {
00291     if (!Base::getTraits().isValid())
00292     {
00293       throw Exception::InvalidIterator(__FILE__, __LINE__);
00294     }
00295     if (!iterator.isValid())
00296     {
00297       throw Exception::InvalidIterator(__FILE__, __LINE__);       
00298     }
00299     if (Base::getTraits().getContainer() != iterator.getContainer())
00300     {
00301       throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00302     }
00303 
00304     return (Base::getTraits().operator < (iterator.getTraits()));
00305   }
00306 
00307   template <typename Container, typename DataType, typename Position, typename Traits>
00308   bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator <= 
00309     (const ConstRandomAccessIterator& iterator) const
00310     throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00311   {
00312     if (!Base::getTraits().isValid())
00313     {
00314       throw Exception::InvalidIterator(__FILE__, __LINE__);
00315     }
00316     if (!iterator.isValid())
00317     {
00318       throw Exception::InvalidIterator(__FILE__, __LINE__);
00319     }
00320     if (Base::getTraits().getContainer() != iterator.getContainer())
00321     {
00322       throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00323     }
00324     return !(Base::getTraits().operator > (iterator.getTraits()));
00325   }
00326 
00327   template <typename Container, typename DataType, typename Position, typename Traits>
00328   bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator >= 
00329     (const ConstRandomAccessIterator& iterator) const
00330     throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00331   {
00332     if (!Base::getTraits().isValid())
00333     {
00334       throw Exception::InvalidIterator(__FILE__, __LINE__);
00335     }
00336     if (!iterator.isValid())
00337     {
00338       throw Exception::InvalidIterator(__FILE__, __LINE__);
00339     }
00340     if (Base::getTraits().getContainer() != iterator.getContainer())
00341     {
00342       throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00343     }
00344 
00345     return !(Base::getTraits().operator < (iterator.getTraits()));
00346   }
00347 
00348   template <typename Container, typename DataType, typename Position, typename Traits>
00349   bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator > 
00350     (const ConstRandomAccessIterator& iterator) const
00351     throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00352   {
00353     if (!Base::getTraits().isValid())
00354     {
00355       throw Exception::InvalidIterator(__FILE__, __LINE__);
00356     }
00357     if (!iterator.isValid())
00358     {
00359       throw Exception::InvalidIterator(__FILE__, __LINE__);
00360     }
00361     if (Base::getTraits().getContainer() != iterator.getContainer())
00362     {
00363       throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00364     }
00365 
00366     return (Base::getTraits().operator > (iterator.getTraits()));
00367   }
00368 
00369   
00370   template <typename Container, typename DataType, typename Position, typename Traits>
00371   const DataType& ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator [] (Index index) const
00372     throw(Exception::InvalidIterator)
00373   {
00374     if (!Base::getTraits().isValid())
00375     {
00376       throw Exception::InvalidIterator(__FILE__, __LINE__);
00377     }
00378 
00379     return Base::getTraits().getData(index);
00380   }
00381 
00382   template <typename Container, typename DataType, typename Position, typename Traits>
00383   ConstRandomAccessIterator<Container, DataType, Position, Traits> 
00384     ConstRandomAccessIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00385     throw(Exception::InvalidIterator)
00386   {
00387     ConstRandomAccessIterator iterator(container);
00388     iterator.toBegin();
00389     return iterator;
00390   }
00391 
00392   template <typename Container, typename DataType, typename Position, typename Traits>
00393   ConstRandomAccessIterator<Container, DataType, Position, Traits> 
00394     ConstRandomAccessIterator<Container, DataType, Position, Traits>::end(const Container& container)
00395     throw(Exception::InvalidIterator)
00396   {
00397     ConstRandomAccessIterator iterator(container);
00398     iterator.toEnd();
00399     return iterator;
00400   }
00401 
00402   template <typename Container, typename DataType, typename Position, typename Traits>
00403   ConstRandomAccessIterator<Container, DataType, Position, Traits> 
00404     ConstRandomAccessIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00405     throw(Exception::InvalidIterator)
00406   {
00407     ConstRandomAccessIterator iterator(container);
00408     iterator.toRBegin();
00409     return iterator;
00410   }
00411 
00412   template <typename Container, typename DataType, typename Position, typename Traits>
00413   ConstRandomAccessIterator<Container, DataType, Position, Traits> 
00414     ConstRandomAccessIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00415     throw(Exception::InvalidIterator)
00416   {
00417     ConstRandomAccessIterator iterator(container);
00418     iterator.toREnd();
00419     return iterator;
00420   }
00421 
00426 
00429   template <typename Container, typename DataType, typename Position, typename Traits>
00430   class RandomAccessIterator
00431     : public ConstRandomAccessIterator<Container, DataType, Position, Traits>
00432   {
00433     public:
00434 
00438 
00439     typedef DataType& reference;
00441     typedef DataType* pointer;
00443     typedef ConstRandomAccessIterator<Container, DataType, Position, Traits> Base;
00445 
00449 
00451     BALL_INLINE RandomAccessIterator()  {}
00452   
00454     BALL_INLINE RandomAccessIterator(const RandomAccessIterator& iterator) 
00455       : Base(iterator)
00456     {
00457     }
00458 
00460     BALL_INLINE ~RandomAccessIterator()  {}
00462 
00466 
00467     BALL_INLINE reference operator [] (Index index) const throw(Exception::InvalidIterator) { return const_cast<reference>(Base::getTraits().getData(index)); }
00469     BALL_INLINE reference operator * () const  { return const_cast<reference>(Base::getTraits().getData()); }
00471     BALL_INLINE pointer operator -> () const  { return const_cast<pointer>(&Base::getTraits().getData()); }
00473 
00480     static RandomAccessIterator begin(const Container& container)
00481       throw(Exception::InvalidIterator);
00482 
00486     static RandomAccessIterator end(const Container& container)
00487       throw(Exception::InvalidIterator);
00488 
00492     static RandomAccessIterator rbegin(const Container& container)
00493       throw(Exception::InvalidIterator);
00494 
00498     static RandomAccessIterator rend(const Container& container)
00499       throw(Exception::InvalidIterator);
00501 
00502     protected:
00503 
00504     BALL_INLINE RandomAccessIterator(const Container& container) 
00505       : Base(container)
00506     {
00507     }
00508 
00509   };
00511   
00512   template <typename Container, typename DataType, typename Position, typename Traits>
00513   RandomAccessIterator<Container, DataType, Position, Traits> 
00514     RandomAccessIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00515     throw(Exception::InvalidIterator)
00516   {
00517     RandomAccessIterator iterator(container);
00518     iterator.toBegin();
00519     return iterator;
00520   }
00521 
00522   template <typename Container, typename DataType, typename Position, typename Traits>
00523   RandomAccessIterator<Container, DataType, Position, Traits> 
00524     RandomAccessIterator<Container, DataType, Position, Traits>::end(const Container& container)
00525     throw(Exception::InvalidIterator)
00526   {
00527     RandomAccessIterator iterator(container);
00528     iterator.toEnd();
00529     return iterator;
00530   }
00531 
00532   template <typename Container, typename DataType, typename Position, typename Traits>
00533   RandomAccessIterator<Container, DataType, Position, Traits> 
00534     RandomAccessIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00535     throw(Exception::InvalidIterator)
00536   {
00537     RandomAccessIterator iterator(container);
00538     iterator.toRBegin();
00539     return iterator;
00540   }
00541 
00542   template <typename Container, typename DataType, typename Position, typename Traits>
00543   RandomAccessIterator<Container, DataType, Position, Traits> 
00544     RandomAccessIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00545     throw(Exception::InvalidIterator)
00546   {
00547     RandomAccessIterator iterator(container);
00548     iterator.toREnd();
00549     return iterator;
00550   }
00551 
00552 } // namespace BALL 
00553 
00554 #endif // BALL_CONCEPT_RANDOMACCESSITERATOR_H